【问题标题】:GNU Make Single Target Generates Multiple FilesGNU Make 单个目标生成多个文件
【发布时间】:2014-05-08 18:14:36
【问题描述】:

我目前有一个工具可以在给定单个输入的情况下生成多个文件。因此,给定一个文件“a.parent”,它会生成一堆未知的命名文件,例如“b.child”、“c.child”、“z.child”等。这一切都取决于“父母”。

我的问题是,我怎样才能正确地为此构建一个 makefile 目标,以便 1)它不会多次运行该工具,因为一次运行会生成所有这些文件,2)如果任何生成的文件是删除,它将再次重新运行该工具并重新生成所有这些,3)如果“a.parent”比其依赖项之一新,它将重新运行该工具,以及 4)我不必列出每一个Makefile 本身中的子文件,因为我真的不在乎生成了什么,只关心它是生成的。

问题在于,至少对我而言,Makefile 是围绕着准确地知道您的最终状态应该是什么而构建的。但是,在这种情况下,我希望它只关心它是什么。

【问题讨论】:

  • 如果有一种方法可以让该工具吐出它将创建的文件的名称,您可能可以使用这种方式,您可以使用 gcc -MD(和朋友)函数生成 @ 987654322@ 制作包含文件来为您处理一些此类问题。即使您这样做,前提条件的可变性也可能会在某个时候咬住您。虽然我认为我们常驻的 MadScientist 提供的高级自动深度技术在这里也可能有所帮助。
  • 这个问题似乎暗示它必须作为一个单一的目标来实现,但这似乎有点人为的限制。我应该认为利用服务器的多个目标来检测何时运行该工具会更容易。

标签: makefile gnu-make


【解决方案1】:

一个像下面这样的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.shmanifest.txt 将只包含与 a.parent.)

当然,此解决方案并非万无一失。例如,如果有人删除 来自文件系统的一些*.child文件来自清单, make 不会注意到。此外,明确的 make manifest.txt 将无济于事 即使有人伪造清单。这个漏洞可以用一些来填补 makefile 的复杂性,但要注意防止此类破坏 因为这些可能并不重要。

【讨论】:

    猜你喜欢
    • 2011-10-28
    • 1970-01-01
    • 2011-02-27
    • 2013-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多