Makefile 规则取决于目录内容的变化
Posted
技术标签:
【中文标题】Makefile 规则取决于目录内容的变化【英文标题】:Makefile rule depend on directory content changes 【发布时间】:2014-09-20 06:05:57 【问题描述】:使用 Make 是否有依赖目录内容的好方法。
基本上我有一些应用程序代码依赖的生成代码。生成的代码仅在目录内容发生更改时才需要更改,而不是在文件内容更改时才需要更改。因此,如果文件被删除、添加或重命名,我需要运行规则。
我的第一个想法是生成目录的文本文件列表,并将其与最后一个列表进行比较。更改意味着重新运行构建。我想我必须将生成和差异部分传递给 bash 脚本。
我希望在他们无限的智慧中可能有一个更简单的解决方案。
【问题讨论】:
Makefile rule that depends on all files under a directory (including within subdirectories)的可能重复 【参考方案1】:让规则依赖于目录的一个缺点是,任何对该目录的更改都会导致规则过期 - 包括在该目录中创建生成的文件。因此,除非您将源文件和目标文件分隔到不同的目录中,否则该规则将在每个 make
上触发。
这是一种替代方法,允许您指定与添加、删除和更改相关的文件子集。例如,假设只有 *.foo
文件是相关的。
# replace indentation with tabs if copy-pasting
.PHONY: codegen
codegen:
find . -name '*.foo' |sort >.filelist.new
diff .filelist.current .filelist.new || cp -f .filelist.new .filelist.current
rm -f .filelist.new
$(MAKE) generate
generate: .filelist.current $(shell cat .filelist.current)
generate-my-code
.PHONY: clean
clean:
rm -f .filelist.*
codegen 规则中的第二行确保.filelist.current
仅在相关文件列表发生变化时被修改,避免误报触发generate
规则。
【讨论】:
【参考方案2】:感谢 gjulianm 让我走上正轨。他的解决方案非常适合单个目录。
为了让它递归工作,我做了以下操作。
ASSET_DIRS = $(shell find ../../assets/ -type d)
ASSET_FILES = $(shell find ../../assets/ -type f -name '*')
codegen: ../../assets/ $(ASSET_DIRS) $(ASSET_FILES)
generate-my-code
现在看来,对目录或文件的任何更改(添加、删除、重命名、修改)都会导致此规则运行。这里的文件名可能存在一些问题(空格可能会导致问题)。
【讨论】:
这对删除有用吗?我没有机会对其进行测试,但我认为删除只会将该文件作为依赖项消除。编辑:当然,目录会在删除的情况下更新。我明白了。 可能不需要“-name '*'”,find 已经找到所有文件了? 请注意,“*”会阻止隐藏文件被包含在内,这可能是可取的【参考方案3】:假设你的目录叫做dir
,那么这个makefile就会做你想做的事:
FILES = $(wildcard dir/*)
codegen: dir # Add $(FILES) here if you want the rule to run on file changes too.
generate-my-code
正如评论所说,如果您希望代码也依赖文件内容,也可以添加 FILES
变量。
【讨论】:
这行得通,但它不能递归地工作。有问题的目录中有目录。以上是关于Makefile 规则取决于目录内容的变化的主要内容,如果未能解决你的问题,请参考以下文章