我发现了一种破解方法,至少可以输出结构清晰的信息,以了解哪些目标取决于哪些先决条件。不利的一面是,这是很麻烦的。换句话说,您需要更改makefile以将所有目标的构建配方包装到一个小的条件函数中。我将发布一个简短的示例:
getRecipe = $(if $(DEPENDENCY_GRAPH),@echo Target $@ depends on prerequisites "$^",$(1))
VARIABLE_TARGET_NAME = foobar.txt
all : TopLevelTarget
TopLevelTarget : Target_A Target_D
$(call getRecipe,\
@echo Building target $@)
Target_A : Target_B
$(call getRecipe,\
@echo Building target $@)
Target_D : Target_C
$(call getRecipe,\
@echo Building target $@)
Target_B : $(VARIABLE_TARGET_NAME)
$(call getRecipe,\
@echo Building target $@)
Target_C :
$(call getRecipe,\
@echo Building target $@)
$(VARIABLE_TARGET_NAME) :
$(call getRecipe,\
@echo Building target $@)
在此示例中,我使用了手动滚动的getRecipe函数来包装每个目标的配方,然后决定是实际运行该配方还是仅输出正在构建的目标及其依赖的先决条件。后者仅在DEPENDENCY_GRAPH
设置了变量(例如,作为环境变量)时才发生。在该示例中,构建配方仅是一个回声,表明正在构建目标,但是显然可以用您选择的命令替换它。
随着DEPENDENCY_GRAPH
设置为1,这导致输出:
Target foobar.txt depends on prerequisites ""
Target Target_B depends on prerequisites "foobar.txt"
Target Target_A depends on prerequisites "Target_B"
Target Target_C depends on prerequisites ""
Target Target_D depends on prerequisites "Target_C"
Target TopLevelTarget depends on prerequisites "Target_A Target_D"
它应该足够容易解析然后转换为点图。
如果DEPENDENCY_GRAPH
完全不设置或设置为0,则输出为:
Building target foobar.txt
Building target Target_B
Building target Target_A
Building target Target_C
Building target Target_D
Building target TopLevelTarget
或者换句话说,使用常规构建配方。我尚未测试过这种方法是否可以可靠地用于复杂的配方。我已经遇到的一个问题是,它对于多行配方根本不起作用。
例如,在最后一个目标的构建配方中,如果除了说正在构建目标之外,我实际上还想要touch
该文件:
$(VARIABLE_TARGET_NAME) :
$(call getRecipe,\
@echo Building target $@\
touch $@)
make
似乎认为该touch $@
部分只是上一行中回显的一部分:
Building target foobar.txt touch foobar.txt
如果我在上一行中省略了结尾的反斜杠,则make
抱怨*** unterminated call to function
呼叫“:丢失” )'. Stop.
如果有人知道如何获取make
打出好球,我将不知所措。:)
编辑:这种方法的另一个问题是,这只有在不存在构建结果的情况下才有效,因为make
显然不会执行它认为是最新的目标的构建配方。