makefile目标中的通配符扩展

时间:2014-10-27 04:47:28

标签: makefile gnu-make

假设我有一组源文件:

src/foo/file.abc
src/foo/otherfile.abc

我想做一些操作(为简单起见,让我们只说复制),导致目标文件在几个不同的地方:

dest/bar/file.xyz
dest/bar/otherfile.xyz
dest/baz/file.xyz
dest/baz/otherfile.xyz
dest/something/file.xyz
dest/something/otherfile.xyz

如何在Makefile中表达该依赖关系,以便更新必备文件会导致配方重新创建目标?

GNU Make manual"通配符扩展由目标和先决条件中的make自动执行" 。顺便说一句,我希望

dest/*/%.xyz : src/foo/%.abc
    install -d $< $@

工作,但失败了:

$ make -f test.mk dest/bar/file.xyz
make: *** No rule to make target `dest/bar/file.xyz'.  Stop.

我是否误解目标中的通配符扩展?有没有更好的方法来实现我之后的目标?

环境: GNU Make 3.82.90
32位Cygwin

3 个答案:

答案 0 :(得分:0)

你所追求的并不完全清楚。怎么样:

dest/%.xyz:
    cp src/foo/$(notdir $*).abc $@

现在make -f test.mk dest/bar/file.xyz会将src/foo/file.abc复制到dest/bar/file.xyz。这就是你想要它做的,或者你是否希望它将文件复制到其他目的地,或者在同一操作中复制其他文件,或者是什么?

答案 1 :(得分:0)

是执行通配符扩展,根据shell 。如果您没有任何目标文件,那么扩展将一无所获。 Make不能神奇地找出你想要的目标文件。

因此,您需要声明所需的目标文件并按以下步骤继续:

DEST_FILES := \
    dest/bar/file.xyz \
    dest/bar/otherfile.xyz \
    dest/baz/file.xyz \
    dest/baz/otherfile.xyz \
    dest/something/file.xyz \
    dest/something/otherfile.xyz \

.PHONY: all
all: $(DEST_FILES)

.SECONDEXPANSION:

$(DEST_FILES): %xyz: src/foo/$$(notdir $$*)abc Makefile
    cp $< $@

答案 2 :(得分:0)

我找到了一个依赖于GNU扩展.SECONDEXPANSION的解决方案,这不是理想的,但总比没有好:

.SECONDEXPANSION:
dest/%.xyz : src/foo/$$(@F)
    install -D $< $@