3

GNU Makefiles 中是否有任何技巧来获取规则的所有依赖项?

例子:

rule1:  dep1_1 dep1_2 dep1_3

rule2:  dep2_1 dep2_2 rule1

dump_deps:
    echo "Dependencies of rule1: $(call do_the_trick, $(rule1))"
    echo "Dependencies of rule2: $(call do_the_trick, $(rule2))"

install:   $(prefix install-,$(call do_the_trick, $(rule1)))

我希望能够打电话来make dump_deps看看:

dep1_1 dep1_2 dep1_3
dep2_1 dep2_2 dep1_1 dep1_2 dep1_3

或者自动安装依赖项之类的make install东西。

可能吗?


编辑:

我更改了示例以更好地表明我想要一些自动的东西,而不必自己硬编码依赖项列表。

4

3 回答 3

3

您无法显示传递依赖关系,只能显示直接依赖关系,但是,您可以获取下面生成的输出并将其输入程序dot(的一部分 graphviz)以理解这些传递关系。

编辑:我想你也可以用其他方式对结果进行后处理以列出部门,但我认为漂亮的图片更好;如果您不同意,请随时投反对票;)

这是一个示例生成文件(在 c&p 时注意丢失的选项卡!):

# Makefile that demonstrates how to dump dependencies.
# The macros we use for compiling stuff.
CC_OBJ=$(CC) -o $@ -c $(CFLAGS) $<
CC_BIN=$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $^

# If we get "DUMP_DEPS=1 DUMP_DOT=1" on the command line, then instead of
# make-style dependencies, we'll output 'dot' syntax.
# Note: normally, DUMP_DOT_TAIL is undefined, so it doesn't generate any noise.
ifeq ($(DUMP_DOT),1)
DUMP_DOT_HEAD=digraph dependencies {
DUMP_DOT_TAIL=@echo "}"
$(info $(DUMP_DOT_HEAD))
list_dep=@for f in $^; do echo "    \"$@\" -> \"$$f\";"; done
else 
list_dep=@echo "$@: $^"
endif

# If we get "DUMP_DEPS=1" on the command line, then
# instead of building the code, just print the dependencies.
ifeq ($(DUMP_DEPS),1)
CC_OBJ=$(list_dep)
CC_BIN=$(list_dep)
endif

# An implicit rule that builds *.c -> *.o.
%.o:%.c
    $(CC_OBJ)

# Variables for stuff we wanna build.
target=hello

objects=main.o
objects+=stuff.o
objects+=yeah.o

# The top-level 'all' target.
.PHONY: all
all: $(target)
    $(DUMP_DOT_TAIL)

# Builds our final executable
$(target): $(objects)
    $(CC_BIN)

# A standard clean target.
.PHONY: clean
clean:
    -rm -f $(target) $(objects)    

现在,您可以这样做:

make -B DUMP_DEPS=1

它将通过并列出您的所有先决条件是制作“目标:先决条件”的风格。示例输出:

正常运行:

cc -o main.o -c  main.c
cc -o stuff.o -c  stuff.c
cc -o yeah.o -c  yeah.c
cc -o hello  main.o stuff.o yeah.o

make -B DUMP_DEPS=1

main.o: main.c
stuff.o: stuff.c
yeah.o: yeah.c
hello: main.o stuff.o yeah.o

make -B DUMP_DEPS=1 DUMP_DOT=1

digraph dependencies {
    "main.o" -> "main.c";
    "stuff.o" -> "stuff.c";
    "yeah.o" -> "yeah.c";
    "hello" -> "main.o";
    "hello" -> "stuff.o";
    "hello" -> "yeah.o";
}

然后,您可以运行以下命令将漂亮的图片输出到 SVG 图像:

make -B DUMP_DEPS=1 DUMP_DOT=1 | dot -Tsvg > deps.svg

这是它的样子(这实际上是一个 png,用 生成-Tpng > deps.png):

图片

我认为这需要一些额外的工作才能在所有情况下产生准确的结果,但原则是合理的(例如,如果您使用 gcc 生成的依赖文件,则需要先创建它们)。

于 2014-08-08T18:23:18.847 回答
1

这应该列出所有依赖项:

DEPEND = dep1 dep2 dep3

.PHONY: $(DEPEND)

dump_deps: $(DEPEND)
     @printf "%s\n" $^

您应该根据需要删除带有 .PHONY 目标的行。它用于示例。请注意,在行首和 printf 之间有一个制表符。

于 2012-09-28T13:55:35.657 回答
1

使用 make 实用程序可用的 buit in 变量 $^ - 这表示规则的所有依赖项。

还通过您的代码查看,我确实将 rule1 变成了变量/宏形式以适合我的目的......

rule1 := dep1 dep2 dep3
于 2013-03-24T01:25:00.833 回答