读GNU Autoconf, Automake, and Libtool后感

 最近读了GNU Autoconf, Automake, and Libtool这本书,介绍autoconf、automake和libtool这三个工具,通常把它们合称Autotools。但如果只是介绍工具软件这么简单,就没有促使我写些文字的动力了。书中在介绍Autotools的同时,具体而微的讲述了写跨平台软件的常见问题和解决方法。我在读硕士的阶段里主要从事与CORBA相关的工作,整天讨论听到的都是跨平台、平台无关性这类的话。由于我当时的关注点在ORB层之上,研究所谓的容错CORBA,对那些话也没经过认真的思考,就想当然的接受了,直到现在。

            在读这本书的时候,让我第一次切肤的感受到跨平台这个问题的粗糙的表面,使我彻底改变了对这个概念的理解。Tom在 oracle expert one on one这本书里讲开发真正数据库无关的程序的唯一途径就是了解所有数据库,在这儿套用一下就是“做到平台无关的唯一途径就是了解所有平台”。
这本书首先沿Autotools产生发展的历史路线,让人明白Autotools是用来解决什么问题的,以及解决问题的思路。开发服务端程序的人都应该知道,在UNIX和类UNIX的数目繁多的操作系统中,每个shell、每套C API、每版C/C++编译器都在80%相类似的基础上,有数不清的细微不同。在C/C++程序中,一般都是用条件编译的预编译块来把不同的地方区别对待。但是这些条件编译块是整洁好用(clean code works)的程序代码的杀手,使代码的可读性极大的降低。而且在较大的程序里,程序员不可能靠人力有效维护大量预编译变量和其中包含的程序,这项工作本不是我们人类大脑所擅长的。

            面对一个个具体的平台差异,书中都有一般性的机械的解决方法。基本上分为两大类:一个是关于写一个可移植makefile的问题,另一个是处理操作系统或者库函数提供的C API之间差异的代码可移植问题。前者属于project组织方面,比如有没有某个头文件、有没有某个库文件、有没有某个可执行程序。通常编写用于探测的shell脚本来判断,而shell脚本也有一个可移植的问题,尽量要使用最通用的shell环境和命令(像sh)。 后者除了上述以外还要涉及到程序本身,需要程序员用可移植的方式来写程序,并用条件编译块把它们包含起来。比如有没有某个函数定义,有没有某个函数实现, 支持不支持某种用法。如果没有的话要寻找变通方式,用其他函数代替,或者自己实现一个。通常探测脚本都要试图编译或者链接一段测试代码。探测的结果保存为 环境变量或者文件变量,最终作为makefile中的变量为整个project设定一个编译链接环境。当project的设定和它的程序代码都能预见到在某个平台上编译、链接、运行环境的变化,并做出相应的处理,这样的project才是在这个平台上可移植的。

               作者对于每个单独的问题和解决方法的阐述都言简意赅,让人在不疲惫的情况下接受所讲的内容,显示了作者对这些问题的了解非常充分。每一章,一小节所讲述的目标交代的都很清楚,对问题产生的原因,常用的解决方法,示例讲解,以及作者的个人经验都照顾到了。

               Autotools只是GNU工具集中的一个典型例子,看这些工具发展并成熟的过程,也就是从一个特定的角度看开源项目,或者叫GNU项目。这类项目建立、管理、发布、升级已经形成了它们的典型方式,并似乎已经成为了某种传统。对于大学、研究型机构或者网络上一群开发者,他们通常都不能用较大段的时间,聚在一起进行开发工作,这只有在组织较严密的公司里才行。并且他们中80%的成员是不停流动的,这个月交付了一批代码的人,下个月可能就不在了。在这种特别开发环境中演进的GNU项目,一般都会以源代码为项目核心,强调代码本身的可读性,再加上少量简明的文档(NEWS、AUTHORS、README、CHANGELOG等 等)。有志于进入一个项目的人都会长时间阅读代码,来了解软件的当前情况。项目中几个固定成员决定着项目的走向和质量,项目控制者通过邮件列表、或者讨论 区来让项目成员或者有兴趣的人统一对项目的认识,解答疑问。并对项目的分工和提交的每一部分代码和文档负责。所以有时候看上去开源项目进展并不快,但是成 功的项目总是能保持稳定的速度,持续的发展。改进和发布与公司不同,受市场因素影响较小,不会迎合宣传和提前发布,可以说它本身就具有频繁发布的特点,并 且假定使用者也能接受这一点。这种方式尤其值得定位在服务端软件研究的单位借鉴。

               从作者介绍的每个示例程序也可以看出作者多年从事程序开发工作的经验,虽然demo都很小,但是作者从构思、到编写代码的一步步的过程都能对志于开发程序的人一些启示。作者的例子通常从书写error.h文件开始,推敲并记录下错误处理的方式,定义错误码和出错处理例程等;然后书写common.h,考虑可能涉及到的可移植性和兼容性问题,定义为处理这些问题而设定的预编译变量,在使用autotools后,其中部分内容更适合写在config.h里; 接下来的工作是从最重要的问题入手,用函数接口的方式来描述解决问题的定义,再逐步实现它。真正的工作不是一次这样的过程就可以完成的,虽然解剖完成的东 西都似乎很简单,但是建构比解构需要更多的努力和耐心。反复的迭代上述的过程中,每一次都是一次丰富和完善,更是一次纠正和重新认识。我相信那句话:下一 次永远比这一次做得好,但你并不见得有再来一次的机会。所以尽可能的给自己创造再来一次的机会,这就像下围棋里的复盘一样。

              说了这么多,都和书中讲的Autotools没有什么关系。下面进入正题:想了解Autotools具体内容的人,看书就好了,我无论说什么都是画蛇添足。

你可能感兴趣的:(读GNU Autoconf, Automake, and Libtool后感)