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

use*_*226 2 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
Run Code Online (Sandbox Code Playgroud)

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

Gle*_*ter 5

从在线GNU制作手册:

伪目标不应该是真实目标文件的先决条件; 如果是,每次make更新该文件时都会运行其配方.只要虚假目标永远不是真实目标的先决条件,只有当虚假目标是指定目标时才会执行虚假目标配方(请参阅指定目标的参数).

这至少解释了你所看到的.由于prog.exe依赖于lib,你收集图书馆的虚假目标,lib规则被解雇,因此prog.exe"过时",并重新链接.

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

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
Run Code Online (Sandbox Code Playgroud)

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