【发布时间】:2016-08-28 05:36:26
【问题描述】:
我有一个设置,我想用 make 处理的文件依赖于另一个程序的输出。构建程序及其所有先决条件 也是一项复杂的任务,所以我也想为此使用 make 。现在我的问题是,似乎无法在 Makefile 配方中生成规则和先决条件。考虑以下代码:
bar:
echo target1 target2 target3 > bar
foo: bar
$(eval BAR := $(shell cat bar))
define FUN
$(1):
touch a$(1)
endef
ifdef BAR
$(foreach i,$BAR,$(eval $(call FUN,$(i))))
endif
blub: foo $(BAR)
我用bar 配方替换了一大组复杂的配方,这些配方最终导致生成我想要拥有的文件列表。实际上,生成bar 的内容非常复杂,应该通过一组 Makefile 配方来完成,而不能仅仅通过(如上所示)来完成:
BAR:=$(shell echo target1 target2 target3)
我想将foreach 循环放入foo 的配方中,但prerequisites cannot be defined in recipes 失败,这是有道理的,在function define in makefile 中也有解释
但似乎当我做make blub 时,当foo eval 的BAR 为不同的值时,blub 的先决条件不会重新评估。
所以我认为最终我正在寻找两件事:
如何在运行时根据(并依赖于)另一个配方(在本例中为
bar)输出的内容动态生成配方?如何在运行时动态更新目标的先决条件(在这种情况下为
blub),基于(并依赖于)另一个配方(在这种情况下为bar)的输出?
谢谢!
编辑:解决方案
在@user657267 的帮助下,以下似乎解决了我的问题:
.PHONY: all
all: blub
-include bar.make
.PHONY: blub
blub: $(BAR)
echo $^
bar.make: Makefile
printf 'BAR=target1 target2 target3\n' > $@
printf 'target1 target2 target3:\n' >>$@
printf '\ttouch $$@' >> $@
.PHONY: clean
clean:
rm -f target1 target2 target3 bar.make
【问题讨论】:
-
FWIW,echo 的这种使用非常不便携。您应该使用 printf (程序)打印除简单文本后跟换行符之外的任何内容。另外仅供参考,您可以使用 eval 从配方中设置变量,但不能使用它来创建新规则。这是因为在 make 读取所有 makefile 之后,在它开始运行配方之前,它会执行一个过程,将所有 makefile 数据对齐到它的内部图表中。一旦发生这种情况,您将无法通过添加新规则来更改图表。
-
@MadScientist 啊,谢谢,我认为你的评论
eval()回答了我在回答这个问题时问你的另一个问题,即确实需要使用include才能工作并且不存在仅eval的解决方案。我在这里使用echo的哪一部分是不可移植的? -
并非所有回显命令都会将
\t字符序列转换为TAB 字符。 -
@MadScientist 确实根据in-ulm.de/~mascheck/various/echo+printf 我不会支持 BSD。我相应地修改了我的答案。谢谢!