如何定义具有未知中间节点名称的依赖关系图?

时间:2012-02-25 04:58:15

标签: build makefile scons

我正在使用工具链,我不知道所有中间文件的名称。

E.g。我知道我开始使用foo.s,然后通过几个步骤来获取foo.XXXX.sym和foo.XXXX.hex,深入挖掘。然后在foo.XXXX.hex和foo.XXXX.sym上运行其他工具,最终我得到了像final.results这样的东西。

但是,问题是我不知道XXXX是什么。它是来自其他一些参数的派生,但可能会远离它们。

现在,在运行生成foo.XXXX。{sym,hex}的工具/步骤之后,我现在通常扫描整个结果目录,查找foo。*。{sym,hex}。即我的代码可以识别中间输出,我只是不确切知道名字是什么。

我通常使用make或scons - 实际上,我更喜欢scons,但我的团队非常喜欢make。我对其他构建工具持开放态度。

我想做的是能够说(1)“make final.results”,或“scons final.results”,(2)并让它扫描部分树; (3)弄清楚,虽然它不知道完整路径,但它肯定知道它必须运行第一步,(4)在第一步之后,寻找并找到foo.XXX。*文件; (5)并将它们插入依赖树。

即。我想在构建完成后完成构建依赖关系树。

一位朋友对scons在这方面的局限性感到沮丧,以至于他编写了自己的构建工具。不幸的是它是专有的。

我想我可以创建第一个构建图,比如使用许多.PHONY目标,然后在我完成第一步后,生成一个带有新名称的新makefile,并让第一个make调用新的生成第二个makefile。看起来很笨拙。还有更优雅的方式吗?

2 个答案:

答案 0 :(得分:1)

GNU make具有您可以使用的“自动rexec”功能。见How Makefiles Are Remade

在完成读取所有makefile(包括自动和/或在命令行中找到的makefile,以及所有包含的makefile)之后,它将尝试重建其所有makefile(使用它知道的规则)。如果这些makefile中的任何一个都是自动重建的,那么make将重新执行,这样它就可以重新读取最新版本的makefile / included文件,并重新开始(包括重新尝试构建所有的makefile)。

在我看来,你应该能够做到这一点。你可以在你的主makefile和“-include foo.sym.mk”中写一下,然后通过在foo.s上调用工具来建立“foo.sym.mk”的规则,然后运行你的“识别下一个”步骤“代码并生成”foo.sym.mk“文件,该文件定义了创建的中间输出的规则。类似的东西(由于你的问题缺乏特异性,我无法给出你理解的真实例子):

SRCS = foo.s bar.s baz.s
-include $(patsubst %.s,%.sym.mk,$(SRCS))
%.sym.mk: %.s
        <compile> '$<'
        <recognize output and generate makefile> > '$@'

现在当make运行时,它将看到foo.sym.mk已经过时(如果是)使用常规算法,它将重建foo.sym.mk,这作为“副作用”导致foo.s要编译的文件。

当然,“foo.sym.mk”文件可以包含另一个文件,如果需要,可以识别下一步。

我不是说这将是微不足道的,但它似乎可以根据你的描述进行。

答案 1 :(得分:0)

在运行任何规则之前构建图形,因此不会有完美的答案。以下是一些相当干净的解决方案。

1)在命令中使用PHONY中间体和通配符。 (您不能使用Make通配符,因为make会在运行规则之前扩展它们。)

final.results: middle                                                         
    # build $@ using $(shell ls foo.*.sym) and $(shell ls foo.*.hex)

.PHONY: middle
middle: foo.s
    # build foo.XXXX.sym and foo.XXXX.hex from $<

2)使用递归Make(这并不像人们说的那么糟糕,有时非常有用。)

SYM = $(wildcard foo.*.sym)
HEX = $(wildcard foo.*.hex)

# Note that this is is the one you should "Make".
# I've put it first so it'll be the default.
.PHONY: first-step
first-step: foo.s
    # build foo.XXXX.sym and foo.XXXX.hex from $<
    @$(MAKE) -s final.results                                               

final.results:                                                                
    # build $@ using $(SYM) and $(HEX)

3)类似于2,但是makefile的规则会导致Make再次运行。

SYM = $(wildcard foo.*.sym)
HEX = $(wildcard foo.*.hex)

final.results:                                                                
    # build $@ using $(SYM) and $(HEX)

Makefile: foo.s
    # build foo.XXXX.sym and foo.XXXX.hex from $<
    @touch $@