一个像下面这样的makefile就足够了。
这就是想法:作为多个未指定*.child 文件的代理目标
您的工具可能会生成,使用 manifest 由
创建文件的相同配方。配方删除陈旧的*.child
文件和清单,然后在a.parent 上运行您的工具以制作新的*.child 文件,
然后为新的*.child 文件创建一个新清单。
制作这个食谱的规则是:
- 清单不存在,或
- 现有清单早于
a.parent,或
- 现有清单早于某些
*.child 文件,或者
- 现有清单不真实,即
*.child 文件集在
清单与存在的集合不同。
细节在cmets中有解释:
.PHONY: all clean
# $(manifest) will be the space-punctuated list of files, if any, that are
# listed in 'manifest.txt', if it exists, else the empty string.
manifest = $(shell if [ -f manifest.txt ]; then cat manifest.txt; fi)
# $(outputs) will be the space-punctuated list of '*.child' files, if any, in
# the current directory, else the empty string
outputs = $(shell ls -1 *.child 2>/dev/null)
# Default target:
# If there is any mismatch between $(manifest) and $(outputs)
# then clean and remake. Else just make 'manifest.txt'
ifneq '$(outputs)' '$(manifest)'
all:
$(MAKE) clean && $(MAKE)
else
all: manifest.txt
endif
manifest.txt : a.parent $(outputs)
$(MAKE) clean && ./tool.sh a.parent && ls -1 *.child > $@
clean:
rm -f *.child manifest.txt
在manifest.txt 的配方中,tool.sh 代表您使用的任何工具
正在a.parent 上运行。为了测试makefile,我简单地使用了:
#!/bin/bash
# tool.sh
while read line
do
echo "This is file $line" > $line
done < $1
连同包含*.child 文件名称的a.parent
生成,每行一个,例如
b.child
c.child
d.child
(所以对于我的tool.sh,manifest.txt 将只包含与
a.parent.)
当然,此解决方案并非万无一失。例如,如果有人删除
来自文件系统的一些*.child文件和来自清单,
make 不会注意到。此外,明确的 make manifest.txt 将无济于事
即使有人伪造清单。这个漏洞可以用一些来填补
makefile 的复杂性,但要注意防止此类破坏
因为这些可能并不重要。