多个目录上的 Makefile 模式匹配

Makefile pattern match on multiple directories

我有一个 *.abc 文件的制作目标,然后需要触发 DIR/%.xyz。问题是 DIR 作为目录列表传入。 %.xyz 是唯一的,只存在于一个地方。我试过使用 foreach 没有任何运气。任何帮助将不胜感激。

OtherDir:=dir1 dir2 dir3
${SOURCE_DIR}/%.abc: $(foreach dir, OtherDir, $(if ${dir}/%.xyz,,$(info Match found in ${dir}))

编辑 - 找到了一种可能的解决方案。它不是将路径存储到 ${dir}/$*.xyz,而是直接传递到编译步骤。 其他目录:=dir1 dir2 dir3

${SOURCE_DIR}/%.abc:
    $(call status, Do the stuff)
    3rd_party_compile_tool $(foreach dir, ${OtherDir}, $(wildcard ${dir}/$*.xyz))

因此,对于初学者来说,您尝试做事的方式听起来像是您的整体制作设计存在缺陷(具体来说,如果您在多个目录中有两个同名的 %.xyz,这会给你带来问题——虽然你现在可能没有,但这是一根锋利的棍子)。

如果您确实想这样做,可以使用 template/eval 为每个目录生成单独的模式规则。 Make 将在尝试构建 %.abc.

时选择第一个匹配的模式
OtherDir:=dir1 dir2 dir3

define abc_rule
${SOURCE_DIR}/%.abc: $(1)/%.xyz
    @3rd_party_compile_tool $^
endef

$(foreach dir,${OtherDir},$(eval $(call abc_rule,${dir})))

(请注意,您更新后的解决方案将因依赖关系而出现问题)。

您想要执行的 foreach 需要 secondary expansion,以便在设置主干(% 部分)时对其进行评估。考虑以下 Makefile

SOURCE_DIR := src
OtherDir := dir1 dir2 dir3

.SECONDEXPANSION:

$(SOURCE_DIR)/%.abc: $$(foreach dir,$(OtherDir),$$(wildcard $$(dir)/$$*.xyz))
        echo Making $@ from $^

具有给定的文件结构:

.
./dir1
./dir2
./dir2/foo.xyz
./dir3
./dir3/bar.xyz
./Makefile

它将根据词干匹配适当的先决条件:

$ make -s src/foo.abc src/bar.abc
Making src/foo.abc from dir2/foo.xyz
Making src/bar.abc from dir3/bar.xyz