我的Makefile
中有一条规则用于创建不同目录中文件的符号链接:
VPATH = ../source
foo: foo
ln -s $< $@
即使我打算让目标解析为./foo
并依赖解析为../source/foo
,我理解为什么make
将其视为循环。有没有办法以非循环的方式表达这条规则?
答案 0 :(得分:0)
请注意,链接不依赖于链接目标的更改;它只需要存在。因此,根本不需要普通的先决条件,并且最简单的片段可以做你想做的事情
foo:
ln -sf ../source/$@
但是,如果您仍需要VPATH
用于其他目的,这将无法正常工作。如果是这样,那么在我看来最简单的方法是使用绝对路径忽略VPATH
这个规则:
VPATH := ../source
$(CURDIR)/foo:
ln -sf ../source/$(@F)
最后,如果文件../source/foo
也是由Make生成的目标,那么最好的方法可能是:
VPATH := ../source
.SECONDEXPANSION:
$(CURDIR)/foo: | ../source/$$(@F)
ln -sf $|
请注意,我们不依赖于此处先决条件的更改,仅取决于它是否存在。
顺便说一下,我使用-f
选项的原因是,Make应支持-B
选项。除非您在此处使用-f
,否则该选项无效。
答案 1 :(得分:0)
我认为您在此尝试的内容属于“VPATH滥用”类别。
我的经历一再指向我的口头禅“明确胜于隐性”,这也是其中一个原因。与GNU make Manual中的断言相反,我的经验让我相信,在更大,更复杂的项目中,你需要更多明确而不是更少,因为它的大小使得它更难以找到文件,除非它们的路径是明确的。
我也相信很多使用VPATH的需要源于使用递归make,你没有构建完整的依赖树;正确编写您的构建系统,您根本不需要VPATH。
在相关主题上,我坚信只指定一个或两个-I
目录:您的顶级src/
和include/
目录并使全部< / em>相对于这些路径的包含。同样,在更大,更复杂的项目中,seing #include "my/really/cool/thing.h"
比仅仅#include "thing.h"
提供更多信息。
那就是说,我愿意将VPATH用于库,尤其是系统库,因为你可以使用-lfoo
语法,但我不想将它作为一般规则使用,因为它可能会威胁到构建的可重复性。