使用Make是一种很好的依赖目录内容的方法。
基本上我有一些应用程序代码依赖的生成代码。如果目录的内容发生变化,则生成的代码只需要更改,不一定是在内部文件更改其内容时。因此,如果删除或添加或重命名文件,我需要运行规则。
我的第一个想法是生成目录的文本文件列表和最后列表的差异。更改意味着重新运行构建。我想我必须将generate和diff部分传递给bash脚本。
我希望以某种方式在他们的无限智慧中可能有一个更容易的解决方案。
答案 0 :(得分:10)
感谢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
现在看来,对目录或文件的任何更改(添加,删除,重命名,修改)都将导致此规则运行。这里的文件名可能存在一些问题(空格可能会导致问题)。
答案 1 :(得分:5)
假设您的目录名为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
变量。
答案 2 :(得分:0)
使规则依赖于目录的一个缺点是,对该目录进行任何 更改都会导致规则过时-包括在该目录中创建生成的文件。因此,除非您将源文件和目标文件分离到不同的目录中,否则该规则将在每个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
规则的错误肯定触发。