一个依赖于指定目录下所有文件(包括子目录中的文件)的Makefile规则

65

在我的Makefile中有一条规则,它将整个目录(res/)压缩成一个ZIP文件。显然,当 res/ 目录下的任何文件发生更改时,此规则需要执行。因此,我希望这个规则的前提条件是该目录下的所有文件。如何实现这个规则?

在启用了 Bash 的 globstar 选项 后,您可以使用通配符模式 res/**/* 获取该目录中所有文件的列表。但是,如果将其指定为 Makefile 中的先决条件,则似乎不起作用:

filename.jar: res/**/*

即使在res/中触摸文件后,Make仍然会报告。
make: `filename.jar' is up to date.

很明显它没有识别出这个模式。

如果我将目录本身声明为先决条件:

filename.jar: res

如果文件被修改,make 不会重新执行(我认为 make 只检查目录本身的修改日期,当直接子级被添加、删除或重命名时才会更改)。


可能是重复的问题:Makefile:依赖于目录中的每个文件 - Ciro Santilli OurBigBook.com
1个回答

84

这个:

filename.jar: $(wildcard res/**/*)

似乎至少在某些平台上可以工作。

编辑:

或者更好的方法是,直接解决问题:

filename.jar: $(shell find res -type f)

2
“通配符”建议对我不起作用,但“查找”可以。 (我只使用了 $(shell find res) 以便在删除文件时也触发它。) - Mechanical snail
8
注意:如果在制作jar包后删除了其中一个输入文件,make命令将不会注意到这个改变。为了能够检测到文件的删除,可以将文件列表存储在一个类似于https://dev59.com/M3A75IYBdhLWcg3wi5sr#3237349的文件中。 - slowdog
18
当一个文件被删除时,res 目录的修改日期也会发生改变。添加 res 目录本身的依赖可能会解决这个问题。只需从 find 命令中移除 -type f 即可。 - Haoshu
8
为了允许空格, filename.jar: $(shell find res -type f | sed 's/ /\\ /g') 对我来说似乎是有效的。 - flungo
1
我所知道的任何 Make 版本中都不存在 ** 语法。请参见 https://www.gnu.org/software/make/manual/html_node/Wildcards.html#Wildcards - Radon Rosborough
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接