2011-01-24 62 views
2

我有一个复杂的makefile,似乎每次调用它时都会重新链接我的库和可执行文件。我能够缩小问题变成一个简单的makefile:为什么.PHONY在这种情况下不起作用?

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,那么它就可以工作。但似乎我应该能够做到我在这里尝试的。有什么基本的我失踪了?

回答

5

从网上GNU使手动:

假目标不应该是一个真正的目标文件的 前提;如果是 那么它的配方会每 运行一次来​​更新该文件。作为 只要假目标从来都不是一个真正的目标的前提 ,只有当假目标是 指定目标(见参数来 指定的目标)的 假目标配方将被执行 。

这至少可以解释你所看到的。由于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 

在上面的例子中,我也改变了假目标的名称progslibs,这在我的经验是比较常见的。在这种情况下,libs目标仅仅是构建所有库的便利,而不是充当实际的依赖关系。

+0

我希望他们让你这样做。我的makefiles允许我的“客户”在没有lib * .so的情况下指定其他库的依赖关系。因此,如果他们有一个名为MYPROG一个exe取决于MyLib1和MyLib2,然后他们只会说: “LIB_FILES:= MyLib1 MyLib2”,而不是 “LIB_FILES:= /libMyLib1.so /libMyLib2.so”。我想我需要存储库的实际名称和位置,这样才能工作。感谢您的回应! – user545226

+0

如何“接受答案”?此外,我试图点击向上箭头,但它说我需要15点声望。我是新来的,所以我想我是一个在这个网站上声名狼借的人。 :( – user545226

+0

至于给予好评的事情会发生,因为你得到更多的声望值,你就可以做更多的事情,比如upvoting的问题。我建议你阅读FAQ(有在每个页面顶部的链接)以更好地了解SO如何运行 –

相关问题