手机站
网通分站
电信主站
密 码:
用户名:
当前位置 : 主页>网站运营>建站经验>列表

如何调试make

来源:互联网 作者:west263.com 时间:2008-04-16
西部数码-全国虚拟主机10强!40余项虚拟主机管理功能,全国领先!双线多线虚拟主机南北访问畅通无阻!免费赠送企业邮局,.CN域名,自助建站480元起,免费试用7天,满意再付款! P4主机租用799元/月.月付免压金!
—— 目标名中基本的部分(不包含扩展名或目录)
  • $@ —— 目标的完整名
  • 虽然 Berkeley make 没有使用这些变量,但是他们(到现在)都是可移植的。至少,是部分可移植的;其确切定义在不同的 make 实现中可能会有所不同。使用这些变量编写的任何复杂规则都可能到某个特定的实现就不能用了。

    Shell 脚本

    有时候可能还需要执行一些 make 中没法移植的内容。由于 make 是通过 shell 来运行任何操作的,因此常见的解决方案是编写一个内嵌的 shell 脚本来实现。下面是如何实现的过程。

    首先,要知道 shell 脚本传统上来讲是在多行中编写的,他们能够使用分号来分割语句,从而将整个脚本压缩成一行。其次,要注意这样做可读性不好。解决方案是一种折衷:使用常见的缩进格式来编写脚本,但是在每行后面都加上一个 “;\” 符号。这在语法上使用分号结束了一个 shell 命令,但却会把一个 make 命令的文本部分一次传递给 shell。举例来说,下面的代码就可能会在某个最上层的 makefile 中出现:


    清单 9. shell 脚本中的换行
    all:
    
                for i in $(ALLDIRS) ;             do      ( cd $$i ; $(MAKE) all ) ;             done
    
                

    其中给出了需要注意的 3 件事情。首先是分号和反斜线的用法。其次是 make 变量的用法 $(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”(请参阅 参考资料)就是个很规范的例子。

    文章整理:西部数码--专业提供域名注册虚拟主机服务
    http://www.west263.com
    以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!