我正在使用工具链,我不知道所有中间文件的名称。
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。看起来很笨拙。还有更优雅的方式吗?
答案 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 $@