我想在一个顶级Makefile
可以包含的文件中描述每个submake的依赖关系。这是为了允许递归的make设置(具有实例化变量和相对路径的所有功能),但具有顶层make中描述的所有依赖关系,以提高编译速度和并行性。
例如,假设我们有一个如下所示的目录树:
project/
|-- lib1
| |-- Makefile
| `-- Makefile.reg
|-- lib2
| |-- Makefile
| `-- Makefile.reg
|-- Makefile
`-- Makefile.reg
project/lib1/Makefile.reg
文件的文件可能看起来像这样:
REG := lib1
include ../Makefile.reg
project/lib2/Makefile.reg
文件的文件可能看起来像这样:
REG := lib2
DEP := lib1
include ../Makefile.reg
文件project/Makefile.reg
看起来像这样:
$(REG)_DIR = ????
$(REG): $(DEP)
$(MAKE) -C $($@_DIR)
最后,顶级project/Makefile
看起来像这样:
include $(shell find . -name "Makefile.reg")
现在,顶级Makefile
拥有每个目标的所有依赖信息,并且可以智能地调用递归make和利用完全并行性,同时保持依赖树的完整性。
问题是,我不确定如何让project/Makefile.reg
知道当前submake的Makefile.reg
的路径是什么。make
将始终从顶级目录调用,因此$(shell pwd)
将始终报告project/
。一种解决方案是包含来自这个SO答案的行,但是我希望每个Makefile.reg
只指定一个目标和一个可选的依赖项列表。
是否有一种方法,包括目录路径发现在共同的project/Makefile.reg
,而不是把一个新的行在每一个子Makefile.reg
?换句话说,包含的makefile可以推断父makefile的目录吗?我看到了MAKEFILE_LIST
变量的一些不同解析的潜力。
正如链接票证上的答案中包含的文档片段所示。MAKEFILE_LIST
的值会随着make的进行而更新。列表中最新的条目是当前的makefile,这使得列表中的倒数第二个条目成为之前最近包含的makefile。如果您愿意断言主project/Makefile.reg
只会从子目录makefile中包含,那么它可以简单地检查MAKEFILE_LIST
中的条目。
或者您可以简单地在主Makefile
中定义一个罐装配方,并在每个项目makefile中调用它来定义适当的目标。
不幸的是,make确实使获取倒数第二个条目变得有点困难,而不是令人愉快。但是下面的代码应该可以工作:
FOO=a b c d e f g
BAR=h i j k l m n
BAZ=o p q r s t u
QUX=v w x y z 1 2
penultimateword = $(wordlist $(words $1),$(words $1), x $1)
REG=FOO
$(REG)_DIR= $(call penultimateword,$($(REG)))
$(info REG_DIR=$($(REG)_DIR))
REG=BAR
$(REG)_DIR= $(call penultimateword,$($(REG)))
$(info REG_DIR=$($(REG)_DIR))
REG=BAZ
$(REG)_DIR= $(call penultimateword,$($(REG)))
$(info REG_DIR=$($(REG)_DIR))
REG=QUX
$(REG)_DIR= $(call penultimateword,$($(REG)))
$(info REG_DIR=$($(REG)_DIR))
all: ;
上面的灵感来自于神奇的GMSL的chop
函数