GNU制作具有不同文件基名的模式规则

时间:2017-02-18 09:13:24

标签: gnu-make rules

我有一个数据处理工作,我想用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 $@ $> 

我想要的是提供规则的模式规则,以及定义依赖关系的显式规则。可以实现这样的事情吗?

1 个答案:

答案 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}包含完整的目标列表。

平行安全。 什么不喜欢?