makefile 的调试有点像魔法。可惜,并不存在makefile 调试器之类的东西可用来查看特定规则是如何被求值的,或某个变量是如何被扩展的。相反,大部分的调试过程只是在执行输出的动作以及查看makefile。事实上,GNU make 提供了若干可以协助调试的内置函数以及命令行选项。用来调试makefile 的一个最好方法就是加入调试挂钩以及使用具保护的编程技术,让你能够在事情出错时恢复原状。我将会介绍若干基本的调试技术以及我所发现的最有用的具保护能力的编码习惯。1.make 的调试功能warning函数非常适合用来调试难以捉摸的makefile。因为warning函数会被扩展成空字符串,所以它可以放在makefile 中的任何地方:开始的位置、工作目标或必要条件列表中以及命令脚本中。这让你能够在最方便查看变量的地方输出变量的值。例如:$(warning A top-level warning)FOO := $(warning Right-hand side of a simple variable)barBAZ = $(warning Right-hand side of a recursive variable)boo$(warning A target)target: $(warning In a prerequisite list)makefile$(BAZ)$(warning In a command script)ls$(BAZ):这会产生如下的输出:$ makemakefile:1: A top-level warningmakefile:2: Right-hand side of a simple variablemakefile:5: A targetmakefile:5: In a prerequisite listmakefile:5: Right-hand side of a recursive variablemakefile:8: Right-hand side of a recursive variablemakefile:6: In a command scriptlsmakefile请注意,warning函数的求值方式是按照make标准的立即和延后求值算法。虽然对BAZ的赋值动作中包含了一个warning函数,但是直到BAZ在必要条件列表中被求值后,这个信息才会被输出来。“可以在任何地方安插warning调用”的这个特性,让它能够成为一个基本的调试工具。2.命令行选项我找到了三个最适合用来调试的命令行选项:--just-print(-n)--print-database(-p)--warn-undefined-variables。2.1 --just-print在一个新的makefile 工作目标上,我所做的第一个测试就是以--just-print(-n)选项来调用make。这会使得make读进makefile并且输出它更新工作目标时将会执行的命令,但是不会真的执行它们。GNU make 有一个方便的功能,就是允许你为将被输出的命令标上安静模式修饰符(@)。这个选项被假设可以抑制所有命令的执行动作,然而这只在特定的状况下为真。实际上,你必须小心以对。尽管make不会运行命令脚本,但是在立即的语境之中,它会对shell函数调用进行求值动作。例如:REQUIRED_DIRS = ..._MKDIRS := $(shell for d in $(REQUIRED_DIRS); \ do \ [[ -d $$d ]] || mkdir -p $$d; \ done)$(objects) : $(sources)正如我们之前所见,_MKDIRS 简单变量的目的是触发必要目录的创建动作。如果这个makefile 是以--just-print 选项的方式运行的,那么当make 读进makefile 时,shell命令将会一如往常般被执行。然后,make 将会输出(但不会执行)更新$(objects)文件列表所需要进行的每个编译命令。2.2 --print-data-base--print-data-base(-p)是另一个你常会用到的选项。它会运行makefile,显示GNU版权信息以及make 所运行的命令,然后输出它的内部数据库。数据库里的数据将会依种类划分成以下几个组:variables、directories、implicit rules、pattern-specific variables、files(explicit rules)以及vpath earch path。如下所示:# GNU Make 3.80# Copyright (C) 2002 Free Software Foundation, Inc.# This is free software; see the source for copying conditions.# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A# PARTICULAR PURPOSE.正常的命令将会在此处执行# Make data base, printed on Thu Apr 29 20:58:13 2004# Variables...# Directories...# Implicit Rules...# Pattern-specific variable values...# Files...# VPATH Search Paths让我们更详细地查看以上这几个区段。变量区段(variable)将会列出每个变量以及具描述性的注释:# automatic