目录
1 介绍
2 历史
3 如何运行configure和make
4 Makefile介绍
5 一个最小的GNU Autotools项目
6 写configure.in
7 GNU Automake介绍
8 启动
9 一个小型GNU Autotools项目
10 GNU Libtool介绍
11 使用GNU Libtooll和configure.in,Makefile.am
12 一个大型的GNU Autotools项目
13 分发软件包
14 安装和卸载被配置的包
15 编写和GNU Autotools可移植的C
16 编写和GNU Autotools可移植的C++
17 动态加载
18 使用GNU libltdl
19 高级GNU Automake用法
20 一个复杂的GNU Autotools项目
21 M4
22 编写可移植的Bourne Shell
23 编写Autoconf的新宏
24 移植现有的库到GNU Autotools
25 在Cygnus Cygwin中使用Autotools
26 和GNU Autotools交叉编译
A 安装GNU Autotools
B 平台
C 生成文件依赖关系
D Autoconf宏参考
E OPL
索引
这是linuxsee第一次转载别人的文章,只因今天在网上找autobook的中文版,竟找不到,且发现很多人和我遇到同样的问题。于是决定将此 书翻译,以满足广大linux 初学者学习automake的愿望。已有人将前几章译过,在此发扬不重复劳动精神借用之,不久就会将autobook完整翻译。因本人水平有限,难免有出 错之处,还望各位不吝赐教,若有能力者强烈建议读原文,在此下载。
——-本篇为转载内容,原作者文章请看这里 ——–
Autoconf、Automake 和 Libtool 这三个软件包可以让你的软件具有更好的可移植性并简化其构建的过程──尤其是在其他人的系统上。软件的可移植性和高效的构建系统是现代软件工程实践中非常 重要的方面。现在,人们通常都希望软件能在不止一个平台上运行,因为硬件的限制有可能会改变对平台的选择,新的客户可能在使用不同的系统,而你所使用的操 作系统提供商也可能在新版本中引入与之前不兼容的变化。此外,能够让软件构建过程更简单且不容易出错的工作也是非常有价值的。
Autoconf 这个工具可以在编译软件包前执行一系列测试,发现系统的特性,而你的源码可以去适应不同系统的差别。通过这种方式,可以让你的软件包具有更好的可移植性。
Automake 是产生’Makefile’──描述要构建什么──的工具,它遵从了很多的标准。Automake 极大地简化了描述软件包结构及追踪源码间依赖关系的过程。
Libtool 是编译器和连接器的命令行接口,利用它可以方便地产生具有可移植性的静态库和动态链接库。
本书是关于 Autoconf、Automake 和 Libtool 的教程,以下将它们简称为 GNU Autotools。GNU手册分别对这三种工具进行详细的阐述,但迄今为止,还没有哪本指南描述过它们如何共同工作的。
近年来,这些工具得到了发展,对相关问题很了解的贡献者们做出了相应的设计,但是描述原理的文件却几乎没有。在阅读例子时,可能有人会问为什么 Autoconf 的宏使用以下的 shell 结构:
if test "x$var" = xbar; then echo yes 1>&5 fi |
而不是更简单的
if [ $var = bar ]; then echo yes 1>&5 fi |
诸如此类问题的答案都记录在了本书中。
本书不是一本 Autoconf、Automake 或 Libtool 的权威参考,否则书中将充斥过时的信息。譬如本书并不对由 Autoconf 提供的每一个预先定义的宏进行描述。相反,本书将帮助你理解你所遇到的任何宏,并影响你处理软件可移植性和软件包创建的方式。以上工具的GNU手册可以作 为参考书。
本书对相关概念只作简单介绍而不是详细地解释它们。本书会介绍如何编写’Makefile’和 Bourne shell 脚本,但是你必须参考其他工具书以便熟悉这些主题。
软件开发者,系统管理员和技术管理员很可能对关于 GNU Autotools 的书感兴趣。
软件开发者,特别是自由项目的开发者会认为了解如何使用这些工具是十分有价值的,因为 GNU Autotools 在自由软件社区中正变得越来越流行。室内项目的开发者如用这些工具也会受益非浅。
系统管理者能从这些工具的使用知识中受益。因为系统管理员的通常任务就是编译和安装使用 GNU Autotools 框架的软件包。偶尔,特性测试也会产生错误的结果而导致编译错误或程序异常。通常稍微 hacking 一下就可以编译软件包了,但是知道解决问题的正确方法能够帮助软件包的维护者。
最后,书中的讨论将使技术管理员对软件可移植性的复杂本质和创建大型项目的过程有进一步的了解。
与任何一本好的教程一样,本书首先解释简单的概念,然后在这些基础知识上再进一步延伸至高层次的主题。
本书的第一部分将阐述这些工具的发展及其存在的原因。
第二部分则是本书的主要内容。首先解释’Makefile’和 configuration triplets 之类的概念。此后的章节将逐一介绍各个工具及如何使用它们来处理不同规模的项目。如果用 C和 C++ 语言编写的程序十分粗糙的话,该程序将不可移植。第 14 和 15 章将分别指导如何用 C 和 C++ 语言编写可移植程序。
第三部分提供的信息是你在其他任何参考书中都没法找到的。因为该部分是根据大量应用这些工具的实际经验编写而成的。其中有章节是关于一些高级但又十 分重要的概念,如m4宏处理器及如何写可移植 Bourne shell 的脚本。第 23 章将概述如何把一个现存的软件包移植到 GNU Autotools 框架。许多开发者会对该章内容十分感兴趣,因为在交叉编译环境中使用 GNU Autotools 创建软件包是最令人困惑的。第 25 章将就此作出解释。
本章我们就书中工具的发展历史进行简要阐述。你不必为了使用这些工具而去了解历史,但是了解这些工具的发展过程将有助于了解为何它们以目前的方式运作。此外,在这样一本书中,我们有必要感谢原创作者及其灵感来源,并对他们所做的贡献作一番解释。
在数种所讨论的程序中,最早开发出来的是 Autoconf。它的发展是由 Unix 操作系统的历史决定的。
贝尔实验室的 Dennis Ritchie 和 Ken Thompson 于 1969 编写了最早版本的 Unix。在上世纪七十年代,尽管贝尔实验室并不被允许商业化地出售 Unix,但是它确实以较低的价格将 Unix 卖给了一些大学。加州大学伯克利分校在原 Unix 的源码上做了改进,并形成了 BSD 版的 Unix。
上世纪八十年代早期,AT&T 签定允许他们商业化地出售 Unix 的协议,Unix 的第一个 AT&T 版本是 System III。
八十年代随着 Unix 越来越流行,其他一些公司对原有的 Unix 进行修改而形成了他们自己的版本。例如,Sun Microsystems 的 SunOS、Digital Equipment Corporation 的 Ultrix 以及 Hewlett Packard 的 HP-UX。
尽管 Unix 的各个版本在本质上是相似的,各版本之间还是有区别的。它们的头文件集和系统库所提供的函数还是有些细微的差别,而在中断处理和作业控制等方面存在的差别则更大。
然而 POSIX 的出现则消除了其中的一些差别。但是 POSIX 在一些领域中又引入了新的特性,从而导致了更多的版本。同样,不同系统采用不同时期的 POSIX 标准,也导致了更多的差异。
所有这些差异给作为源代码散布的程序带来了问题。即便是像 memcpy 这样简单的函数也不是任何系统都提供的;BSD 系统库提供与之类似的功能 bcopy,但是参数的次序是相反的。
要想使程序在不同版本的 Unix 都能运行,程序的作者若就必须熟悉各版本之间的具体差别。他们还需要注意这些差别在各版本中是如何体现的,因为它们虽然都遵循 POSIX 标准,但是各自又引入了新的各不相同的特性。
虽然通常情况下可以用 #ifdef 来确认特定的系统和版本,但是人们越来越难以知道哪个版本具有哪些特性。因此,人们需要更系统的方法来处理不同版本间的差异。
到 1992 为止,人们已经开发了四个系统来帮助实现源代码的移植:
以上系统都将构建程序分成两步:配置和构建。并且在进行构建时都使用了标准的 Unix make 程序。Make 程序从’Makefile’中读取一系列规则,并用这些规则创建程序。配置步骤所做的工作是产生’Makefile’文件,也可能还产生其它可能在构建过 程中使用到的文件。
Metaconfig 和 Autoconf 都用特性测试来测试系统的兼容性。它们用 Bourne shell 脚本(所有 Unix 版本都以不同形式支持 Bourne shell 脚本)运行不同的测试以确定系统支持的内容。
Cygnus 的’configure’脚本和原先的 GCC’configure’脚本也是 Bourne shell 脚本。它们靠小的配置文件得到每个系统的变量,包括头文件和’Makefilse’片段。在早期版本中,编译程序的使用者必须告诉脚本该程序是为哪种系统 构造的;后来 Per Bothner 对其进行了改进,他编写的 shell 脚本能根据标准 Unix uname 程序和其它信息确定系统类型。
Imake 是可移植的 C 程序。它可以被定制以用于特定的系统,并作为软件包构建的一部分来运行。但更常见的情况是,Imake 和软件包一起发行,其中的软件包包含了被支持的系统所需的所有配置信息。
Metaconfig 和 Autoconf 是程序作者使用的程序。它们产生的 shell 脚本将与程序的源代码一起散布。而想要构建程序的用户在程序要运行的系统上执行这个 shell 脚本,从而为源代码产生相应系统的配置。
Cygnus 和 GCC’configure’脚本, 还有 imake, 对于用户和开发人员使用来说没有分别。
Cygnus 和 GCC’configure’脚本支持跨平台开发,两者都支持内建一个可以在不同的平台上编译的跨平台的编译器,用来编译程序。
Autoconf, Metaconfig 和 Imake 没有这些功能 (他们最后加入了 Autoconf);它们只支持在它们各自工作的平台上编译程序。
TMetaconfig 生成的脚本是默认交互的: 它们在执行时向用户询问。这样可以使它们知道难于测试出的平台的特征,来确定平台下的执行方式。
Cygnus 和 GCC’configure’脚本,及autoconf生成的脚本, imake 程序不是交互式的: 它们自己决定任何事。 使用 Autoconf 时,包开发者一般会写命令行的参数选项来决定它们不能检测出的功能,有时会要求用户在执行 ‘configure’ 脚本后写一个头文件。
Cygnus 的’configure’脚本和原先的 GCC’configure’脚本必须更新以适应它们支持的 Unix 新版本。也就是说,随着 Unix 新版本的不时出现,使用它们的软件包就时常处于过时状态。尽管对开发者而言,增加新系统版本的支持并不困难,但是软件包用户却不能轻易完成这项任务。
Imake 在通常的使用过程中也存在着同样的问题。尽管用户可以为特定系统创建并配置 Imake,但是这种做法并不常用。事实上,像 X window 系统这样使用 Imake 的软件包是与针对特定 Unix 版本的详细配置信息一起发布的。
由于 Metaconfig 和 Autoconf 都使用特性测试,它们产生的脚本通常不用修改就能在新的 Unix 版本上运行。因此,它们更容易使用并且适应性更强,而 Autoconf 也被广泛的应用。
1994年,David MacKenzie 将 Cygnus 的’configure’脚本和原先的 GCC’configure’脚本的特性融合到 Autoconf 中,其中包括使用针对特定系统的头文件和 makefile 片段,还包括对交叉编译的支持。
GCC 至此也改用 Autoconf 来替代 GCC’configure’脚本。使用 Cygnus’configure’脚本的程序也大多用 Autoconf 进行了改写,人们也不再用 Cygnus 的’configure’脚本编写新的程序了。
metaconfig 程序至今仍被用于配置 Perl 和其他很少的程序。imake 仍被用于配置 X window 系统。但是,这些工具一般不再用于新的软件包。
到 1994 年,Autoconf 已经是处理不同 Unix 版本之间差异的固定框架。但是程序开发者仍不得不编写庞大的’Makefile.in’文件才能使用 Autoconf。由 Autoconf 产生的’configure’脚本将’Makefile.in’文件转化为 make 程序使用的’Makefile’。
‘Makefile.in’文件必须对如何创建程序进行描述。而在 Imake 中具有’Makefile.in’功能的’Imakefile’却只需描述创建程序时使用了哪些源文件。当 Imake 产生一个’Makefile’时,它会自动增加关于如何创建程序的规则。BSD make 程序后来的版本也包含了构建程序的规则。
由于大多程序的创建方式是相同的,’Makefile.in’文件中也存在大量的重复。同时,GNU 项目开发了一个相当复杂的’Makefile’标准集,它很容易产生细节错误。
上述因素都促成了 Automake 的开发。automake 像 autoconf一样是由开发者运行的程序。开发者编写名为’Makefile.am’的文件;这些文件使用比普通的’Makefile.in’更简单的 语法。Automake 读取’Makefile.am’文件并产生’Makefile.in’文件。这样,由 autoconf 产生的脚本将这些’Makefile.in’文件转化为’Makefile’。
如同 Imake 和 BSD make 一样,’Makefile.am’文件只需描述用于构建程序的文件。Automake 在产生’Makefile.in’文件时会自动增加所需规则。automake 还会增加 GNU’Makefile’要求的任何规则。
1994 年,David MacKenzie 编写了 Automake 的第一个版本。1995年,Tom Tromey 对此进行了彻底的改写。
随着时间的发展,Unix 系统增加了对共享库的支持。
传统的库,即静态库,是与程序的映象链接在一起的。也就是说,使用静态库每个程序中都包含了磁盘上部分或全部的库。
共享库是独立的文件。使用共享库的程序并不包含库,它仅仅包含库的名字。许多程序能使用同一个共享库。
使用共享库降低了对磁盘空间的需求。由于通常情况下系统能在许多程序中共享同一个共享库的可执行实例,使用共享库也降低了运行时对交换空间的需求。另外,通过更新磁盘上的一个共享库文件就能改正错误,而不必重建使用库的所有程序。
第一个 Unix 的共享库应用是在 AT&T 发行的 System V 第三版。这一想法很快被其他的 Unix 销售商采纳。如 SunOS, HP-UX, AIX, 和 Digital Unix。不幸的是,各个共享库在创建、使用以及它所支持的具体特征方面都是不同的。
很自然地,包含库并作为源代码散布的软件包想创建它们自己的共享库。几个不同的共享库实现被写在 Autoconf/Automake 框架上。
1996 年, Gordon Matzigkeit 开始创建软件包 Libtool。Libtool 是 shell 脚本集合。这些 shell 脚本集合是用于处理不同版本的共享库在不同系统中使用时的差异。Libtool 与 Automake 紧密相连,而且不能独立使用。
随着时间的推移,Libtool 已经能够支持更多的 Unix 版本,并能提供使共享库特性标准化的接口。
1995 年,Microsoft 发行了 Windows 95。Windows 95 很快成为全世界广泛应用的操作系统。Autoconf 和 Libtool 在编写时是为了支持不同 Unix 版本之间的移植,但是它们提供的框架结构也能支持移植到 Windows。这样使得程序可以支持来自同一源代码库的 Unix 和 Windows。
Autoconf 和 Libtool 中都必须需要使用 Unix shell。在由 Steve Chamberlain 编写的 Cygwin 项目中,GNU bash shell 被移植到了 Windows 上。Cygwin 项目在 Windows 上实现了基本的 Unix API,这就使直接移植 Unix 程序成为可能。
当 shell 和 Unix make 程序(也是由 Cygwin 提供的)可以使用后,Autoconf 和 Libtool 就可以通过使用 Cygwin 接口或 Microsoft 的 Visual C++ 直接支持 Windows 了。这需要处理像不同系统使用不同文件扩展名以及共享库的另一特性集之类的细节。Ian Lance Taylor 于 1998 年第一次完成了这个任务。Automake 也被移植到 Windows上,它需要使用 Perl(see section Prerequisite tools)。