在makefile中使用'Empty Target'

最后发布: 2013-12-13 09:25:58


问题

最近我一直试图深入了解GNU Make的概念。 在阅读时,我遇到了一个名为Empty Target的话题。 GNU Make手册我所知道的是

空目标是虚假目标的变体; 它用于保存您不时明确请求的操作的配方。 与虚假目标不同,此目标文件确实存在; 但文件的内容无关紧要,通常都是空的。

空目标文件的目的是记录上次修改时间,上次执行规则的配方时。 这样做是因为配方中的一个命令是用于更新目标文件的触摸命令。

另一个来源 ,我读到这样的东西

空目标与虚假目标类似,因为目标本身被用作利用make功能的设备。 伪目标总是过时的,所以它们总是执行,并且它们总是导致它们的依赖(与先决条件相关联的目标)被重建。 但是假设我们有一些命令,没有输出文件,只需要偶尔执行,我们不希望我们的家属更新? 为此,我们可以制定一个规则,其目标是一个空文件(有时称为cookie):

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

请注意,大小规则使用touch在完成后创建名为size的空文件。 此空文件用于其时间戳,以便make仅在prog.o更新时才执行大小规则。 此外,prog的大小先决条件不会强制更新prog,除非它的目标文件也更新。

从阅读它们我所理解的是

  • 空目标用于维护时间戳
  • 空目标的内容没有意义,只有更新时间。

为了做一些动手,我写了两个样本makefile

makefile 1

空目标使用

prog: size prog.o
    gcc -o $@ prog.o

size: prog.o
    size $<
    touch size

prog.o: prog.c
    gcc -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
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

没有空目标使用

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

prog.o: prog.c
    gcc -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]# 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]#

在上述两个不同的makefile中,类似条件的输出是相同的。 所以,我不清楚空目标的特定使用范围 如果它们仅用于保存时间戳,那么我们可以在不使用它们的情况下实现相同的目的。 [或与自动变量$? 关于我还没有详细阅读的内容]。 任何人都可以用其他一些措辞解决这种混乱,可能还有一些例子(如果我不是要求太多)?

谢谢,干杯!

c makefile gnu-make
回答

在您的情况下,您已经有一个目标(大小),当您的一个源文件执行时,它会更改。 所以在你的例子中,gcc就像触摸一样。 但是,在您的第一个链接中,如果您查看示例:

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

这里没有touch printmake print将始终执行lpr -p因为打印规则不引用更改的文件。 ls示例:

Makefile文件:

print: foo.c bar.c
       ls $?

制作印刷品(1):

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

制作印刷品(2):

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

但是,现在如果make print更改了重命名为“print”的文件的时间戳,那么现在规则引用现有文件:

Makefile文件:

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

制作印刷品(1):

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

制作印刷品(2):

make: `print' is up to date.

因为文件打印比foo.c和bar.c更新。