Makefile 动态生成文件目标

Makefile 动态生成文件目标,makefile,Makefile,下面是我正在使用的GNU Makefile的一个片段。基本上,我有一个图像目录,当运行make时,我希望将其复制到dist目录中,但我不希望单独列出每个图像 DISTDIR := dist IMG := $(shell find app/img -type f) $(subst app/img, $(DISTDIR), $(filter-out %.svg, $(IMG)))): $(filter-out %.svg, $(IMG)) @cp $? $(DISTDIR) 这种工

下面是我正在使用的GNU Makefile的一个片段。基本上,我有一个图像目录,当运行make时,我希望将其复制到dist目录中,但我不希望单独列出每个图像

DISTDIR := dist
IMG := $(shell find app/img -type f)
$(subst app/img, $(DISTDIR), $(filter-out %.svg, $(IMG)))): $(filter-out %.svg, $(IMG))
        @cp $? $(DISTDIR)

这种工作方式,除了在源文件更改时(在
app/img
中),使始终重新生成目标文件。处理这种情况的正确方法是什么?

如果您提供了一些示例结果,那么回答起来就更容易了。假设find操作返回以下文件:
app/img/foo.svg
app/img/bar.jpg
,以及
app/img/baz.png

在这种情况下,
filter out
函数将返回文件
app/img/bar.jpg
app/img/baz.png
。这意味着生成的规则如下所示:

$(DISTDIR)/bar.jpg $(DISTDIR)/baz.png: app/img/bar.jpg app/img/baz.png
        @cp $? $(DISTDIR)
事情是这样的:当您在一个显式规则中定义N个目标时,就像定义N个规则,每个目标一个,具有所有相同的先决条件。因此,上面的内容与写这篇文章的内容相同:

$(DISTDIR)/bar.jpg: app/img/bar.jpg app/img/baz.png
        @cp $? $(DISTDIR)
$(DISTDIR)/baz.png: app/img/bar.jpg app/img/baz.png
        @cp $? $(DISTDIR)
现在,您可以了解为什么会出现这样的行为:每个目标都将所有文件列为先决条件,因此每当更改任何文件时,都会重建目标

答案是,在make中,您通常应该尝试编写规则,仅从目标的先决条件创建一个目标。一个简单的方法是使用模式规则;上面的模式规则可能如下所示:

DISTDIR := dist

$(DISTDIR)/% : app/img/%
    @cp $< $@

make会解决剩下的问题

太好了!谢谢你的帮助!
IMG := $(shell find app/img -type f)

all: $(IMG:app/img/%=$(DISTDIR)/%)