查看 make 的命令以及之后所有调用的 make 文件

See commands of make and all called make files thereafter

我正在尝试分解一个非常大的代码库的 make 构建系统,但是我无法看到 make 调用的每个命令,因为它在当前目录之外的许多目录中调用各种 make 文件。我遵循了这个答案和其他各种答案 Making make print commands before executing when NOT using CMake

尽管以上内容取得了一些进展并且很有启发性,但它并不是我需要的家 运行。它提供了查看调用命令的解决方案。这比伟大更好。但是,问题在于此后调用的各种 sub make 命令。我只看到那些打印出来的命令,没有关于正在发生的事情的附加信息。我试图别名 make 这样

alias make='make SHELL='\''/bin/bash -x'\'''

# or

alias make='make -n'

然而,以上无法用别名替换调用的 make 命令。有没有另一种方法可以剖析大型代码库构建系统?

> make
rmdir --ignore-fail-on-non-empty /somefolder* 2> /dev/null; true
cd /someotherfolder/; make cur-dir=somefolder dirs-to-build=somemorefolders/ env_variable another_variable someMakeRule # no output from this  make
make  TARGET=someTarget env_variable gdbinit source_dir someMakeRule; # no output from this  make
# ...
# output from first top makefile
# ...
make[1]: Nothing to be done for 'someMakeRule'.

您不能使用别名,因为别名仅存在于交互式 shell 中,而不存在于非交互式 shell 中,例如用于在食谱中调用注释的别名。与 shell 函数相同。

您也不能将 SHELL 变量设置为使用参数的命令:SHELL 的值只能是一个命令名称。不过,您可以将 .SHELLFLAGS 变量设置为额外的选项以传递给 shell。不要忘记除了您添加的任何标志之外,您还需要 -c 选项!

类似于.SHELLFLAGS=-xc

如果您的 makefile 都正确地调用了它们的 submake,那么使用 make -n 作为初始调用应该就可以了。

"properly invoking" 我的意思是,他们应该 总是 在调用子 make 时使用 $(MAKE) 变量并且永远不要使用原始 make命令。

如果他们没有正确调用 sub-make 而你无法修复它,那么你能做的最好的事情就是编写一个名为 make 的 shell 脚本来完成你上面的别名所做的事情,然后将其添加到您的 PATH 以便首先找到它。显然,在脚本中,您必须使用 运行 的完全限定路径,"real" 否则您将获得无限递归:)

您可以使用 --trace 选项轻松跟踪执行情况。考虑以下示例,其中有人想只显示干净的输出而没有任何冗长的选项:

$ cat Makefile
all: foo
        @echo Done with $@

foo: bar
        @echo Done with $@

bar:
        @$(MAKE) -f Makefile2 bar

.SILENT:

$ cat Makefile2
bar: baz
        @echo Done with $@

baz:
        @echo Done with $@

常规构建不允许检查发生了什么:

$ make
Done with baz
Done with bar
Done with foo
Done with all

但是 --trace 会显示正在发生的事情以及原因:

$ make --trace
Makefile:8: target 'bar' does not exist
make -f Makefile2 bar
Makefile2:5: target 'baz' does not exist
echo Done with baz
Done with baz
Makefile2:2: update target 'bar' due to: baz
echo Done with bar
Done with bar
Makefile:5: update target 'foo' due to: bar
echo Done with foo
Done with foo
Makefile:2: update target 'all' due to: foo
echo Done with all
Done with all