Makefile GNU make with VPATH:target,它看起来是圆形的,但实际上不应该';不可能
我的Makefile GNU make with VPATH:target,它看起来是圆形的,但实际上不应该';不可能,makefile,gnu-make,circular-dependency,Makefile,Gnu Make,Circular Dependency,我的Makefile中有一条规则,用于创建指向不同目录中文件的符号链接: VPATH = ../source foo: foo ln -s $< $@ VPATH=../source 福:福 ln-s$
Makefile
中有一条规则,用于创建指向不同目录中文件的符号链接:
VPATH = ../source
foo: foo
ln -s $< $@
VPATH=../source
福:福
ln-s$<$@
尽管我希望目标解析为
/foo
,依赖解析为。/source/foo
,但我理解为什么make
将其视为循环。是否有一种非循环的方式来表达此规则?请注意,链接不依赖于链接目标的更改;它只需要存在。因此,根本不需要普通的先决条件,要想做什么,最简单的片段就是
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
,否则该选项将不起作用 我认为你在这里尝试的属于“虚拟路径滥用”的范畴
我的经验不断地向我指出“显式优于隐式”这是其中一个原因。与GNU make手册中的断言相反,我的经验让我相信,在更大、更复杂的项目中,您需要更明确,而不是更少,因为文件的大小使得定位文件更加困难,除非它们的路径是明确的
我还认为,使用VPATH的许多需求源于使用递归make,在这里您没有构建完整的依赖树;正确地编写构建系统,您根本不需要VPATH
在一个相关主题上,我坚信只指定一个或两个-I
目录:您的顶级src/
和include/
目录,并使所有inclusion都与这些路径相关。同样,在更大、更复杂的项目中,seing#include“my/really/cool/thing.h”
比简单的#include“thing.h”
信息量大得多
也就是说,我愿意为库使用VPATH,特别是系统库,因为您可以使用
-lfoo
语法,但我不想将其作为一般规则使用,因为它可能威胁到构建的可复制性。为什么不将foo
作为依赖项删除并更改$将依赖项更改为。/source/foo
并删除VPATH
似乎可行,尽管这意味着我必须修改Makefile
中依赖于VPATH
的任何其他内容。我希望避免这样,但这不是太多的工作。