Makefile GNU使单个目标生成多个文件
我目前有一个工具,可以在一次输入的情况下生成多个文件。因此,给定一个文件“a.parent”,它将生成一组未知的命名文件,如“b.child”、“c.child”、“z.child”等。这都取决于“a.parent”中的内容 我的问题是,我如何正确地为此构建一个makefile目标,以便1)它不会多次运行该工具,因为一次运行将生成所有文件;2)如果删除任何生成的文件,它将再次重新运行该工具并重新生成所有文件;3)如果“a.parent”比其一个从属文件更新,它将重新运行该工具,并且4)我不必列出Makefile本身中的每个子文件,因为我真的不关心生成了什么,只关心生成了什么Makefile GNU使单个目标生成多个文件,makefile,gnu-make,Makefile,Gnu Make,我目前有一个工具,可以在一次输入的情况下生成多个文件。因此,给定一个文件“a.parent”,它将生成一组未知的命名文件,如“b.child”、“c.child”、“z.child”等。这都取决于“a.parent”中的内容 我的问题是,我如何正确地为此构建一个makefile目标,以便1)它不会多次运行该工具,因为一次运行将生成所有文件;2)如果删除任何生成的文件,它将再次重新运行该工具并重新生成所有文件;3)如果“a.parent”比其一个从属文件更新,它将重新运行该工具,并且4)我不必列出
问题是,至少对我来说,makefile是建立在确切知道最终状态的基础上的。但是,在这种情况下,我希望它只关心它是什么。像下面这样的makefile就足够了 这就是想法:作为多个未指定的
*.child
文件的代理目标
您的工具可能会生成,请使用由创建的这些文件的清单
与创建文件的配方相同。配方将删除过时的*。子项
文件和清单,然后在a.parent
上运行工具以生成新的*.child
文件,
然后为新的*.child
文件创建一个新清单
制作此配方的规则是:
- 清单不存在,或者
- 现有清单早于父清单,或
- 现有清单比某些
*.child
文件旧,或
- 现有清单不真实,即中命名的
*.child
文件集
清单与存在的集合不同
评论中解释了详情:
.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
(因此对于我的tool.sh
,manifest.txt
将只包含与
a.parent
)
当然,这个解决方案不是防弹的。例如,如果有人删除
文件系统和清单中的一些*.child
文件
make不会注意到。此外,显式的makemanifest.txt
也不会起任何作用
即使有人伪造了舱单。这个漏洞可以用一些方法来弥补
makefile的复杂性,但防止此类破坏的预防措施,如
这些可能性可能并不重要。如果有办法让工具说出它将创建的文件的名称,您可能可以使用这种方法,您可以使用gcc-MD
(和friends)函数生成.d
make include文件来为您处理一些文件。prereqs的可变性可能会在某个时候影响到你,即使你这样做了。虽然我认为来自我们的常驻疯人院的高级自动dep技术在这里也可能有所帮助。这个问题似乎意味着它必须作为一个单一的目标来实现,但这似乎有点人为的限制。我应该认为,利用服务器检测何时运行该工具的多个目标会更容易。
b.child
c.child
d.child