Makefile:修改模式规则中的词干

Makefile: modifying stem in pattern rule

我在名为 datahelpers 的目录中有文件,我想使用它们在 result.

中创建目标文件

目录结构如下:

data
 + A
 | + file1
 | + file2
 | + ...
 + B
 | + file1
 ...
helpers
 + file1
 + file2
 ...

result 中的目录结构与 data 中的相同。因此,我想编写以下规则:

result/%: data/% helpers/% script
    script $@ $(word 1,$^) $(word 2,$^)

问题在于helpers目录中的file1file2等不在子目录中

我现在有以下选择:

但是,我更愿意写以下内容之一:

result/%: data/% helpers/$(basename %) # this doesn't work
result/%: data/% helpers/$(basename $*) # this doesn't work either

有什么方法可以通过修改匹配的词干来修改规则声明中的模式吗?

做你想做的唯一方法是在你的 makefile 中启用 Secondary Expansion

示例:

Note that the directory prefix (D), as described in Implicit Rule Search Algorithm, is appended (after expansion) to all the patterns in the prerequisites list. As an example:

.SECONDEXPANSION:

/tmp/foo.o:

%.o: $$(addsuffix /%.c,foo bar) foo.h
        @echo $^

The prerequisite list printed, after the secondary expansion and directory prefix reconstruction, will be /tmp/foo/foo.c /tmp/bar/foo.c foo.h. If you are not interested in this reconstruction, you can use $$* instead of % in the prerequisites list.

所以像这样的东西应该可以工作(未经测试):

.SECONDEXPANSION:
result/%: data/% helpers/$$(notdir %)

make 的 basename 与 shell 的 basename 不同(经常 让我失望)。

如果你想使用 $(foreach) 虽然你想要类似(未测试)的东西:

define dirrule
result//%: data//% helpers/%
        @echo cmd 1
        @echo cmd 2
endef

$(foreach dir,subdir1 subdir2 ... subdir20,$(eval $(call dirrule,$(dir))))