我有一个可以创建多个目标的顶级Makefile,我有一个for循环 . 在这个文件中,我试图读取一个文本文件,其版本号仅在子makefile运行时创建 . 我有它工作,但它看起来很丑,所以我认为可能有更好的方法来做到这一点 . 这是顶级Makefile:
T1=_release
T2=_debug
T3=_test
all: bin/mybin_release.bin
debug: bin/mybin_debug.bin
debug: export DBG:=1
test: bin/mybin_test.bin
test: export TST:=1
define build_foo
bin/mybin$$($(1)).bin: bin/abc$$($(1)).bin bin/xyz$$($(1)).bin
cat $$^ > $$@
VER=$$$$(cat bin/rev.txt) && mv bin/mybin$$($(1)).bin bin/mybin$$($(1))_$$$${VER}.bin
bin/abc$$($(1)).bin:
$(MAKE) -C mod1 # <--- rev.txt is produced here
bin/xyz$$($(1)).bin:
$(MAKE) -C mod2
endef
$(foreach suffix, T1 T2 T3, $(eval $(call build_foo,$(suffix))))
clean:
rm bin/*.bin bin/*.txt
请注意尝试在 VER
中获取文件内容 . 有没有更好/正确的方法来做到这一点?我不能使用 eval
因为它在开始时运行而 rev.txt
仅在子make运行时才会被创建 . 另外,这是构建多个目标(使用foreach)的一种不错的方法吗?我使用导出的变量来修改子makefile构建的目标 .
1 回答
据我所知,这个
bin/rev.txt
文件和bin/abcXXX.bin
都是在运行$(MAKE) -C mod1
时生成的 . 所以,对所有人来说都是一样的 . 关于什么:演示:
说明:
version.mk
是make将要查找的第二个makefile . 根据GNU make documentation, section 3.5:注意:在编写makefile时,
$(MAKE) -C mod1
将运行几次,这是一种浪费 . 您可以使用GNU make pattern规则的特异性:当它们有多个目标时,make会认为所有目标都是通过一次调用配方生成的 . 例:看到?配方仅执行一次以构建3个目标 . 唯一的问题是
%
通配符必须至少匹配一个字符 . 所以,在你的情况下,你可以做类似的事情(%
匹配的字符是b
的bin/
):这将告诉make
$(MAKE) -C mod1
一次构建所有bin/abcXXX.bin
和bin/rev.txt
. 与$(MAKE) -C mod2
相同 .总而言之,通过将所有这些功能粘合在一起,您可能完全摆脱了
build_foo
通用规则 . 就像是: