为什么GNU make的vpath命令如此弱?

时间:2012-04-27 16:20:55

标签: makefile gnu

我正在优化一个非常大的项目的一些makefile,我发现GNU make的vpath命令只能完成非常有限的工作。例如:

vpath %.o $(OBJPATH)

表示通过OBJPATH搜索路径值中的所有目标文件。这意味着/dir1/../dir2/obj1.o/dir3/../dir2/obj1.o是同一个文件,但是,如果我已经创建了/dir1/../dir2/obj1.o,当工具在考虑/dir3/../dir2/obj1.o的规则时,它仍然无法找到它,并且必须重新制作/dir3/../dir2/obj1.o,即使它代表与/dir1/../dir2/obj1.o相同的文件。

我检查了GNU make源代码;它使用哈希表来比较文件路径字符串,因此如果字符串不同,虽然它们代表相同的文件,但仍然无法使用vpath进行匹配。

为什么不通过更强大的功能来实现vpath

1 个答案:

答案 0 :(得分:6)

回复:

[GNU Make]使用哈希表来比较文件路径字符串,因此如果字符串不同,虽然它们代表相同的文件,但仍然无法使用vpath进行匹配。

Make正在做大致正确的事情。检测两个对象是否相同需要依赖文件系统中的唯一ID(例如inode编号),这些ID是OS和特定于文件系统的。

为什么使用两个不同的路径来引用相同的目标或先决条件?可以说,你在Makefile中所做的事情比依靠字符串相等进行路径比较更糟糕。

另外,你可能会误解某些东西。 vpath指令和VPATH变量与搜索先决条件文件有关。

您很少(如果有的话)希望将对象文件作为先决条件进行搜索(即使它们是构建可执行文件或库的先决条件)。

这是因为不能假定目标文件存在,并且您不搜索可能不存在的内容。执行干净构建时,目标文件不存在。您的Makefile 必须知道它们的确切名称。这是可以变化的先决条件。例如,您知道要构建foo.o(可能已经存在于以前的构建中,或者可能不存在)。您不一定知道的是构建foo.o的源文件。是libfoo/foo.c还是utils/foo.c?这是vpath解决的问题:它将搜索这些地点并找到foo.c,类似于PATH帮助您的shell在foo中查找程序/bin的方式}或/usr/bin等。

VPATH/vpath对于为小型项目编写快速和脏的makefile而言有点骇人听闻,它们无法扩展到大型配置。尝试改进它们毫无意义。