77

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

4

7 回答 7

109
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'.
于 2009-11-17T01:02:52.823 回答
26

您在寻找 Make 的“试运行”吗?它会打印出 make 正在做的事情而不实际这样做,让你看到发生了什么。

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

于 2009-11-17T01:03:44.473 回答
8

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

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

于 2010-08-11T16:10:55.070 回答
7

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

# Make 将宣布它何时制作这个目标,以及为什么。
一些目标:preq1 preq2 preq3
    @echo 制作 $@
    @echo 以下先决条件比目标新: $?
    做事
于 2009-11-17T01:11:30.263 回答
7

我通常做的不是像以前的回答者所说的那样使用 -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
于 2014-07-16T09:33:21.993 回答
1

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

于 2013-08-23T10:00:23.713 回答
0

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

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

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

在此示例中:如果将 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 文件)

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

于 2014-07-20T11:55:58.327 回答