ChatGPT解决这个技术问题 Extra ChatGPT

如何强制 make/GCC 向我显示命令?

我正在尝试调试编译问题,但我似乎无法让 GCC(或者它可能是 make??)向我展示它正在执行的实际编译器和链接器命令。

这是我看到的输出:

  CCLD   libvirt_parthelper
libvirt_parthelper-parthelper.o: In function `main':
/root/qemu-build/libvirt-0.9.0/src/storage/parthelper.c:102: undefined reference to `ped_device_get'
/root/qemu-build/libvirt-0.9.0/src/storage/parthelper.c:116: undefined reference to `ped_disk_new'
/root/qemu-build/libvirt-0.9.0/src/storage/parthelper.c:122: undefined reference to `ped_disk_next_partition'
/root/qemu-build/libvirt-0.9.0/src/storage/parthelper.c:172: undefined reference to `ped_disk_next_partition'
/root/qemu-build/libvirt-0.9.0/src/storage/parthelper.c:172: undefined reference to `ped_disk_next_partition'
collect2: ld returned 1 exit status
make[3]: *** [libvirt_parthelper] Error 1

我想看到的应该是这样的:

$ make
gcc -Wall   -c -o main.o main.c
gcc -Wall   -c -o hello_fn.o hello_fn.c
gcc   main.o hello_fn.o   -o main

请注意此示例如何显示完整的 gcc 命令。上面的示例仅显示了诸如“CCLD libvirt_parthelper”之类的内容。我不确定如何控制这种行为。

您是在运行一个 makefile,还是只是一个 gcc 命令?
这看起来像 KbuildAutotools 输出。试试 make V=1

Z
Zombo

要调用试运行:

make -n

这将显示 make 正在尝试做什么。


找到了 :) make V=1 虽然上面关于“make -n”的建议也很有效。 :) 谢谢大家的回复。
不同之处在于 make -n 不执行命令。因此正确答案是make V=1
make V=1 只有在 Makefile 支持时才有效。 automake 的 makefile 可以做到这一点,但许多其他的却没有。
对于 CMake,请使用 make VERBOSE=1;对于 GNU 自动工具 make V=1
@m-ric 如果您想运行实际运行命令,请考虑 make SHELL='sh -x': stackoverflow.com/a/32010960/895245
P
Peter Mortensen

由自动工具(您必须发出的 ./configure)生成的库 makefile 通常有一个详细的选项,所以基本上,使用 make VERBOSE=1make V=1 应该会给您完整的命令。

但这取决于生成文件的方式。

-d 选项可能会有所帮助,但它会给您提供极长的输出。


注意:CMake 生成的 Makefile 仅支持 VERBOSE=1,不支持 V=1
V=1 为我工作,用 mips-linux-gnu-gcc 编译 nuttx,谢谢。
C
Ciro Santilli Путлер Капут 六四事

构建系统独立方法

make SHELL='sh -x'

是另一种选择。示例 Makefile

a:
    @echo a

输出:

+ echo a
a

这为 make 设置了特殊的 SHELL 变量,并且 -x 告诉 sh 在执行之前打印展开的行。

-n 相比的一个优势是它实际上运行了命令。我发现对于某些项目(例如 Linux 内核),-n 可能会比平时更早停止运行,这可能是由于依赖性问题。

此方法的一个缺点是您必须确保将使用的 shell 是 sh,这是 Make 使用的默认 shell,因为它们是 POSIX,但可以使用 SHELL make 变量进行更改。

执行 sh -v 也会很酷,但 Dash 0.5.7 (Ubuntu 14.04 sh) 会忽略 -c 命令(这似乎是 make 使用它的方式)所以它什么都不做。

make -p 也会让您感兴趣,它会打印设置变量的值。

CMake 生成的 Makefile 始终支持 VERBOSE=1

如:

mkdir build
cd build
cmake ..
make VERBOSE=1

专用问题:Using CMake with GNU Make: How can I see the exact commands?


绝对是最好的答案,它不依赖于原始 Makefile 的编写/生成情况
如果有人可以解释否决票,请告诉我,以便我可以学习和改进信息;-)
make SHELL='$$SHELL -x' 将使 $SHELL 不被评估的文字。使用 make SHELL="$SHELL -x" 将起作用。
这是最好的通用答案,与其他一些答案相反,这不依赖于使用 cmake
make SHELL='sh -x' 超级棒!
F
Flow

从 GNU Make 版本 4.0 开始,--trace 参数是一种很好的方式来告诉 makefile 做什么和为什么做,输出如下行:

makefile:8: target 'foo.o' does not exist

或者

makefile:12: update target 'foo' due to: bar

此参数打印比试运行更详细的信息。了解像 dpdk 这样具有复杂构建过程的 make 系统非常有帮助。
@makerj:也许吧,但它确实执行了命令,这与 make -n 不同。
T
TarmoPikaro

使用make V=1

这里的其他建议:

make VERBOSE=1 - 至少在我的试验中不起作用。

make -n - 只显示逻辑操作,不显示正在执行的命令行。例如 CC source.cpp

make --debug=j - 也可以,但也可能启用多线程构建,从而导致额外的输出。


make VERBOSE=1 用于 CMake。您的试验很可能是基于 GNU 自动工具的项目。
S
Santiago Villafuerte

我喜欢使用:

make --debug=j

https://linux.die.net/man/1/make

--debug[=标志]

打印除正常处理外的调试信息。如果省略 FLAGS,则行为与指定 -d 时相同。 FLAGS 可以是所有调试输出的 a(与使用 -d 相同),b 用于基本调试,v 用于更详细的基本调试,i 用于显示隐式规则,j 用于详细信息命令调用,以及 m 用于在重新制作 makefile 时进行调试。


它不一定显示它执行的命令。您可能只会得到 Reaping winning child xyzJobserver client (fds 3,4)Need a job token; we don't have children 等等。
同意,@einpoklum。
P
Peter Mortensen

根据您的 automake 版本,您还可以使用它:

make AM_DEFAULT_VERBOSITY=1

参考:AM_DEFAULT_VERBOSITY

注意:我添加了这个答案,因为 V=1 不适合我。


仅当您使用 GNU autotools / automake 时才会这样做。
@einpoklum 答案说明了这一点......