Use of 'Empty Target' in makefile

Lately I've been trying to get into the concepts of GNU Make. While reading, I came accross a topic called Empty Target . From GNU Make manual what I got to know is

The empty target is a variant of the phony target; it is used to hold recipes for an action that you request explicitly from time to time. Unlike a phony target, this target file can really exist; but the file's contents do not matter, and usually are empty.

The purpose of the empty target file is to record, with its last-modification time, when the rule's recipe was last executed. It does so because one of the commands in the recipe is a touch command to update the target file.

From another source, I read something like this

Empty targets are similar to phony targets in that the target itself is used as a device to leverage the capabilities of make. Phony targets are always out of date, so they always execute and they always cause their dependent (the target associated with the prerequisite) to be remade. But suppose we have some command, with no output file, that needs to be performed only occasionally and we don't want our dependents updated? For this, we can make a rule whose target is an empty file (sometimes referred to as a cookie):

prog: size prog.o
$(CC) $(LDFLAGS) -o $@ $^

size: prog.o
size $^
touch size

Notice that the size rule uses touch to create an empty file named size after it completes. This empty file is used for its timestamp so that make will execute the size rule only when prog.o has been updated. Furthermore, the size prerequisite to prog will not force an update of prog unless its object file is also newer.

From reading them what I understood is

  • Empty target is used to maintain the timestamp
  • The content of empty target is of no interest, only the update time is.
  • For doing some hands-on, I have written two sample makefiles

    makefile 1

    with empty target use

    prog: size prog.o
        gcc -o $@ prog.o
    
    size: prog.o
        size $<
        touch size
    
    prog.o: prog.c
        gcc -c $<
    

    output

    [sourav@localhost Practice]# make
    gcc -c prog.c
    size prog.o
       text    data     bss     dec     hex filename
         58       0       0      58      3a prog.o
    touch size
    gcc -o prog prog.o
    [sourav@localhost Practice]# make
    make: `prog' is up to date.
    [sourav@localhost Practice]# touch prog.c //suppose some real change in the file
    [sourav@localhost Practice]# make
    gcc -c prog.c
    size prog.o
       text    data     bss     dec     hex filename
         58       0       0      58      3a prog.o
    touch size
    gcc -o prog prog.o
    [sourav@localhost Practice]#
    

    makefile 2

    without empty target use

    prog: prog.o
        size $^
        gcc -o $@ prog.o
    
    prog.o: prog.c
        gcc -c $<
    

    output

    [sourav@localhost Practice]# make
    gcc -c prog.c
    size prog.o
       text    data     bss     dec     hex filename
         58       0       0      58      3a prog.o
    gcc -o prog prog.o
    [sourav@localhost Practice]# make
    make: `prog' is up to date.
    [sourav@localhost Practice]# touch prog.c 
    [sourav@localhost Practice]# make
    gcc -c prog.c
    size prog.o
       text    data     bss     dec     hex filename
         58       0       0      58      3a prog.o
    gcc -o prog prog.o
    [sourav@localhost Practice]#
    

    In above two different makefiles , the output for the similar condition is same. So, I'm not clear with the particular scope of use for empty targets. If they are used only to hold the timestamp, then we can achieve the same without using them . [Or is related with automatic variable $? about which I'm yet to read in detail]. Can anyone resolve this confusion in some other wordings, possibly with some example (if I'm not asking too much)?

    Thanks and Cheers!!


    In your case you already have a target (size), which changes when one of your source file does. So in your example, gcc acts like touch. However, in your first link, if you take a look at the example:

     print: foo.c bar.c
             lpr -p $?
             touch print
    

    Here without touch print , make print will always execute lpr -p as the print rule does not refer to a file that changes. Example with ls:

    Makefile:

    print: foo.c bar.c
           ls $?
    

    make print (1):

    ls foo.c bar.c
    bar.c foo.c
    

    make print (2):

    ls foo.c bar.c
    bar.c foo.c
    

    However, now if make print changes the timestamp of a file renamed "print", now the rule refers to an existing file:

    Makefile:

    print: foo.c bar.c
           ls $?
           touch print
    

    make print (1):

    ls foo.c bar.c
    bar.c foo.c
    

    make print (2):

    make: `print' is up to date.
    

    because file print is more recent than foo.c and bar.c.

    链接地址: http://www.djcxy.com/p/64118.html

    上一篇: Makefile:获取目标先决条件的先决条件

    下一篇: 在makefile中使用'空目标'