为什么.PHONY不能在这种情况下工作?

时间:2011-01-24 21:58:59

标签: makefile

我有一个复杂的makefile,每次调用它时似乎都会重新链接我的库和可执行文件。我能够将问题缩小到一个简单的makefile:

 1: all: prog
 2:
 3: .PHONY: prog
 4: prog: prog.exe
 5:
 6: prog.exe: lib prog.o
 7:         touch prog.exe
 8:
 9: prog.o: prog.c
10:         touch prog.o
11:
12: .PHONY: lib
13: lib: lib.so
14:
15: lib.so: lib.o
16:         touch lib.so
17:
18: lib.o: lib.c
19:         touch lib.o
20:
21: .PHONY: clean
22: clean:
23:         rm *.so *.o *.exe

出于某种原因,这个例子,每次都会创建prog.exe。如果我用lib.so替换第6行的lib,那么它可以工作。但似乎我应该能够做我在这里尝试的事情。是否有一些我缺少的基础?

1 个答案:

答案 0 :(得分:5)

从在线GNU制作手册:

  

虚假的目标不应该是   真实目标文件的先决条件;如果   它是,它的配方将每运行一次   时间make去更新该文件。如   只要虚假的目标永远不是一个   真正目标的先决条件,   将执行假目标食谱   只有当虚假的目标是一个   指定目标(参见参数   指定目标。

这至少解释了你所看到的。由于prog.exe取决于lib,您收集库的虚假目标,lib规则被触发,因此prog.exe已“过时”,并重新链接。< / p>

看起来你必须更明确地了解你的依赖关系。也许你会有兴趣将它们放在一个变量中,以便更轻松地管理多个库?例如:

LIBS = lib.so

all: libs progs

.PHONY: progs libs clean

progs: prog.exe

prog.exe: $(LIBS) prog.o
    touch prog.exe

# etc.
libs: $(LIBS)

lib.so: lib.o
    touch lib.so

# and so on

在上面的示例中,我还将虚假目标的名称更改为progslibs,根据我的经验,这些名称更为常见。在这种情况下,libs目标只是构建所有库的便利,而不是作为实际的依赖。