Makefile 将先决条件扩展推迟到(不同)目标创建之后
我希望能够在GNU make中的另一个规则的先决条件中使用在规则中创建的目标的结果。例如:Makefile 将先决条件扩展推迟到(不同)目标创建之后,makefile,gnu-make,gnu,Makefile,Gnu Make,Gnu,我希望能够在GNU make中的另一个规则的先决条件中使用在规则中创建的目标的结果。例如: PREREQ = $(shell echo "reading target1" >&2; cat target1) target1: echo "prereq" > $@ target2: target1 $(PREREQ) echo foo > $@ target2应取决于从target1文件中读取的prereq,但在执行target1配方
PREREQ = $(shell echo "reading target1" >&2; cat target1)
target1:
echo "prereq" > $@
target2: target1 $(PREREQ)
echo foo > $@
target2
应取决于从target1
文件中读取的prereq
,但在执行target1
配方之前,该文件不在文件中
假设这是一个非常做作的例子,我肯定有很多关于如何重构这个例子的建议,但我不打算重构这个例子。这只是我更复杂问题的一个简化示例,其中我需要从文件的内容中派生先决条件,该文件在执行Makefile
中的配方之前未创建
问题是,[如何]扩展$(PREREQ)
(因此,$(shell cat target1)
的执行推迟到实际执行target1
规则之后
更新:我尝试了。第二次扩展:
,但这似乎不起作用:
$ make -d target2
...
reading target1
cat: target1: No such file or directory
...
Updating goal targets....
Considering target file 'target2'.
File 'target2' does not exist.
Considering target file 'target1'.
File 'target1' does not exist.
Finished prerequisites of target file 'target1'.
Must remake target 'target1'.
echo "prereq" > target1
[ child management ]
Successfully remade target file 'target1'.
Finished prerequisites of target file 'target2'.
Must remake target 'target2'.
echo foo > target2
[ child management ]
Successfully remade target file 'target2'.
如你所见,“阅读目标”仅在一开始打印了一次,表明由于
的原因,PREREQ
没有再次展开。第二次展开:
,并且为target2
考虑的目标列表不包括PREREQ,您可以将target2
的完整规则写入单独的文件并-include>代码>it:
确切的机制将取决于您的特定用例,使用这种方法很可能无法实现我们所需的功能,但它支持自动生成依赖项的各种样式。推迟先决条件$(PREREQ)的扩展
可以通过有条件地创建target2
并依赖递归来实现:
ifndef expand-prereq
target2: target1
$(MAKE) --no-print-directory -f $(lastword $(MAKEFILE_LIST)) $@ expand-prereq=y
else
target2: target1 $(PREREQ)
echo foo > $@
endif
第一次为此makefile运行make
时,变量expand prereq
未定义,因此,第一个target2
规则作为条件的结果生成。这种伪规则使更新target1
成为可能,而无需扩展$(prereq)
。
匹配此规则将导致更新target1
(因为target1
是此规则的先决条件),并针对同一makefile递归调用make
,并将target2
作为目标
第二次make
是(递归)调用时,变量expand-prereq
是通过命令行参数expand-prereq=y
定义的,因此第二个target2
规则是这次else
分支的结果。此规则是实际生成targettarget2
的规则。请注意,在此之前可以执行此规则匹配后,target1
已经作为第一个虚拟规则的副作用创建,因此$(PREREQ)
的扩展发生在创建了target1
之后(您正在寻找的内容)。抱歉,我现在意识到它没有按预期工作。但需要明确的是:“二次扩展”并不意味着扩展两次,而是在匹配规则时进行扩展(即:仍然只有一次)。问题似乎是在创建target1
之前仍然碰巧执行了二次扩展。我删除了以前的答案,并添加了一个新的潜在解决方案。我希望这会有所帮助。