2009-11-17 101 views
61

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

+0

是不是有像详细模式?难道你不能在每个目标上进行一些'echo'调试来弄清楚吗? – Earlz 2009-11-17 00:58:48

回答

85
make -d 

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

被警告:分析输出需要花费一些时间和精力,但将输出加载到您喜欢的编辑器中,并且执行搜索将有很大帮助。

可以大大减少调试输出量,如果你指定你感兴趣的特定目标。因此,如果你只在dodgy目标感兴趣,而不是仅仅make -d这可能使一百个不同的东西,尝试:

make clean 
make -d dodgy 

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

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

make --debug=FLAGS 

其中标志可以是:

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

看起来make --debug=b是你需要什么是最好的选择,因为显示在下面的成绩单:

[email protected]> cat makefile 
c:a b 
    touch c 

[email protected]> touch a b ; make 
touch c 

[email protected]> make 
make: 'c' is up to date. 

[email protected]> 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'. 
+4

另一个建议是,如果你想摆脱内建的隐式规则,你可以使用'-r'标志和'-d'一起。 – 2009-11-17 15:07:26

17

您是否在寻找制作的“预演”?它会打印出制作过程中没有做的事,让你看到会发生什么。

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

+0

这是我最喜欢的,'-d'太冗长了(甚至是'--debug = b')。特别是如果你坚持递归make(唉!)。 – 2011-07-13 13:34:20

7

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

 
# Make will announce when it is making this target, and why. 
sometarget: preq1 preq2 preq3 
    @echo making [email protected] 
    @echo The following preqs are newer than the target: $? 
    do_things 
+0

我打算建议$?以及 – 2009-11-17 01:22:51

+0

不是一个真正的命令行解决方案,但仍然有用。只有在设置了env-var的情况下,才可以通过仅执行回显来使其成为命令行。 – paxdiablo 2009-11-17 01:34:20

1

几声我也使用this(旧的但仍然有效)交互式调试器作者:John Graham-Cumming

5

我通常所做的并不是像前面的回答者那样使用-d。

我可以:

  1. 使用-p打印的数据库,看规则已经创造了什么。如果您有第二个扩展规则并且正在创建规则,那么这非常方便,特别是递归make。
  2. 大量使用$(info)函数。
  3. 使用此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 
0

我使用GNU使使模板定义按目标制定规则;

模板都是这样写的规则宏,他们在这里https://www.gnu.org/software/make/manual/html_node/Eval-Function.html

当你有化妆系统,包括核心的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 
  • $(叫...)调用模板
  • $(信息...)打印模板替换的结果; (EVAL会调用输出和另外的分析当前的make文件)

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