我有一个数据处理工作,我想用Make自动化。需要在几个步骤中处理数百个文件。 不幸的是,基本名称将至少在其中一个步骤中发生变化,但很容易将这些依赖项写入随后包含的单独文件中。
但是,我还想避免分别为所有这些文件编写构建指令(这些内容非常复杂)。
我设想了以下几点:
# automatically generated rules, included into make file
dir1/test.bb: dir2/test_other_name.aa
# (many more rules like the above, linking xxx.bb to yyy.aa)
# pattern rule
%.bb: %.aa
# build step using $@ $>
我想要的是提供规则的模式规则,以及定义依赖关系的显式规则。可以实现这样的事情吗?
答案 0 :(得分:0)
当制作时,点头的图案不会切掉芥末, 只是明确地写出规则。 (这具有不使用模式规则的快乐副作用。)
我们假设您有一个函数src-to-target
,它会生成目标文件名(即$(call src-to-target,dir2/test_other_name.aa)
扩展为dir1/test.bb
。
此外,您在${srcs}
中有一个来源列表,${recipe}
是使用$@
,$<
等的shell命令列表。
define src-to-target = ... # $1:source
define recipe =
echo Building $@ from $<
⋮
endef
define generate-rule = # $1:source
target := $(call src-to-taget,$1)
targets += $${target}
$${target}: $1 ; $${recipe}
endef
$(foreach _,${srcs},$(eval $(call generate-rule,$_)))
.PHONY: all
all: ${targets} ; : $@ Success
$(foreach ...)
完成所有工作。
所以,在痛苦的细节中看着它,
${srcs}
$_
设置为列表中的第一个(dir2/test_other_name.aa
说)展开$(call generate-rule,$_)
$(call generate-rule,dir2/test_other_name.aa)
$1
设置为dir2/test_other_name.aa
,随后展开$(generate-rule)
,导致此文本块
target := dir1/test.bb
targets += ${target}
${target}: dir2/test_other_name.aa ; ${recipe}
作为副作用,$(eval)
吞下上述文字。 $(eval)
的扩展虽然是空的。
$_
设置为下一个源文件。 $(foreach)
完成后,
${targets}
包含完整的目标列表。
平行安全。 什么不喜欢?