我有一个复杂的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,那么它可以工作。但似乎我应该能够做我在这里尝试的事情。是否有一些我缺少的基础?
答案 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
在上面的示例中,我还将虚假目标的名称更改为progs
和libs
,根据我的经验,这些名称更为常见。在这种情况下,libs
目标只是构建所有库的便利,而不是作为实际的依赖。