使用Make有一种很好的方法来依赖目录的内容。
基本上,我有一些生成的代码,应用程序代码依赖于这些代码。仅当目录的内容更改时,才需要更改生成的代码,如果其中的文件更改了内容,则不必更改。因此,如果文件被删除,添加或重命名,则需要运行规则。
我首先想到的是生成目录的文本文件列表,并将其与最后一个列表进行比较。更改意味着重新运行构建。我想我必须将generate和diff部分传递给bash脚本。
我希望他们的无限智能可能会有更简单的解决方案。
对让我走上正轨的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
现在看来,对目录或文件的任何更改(添加,删除,重命名,修改)都会导致该规则运行。这里的文件名可能存在一些问题(空格可能会引起问题)。
假设您的目录名为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
变量。
使规则依赖于目录的一个缺点是any对该目录的更改将导致规则过时-包括在该目录中创建生成的文件。因此,除非您将源文件和目标文件分隔到不同的目录中,否则该规则将在每个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.*
代码生成规则的第二行确保仅当相关文件列表更改时才修改.filelist.current
,避免了对generate
规则的错误肯定触发。