调试GNU make


75

是否有命令行方法make可以找出未更新目标的哪些先决条件?


那里不是像冗长的模式吗?您不能只是echo在每个目标上都进行一些调试来弄清楚这一点吗?
Earlz

Answers:


106
make -d

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

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

如果您指定感兴趣的特定目标,则可以大大减少调试输出的数量。因此,如果您仅对dodgy目标感兴趣,而不是仅仅感兴趣的目标,那么make -d可以尝试:

make clean
make -d dodgy

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

make --debug是相同的make -d,但你也可以指定:

make --debug=FLAGS

标志可以是:

  • a用于所有调试(与make -d和相同make --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'.

7
另一个建议是,如果您想摆脱内置的隐式规则,可以在mere-r旁边使用flag -d
P Shved

24

您是否在寻找Make的“试运行”?它会打印出make在做什么,而无需实际执行,从而使您看到发生了什么。

标志是-n,像使用它make -n


这是我的最爱,-d太冗长了(甚至--debug=b)。尤其是如果您对递归make感到困惑(嗯!)。
亚当·林德伯格


7

您的问题还不清楚。如果要查看哪些先决条件文件最近未修改,请使用ls -l查看其修改时间。如果要查看make在做什么,请尝试以下操作:

#Make将宣布何时达到此目标以及原因。
sometarget:preq1 preq2 preq3
    @echo赚$ @
    @echo以下条件比目标要新:$?
    做事

我打算建议$?以及
某人

并不是真正的命令行解决方案,但仍然很有用。仅在设置了env-var的情况下,才可以通过执行回显将其设置为基于命令行。
paxdiablo

7

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

我要么:

  1. 使用-p打印数据库,以查看已创建了哪些规则。如果您有第二个扩展规则并且正在动态创建规则(特别是递归生成),这将很方便。
  2. 大量使用$(info)函数。
  3. 使用此DrDobbs文章调试Makefile中描述的提示和技巧。

以下是我用于打印值的一些代码:

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

1

几次,我也使用过约翰·格雷厄姆·卡明(John Graham-Cumming)的这种(古老但仍在运行的)交互式make调试器


0

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

模板就像编写规则的宏一样,在此进行解释 https://www.gnu.org/software/make/manual/html_node/Eval-Function.html

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

在此示例中:如果在make命令行中添加SHOW_RULES = 1,则它还会显示由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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.