Linux中国 Linux中国门户站!
设为主页 设为主页
收藏本站 收藏本站
 
当前位置 :首页 ->Linux技术 ->Linux程序设计 ->正文

怎么样调试make

来源:IBM DW中国 作者:Peter Seebach  时间:2007-04-22 点击: [收藏] [投稿]
$(VARIABLE)。再次是使用 $$ 向 shell 传递一个 $ 符号。就是这样,这实际上都非常简单。

前缀

默认情况下,make 会打印出它所运行的每个命令,如果有任何命令失败,make 就会停止执行。在某些情况中,可能会出现某个命令看起来失败了,但是我们却希望整个编译过程继续进行。如果一个命令的第一个字符是连字符(-),那么该行中剩余的命令都会执行,不过其退出状态会被忽略。

如果并不希望回显命令,可以在前面加上 @ 符号作为前缀。这是显示消息最常用的方法:


清单 10. 禁止回显
all:
	@echo "Beginning build at:"
	@date
	@echo "--------"

如果没有 @ 符号,这就会产生下面的输出:


清单 11. 没有 @ 的命令
echo "Beginning build at:"
Beginning build at:
date
Sun Jun 18 01:13:21 CDT 2006
echo "--------"
--------

尽管 @ 符号不会真正改变 make 所做的事情,但是这却是一种非常受欢迎的特性。

不可移植的功能

有些人们非常希望实现的事情却不可移植。但是这些问题也有一些解决办法。

包含文件

历史上最难解决的一个兼容性问题是在 makefile 中对包含的处理。早先的 make 实现通常都没有提供方法来实现这种功能,但是现代的一些 make 变种似乎看起来都对这个问题进行了妥善处理。GNU make 语法非常简单,即 include file。传统的 Berkeley 语法是 .include "file"。至少有一种 Berkeley make 现在也可以支持 GNU 的符号了,但是目前还尚未全部支持。 autoconfImake 所提供的可移植解决方案只是将所希望使用的每个变量的赋值都包含进来。

有些程序可能会简单地要求使用 GNU make,有些则可能要求使用 Berkeley make,还有些可能要求使用 smake。如果需要包含的文件非常多,可以尝试简单指定一个 make 工具,用这个工具编译一个树(在这 3 种以源代码形式发布的可移植 make 工具中,我最喜欢的是 Berkeley make)。

使用变量进行嵌套编译

实际上并没有什么好方法来做这件事情。如果使用了一个包含文件,就可能会遇到此文件是否被干净地包含这样的移植性问题。如果在每个文件中都设置了变量,那么就很难全部重载这些变量。如果只在一个顶层文件中设置这些变量,那么子目录中一些独立的编译就会失败,因为还没有设置变量!

根据所使用的 make 版本的不同,一个理想的解决方案是在每个文件中都有条件地设置变量:只有在还没有设置这些变量时才需要进行设置;然后顶层文件中的变化在完全编译时就会影响到所有的子目录。当然,此时如果单独进入一个子目录并运行 make 会产生不同的并且不兼容的结果。

如果所包含的文件不存在,这样做的负面影响就会被放大,那些曾经在 Imake 数千行 makefile 中挣扎过的人都可以证明这点。

有些人提倡另外一种简单的解决方案:根本就不要递归使用 make。对于大部分项目来说,这是绝对可行的,可以急剧简化(并加速)整个编译过程。 Peter Miller 撰写的文章 “Recursive Make Considered Harmful”(请参阅 参考资料)就是一个非常规范的例子。

当出现问题时应该如何做

首先,不要恐慌。开发人员在编写出一个完整的版本之前,可能需要解决很多怪异的 make 问题。隐式规则、没想到的变量替换以及嵌入式 shell 脚本中的语法错误,都可能会引发这种痛苦的享受。

此时需要仔细阅读错误消息。这是 make 自己产生的消息么?还是 make 所调用的东西产生的消息?如果有一个嵌套的编译,可能会需要通过对一组错误消息来仔细进行分析,才能找到确切的错误。

如果一个程序没有找到,首先要检查它是否已经安装了。如果已经安装了,那么就要检查路径设置是否正确;有些开发人员的习惯是在 makefile 中使用绝对路径,这在其他系统上可能会失败。如果将某些东西安装到 /opt 中,而 makefile 引用的却是 /usr/local/bin,那么编译就会失败。此时就需要修改路径的设置。

检查系统时钟;更重要的是,要检查编译树中文件的日期、系统中其他文件的日期以及系统的时钟。在面临输入数据的时间顺序不一致的情况时,make 的行为可能是无害的,也可能是不现实的。如果碰到了时钟问题(例如有些 “新” 文件被标记成 1970 年的),那么就需要修整这个问题了。 “touch” 工具是一个很好的帮手。在时钟问题中产生的错误消息通常都不太明显。

如果看到的错误消息显示有一些语法错误,或者有很多变量没有设置,或设置得不正确,那么可以尝试试验一下其他版本的 make;举例来说,有些程序在使用 gmake 编译时会产生一些非常含糊的错误,而使用 smake 时就能很好地进行编译。有些非常怪异的错误会说明正在使用 GNU make 来运行一个 Berkeley 的 makefile,反之亦然。Linux 特有的程序通常会假设使用 GNU make,使用其他 make 工具可能会碰到莫名其妙的错误,有些甚至在文档中都没有任何提示。

调试标记可能会非常有用。对于 GNU make ,-d 标记会提供大量的信息,其中有些是非常有用的。对于 Berkeley make ,-d 标记有一组标记;-d A 表示完整的集合,或者可以使用其中的一些子集;举例来说,-d vx 会给出有关变量赋值(v)的调试信息,这会导致通过 sh -x 来运行所有的命令,这样 shell 就会精确地回显自己接收到的命令。-n 调试标记会导致 make 打印它认为需要做的事情的一个列表;这并不总是正确的,不过通常可以为思考哪些地方出现了问题而提供一些思路。

 如果您对本文有任何疑问或者建议,请到讨论区发表您的意见: >> 论坛入口 <<



上一篇:Windows 打印管理在Linux 平台实现   下一篇:C 语言中的指针和内存泄漏

文章评论】 【收藏本文】 【推荐好友】 【打印本文】 【我要投稿】 【论坛讨论
更多相关文章
Power by linux-cn.com 粤ICP备05006655号