我正试图分解一个非常庞大的代码库的make构建系统,然而我无法看到make调用的每一条命令,因为它调用了当前目录之外的许多目录中的各种make文件。我遵循了这个答案和其他各种答案 在不使用CMake的情况下,让make打印命令在执行前进行。
虽然上面产生了一些进步,而且很有启发性,但这不是我需要的本垒打。它提供的解决方案是看到使调用的命令。这是比伟大的。然而,问题是此后被调用的各种子make命令。我只看到这些命令被打印出来,而没有额外的子make发生的信息。我试着将make别名为
alias make='make SHELL='\''/bin/bash -x'\'''
# or
alias make='make -n'
然而上面未能将调用的make命令替换成别名。有没有其他方法可以让我分解一个大型代码库的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中是不存在的,比如make用来调用配方中的注释。 和shell函数一样。
你也不能设置 SHELL
变量到一个使用参数的命令中去。SHELL
必须只是一个命令名。 不过,您可以将 .SHELLFLAGS
变量为额外的选项来传递给shell。 不要忘了你需要用 -c
选项,以及您添加的任何标志!
类似于 .SHELLFLAGS=-xc
如果你的makefile都能正确地调用它们的子make,那么使用 make -n
作为初始调用应该是Just Work。
我所说的 "正确调用 "的意思是,它们应该是 始终 使用 $(MAKE)
变量,并且在调用子制造时绝不使用原始的 make
命令。
如果它们没有正确地调用sub-make,而你又不能解决这个问题,那么你最好的办法是写一个叫做 make
的别名,然后将其添加到您的 PATH
所以它首先被发现。 显然,在脚本中,你必须使用一个完全限定的路径来运行 "真正的 "make,否则你会得到无限的递归 :)
你可以很容易地用 --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