调试 GNU make

Posted

技术标签:

【中文标题】调试 GNU make【英文标题】:Debugging GNU make 【发布时间】:2010-12-17 06:51:37 【问题描述】:

make 中是否有命令行方式来找出目标的哪些先决条件没有更新?

【问题讨论】:

不是有详细的模式吗?你不能在每个目标上输入一些echo 调试来解决这个问题吗? 【参考方案1】:
make -d

应该给你更多足够的信息来调试你的makefile。

请注意:分析输出需要一些时间和精力,但将输出加载到您喜欢的编辑器并进行搜索会很有帮助。

如果您指定您感兴趣的特定目标,您可以大大减少调试输出量。因此,如果您只对dodgy 目标感兴趣,而不仅仅是make -d,这可能会产生一百种不同东西,试试:

make clean
make -d dodgy

(当然假设你有一个clean 目标)。

make --debugmake -d 相同,但您也可以指定:

make --debug=FLAGS

标志可以在哪里:

a 用于所有调试(与 make -dmake --debug 相同)。 b 用于基本调试。 v 用于更详细的基本调试。 i 用于隐式规则。 j 获取调用信息。 m 获取 makefile 重制期间的信息。

看起来make --debug=b 是您需要的最佳选择,如以下脚本所示:

pax@paxbox> cat makefile
c:a b
    touch c

pax@paxbox> touch a b ; make
touch c

pax@paxbox> make
make: 'c' is up to date.

pax@paxbox> touch a ; make --debug=b
GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc. Blah, blah, blah.
Reading makefiles...
Updating goal targets....
 Prerequisite 'a' is newer than target 'c'.
Must remake target 'c'.
touch c
Successfully remade target file 'c'.

【讨论】:

另一个建议是,如果你想摆脱内置的隐式规则,你可以使用-r 标志和-d【参考方案2】:

您在寻找 Make 的“试运行”吗?它会打印出 make 在没有实际执行的情况下正在执行的操作,让您看到发生了什么。

标志是-n,像make -n一样使用它。

【讨论】:

这是我的最爱,-d 太冗长了(甚至是--debug=b)。特别是如果你被递归 make 卡住了(呃!)。【参考方案3】:

还有带有调试器和更好的跟踪/错误输出的 GNU make:Remake

演示第 1 部分:https://vimeo.com/232710891 演示第 2 部分:https://vimeo.com/97397484

这两个虽然仍然相关,但有点老了。

【讨论】:

【参考方案4】:

你的问题有点不清楚。如果您想查看哪些必备文件最近没有被修改,请使用 ls -l 查看它们的修改时间。如果你想看看 make 在做什么,试试这个:

# Make 将宣布它何时制作这个目标,以及为什么。 一些目标:preq1 preq2 preq3 @echo 制作 $@ @echo 以下先决条件比目标更新: $? 做事

【讨论】:

我打算建议 $?还有 不是真正的命令行解决方案,但仍然有用。仅当设置了 env-var 时才执行回显,您可能会使其基于命令行。【参考方案5】:

我通常不会像以前的回答者所说的那样使用 -d。

我要么:

    使用 -p 打印数据库,查看创建了哪些规则。如果您有第二个扩展规则并且正在动态创建规则,尤其是递归生成,这将非常方便。 大量使用 $(info) 函数。 使用这篇 DrDobbs 文章 Debugging Makefiles 中描述的提示和技巧

下面是我用来打印值的一些代码:

define pv
$(info $(1) [$(origin $(1))] : >|$($(1))|<)
endef

define pva
$(foreach t,$(1),$(call pv,$(t)))
endef

define itemizer
$(foreach t,$($(1)),$(info $(t)))
endef

【讨论】:

【参考方案6】:

我也有几次使用 John Graham-Cumming 的 this(旧但仍在工作)交互式 make 调试器

【讨论】:

【参考方案7】:

我正在使用 make gnu make 模板来定义每个目标的 make 规则;

模板就像写规则的宏,这里解释https://www.gnu.org/software/make/manual/html_node/Eval-Function.html

当您的 make 系统包含一个核心 makefile 以生成每个项目类型的所有规则时,此功能很有用;如果它说要做一个共享库,那么它会编写规则来编译一个共享库;等其他类型的目标。

在此示例中:如果您将 SHOW_RULES=1 添加到 make 命令行,它还会显示由 PROGRAM_target_setup_template 生成的规则文本;以及自己生成规则(使用 eval)。

 # this one defines the target for real
 $(foreach prog, $(TARGETS), $(eval $(call PROGRAM_target_setup_template,$(prog))))

 ifneq "$(SHOW_RULES)" ""
 $(foreach prog, $(TARGETS), $(info $(call PROGRAM_target_setup_template,$(prog))))
 endif
$(call ... ) 调用模板 $(info ... ) 打印模板替换的结果; (eval 会调用解析输出并添加到当前的 make 文件)

更多关于我的 make 文件在这里:http://mosermichael.github.io/cstuff/all/projects/2011/06/17/make-system.html

【讨论】:

以上是关于调试 GNU make的主要内容,如果未能解决你的问题,请参考以下文章

《GNU_makefile》第五章——为规则书写命令

《GNU_makefile》第五章——为规则书写命令

Qt5.3.2_CentOS6.4_单步调试环境

gnu ld/gdb:单独的调试文件。当需要链接的调试信息过多时如何生成调试文件?

使用GNU/gdb调试Linux C/C++可执行程序查看出错源代码、设置断点

text GDB(GNU调试器)