Chinaunix首页 | 论坛 | 博客
  • 博客访问: 462290
  • 博文数量: 185
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 681
  • 用 户 组: 普通用户
  • 注册时间: 2011-08-06 21:45
个人简介

为梦而战

文章分类

全部博文(185)

文章存档

2016年(3)

2015年(103)

2014年(79)

我的朋友

分类: LINUX

2014-05-30 23:26:37

3.2.4  可移植的源代码(GNU自动化工具)

为Linux编写的软件不仅应该在运行于相同硬件平台上的发行版之间尽可能实现二进制兼容,还应该可以在大多数已提供正确的函数库和其他必备条件的系统中成功编译。编译过程必须小心地确定不同软件环境之间的差异。这既适用于不同Linux发行版之间的情况,也适用于Linux和其他商业UNIX环境之间的情况。

为辅助实现不同编译环境之间的源代码级的可移植性,人们创建了GNU的自动化工具(Autotools)。Autoconf、Autoheader、Libtool、Automake和许多其他的脚本和工具一起工作并共同构成GNU的编译系统。每个工具会自动运行一系列的测试以获得对用户所处硬件和软件环境的理解,然后再确定是否有可能在这一特定的软件环境中编译应用程序。

当准备好合适的源代码集之后,就可以使用你可能早已熟悉的“configure,make,make install”序列来编译软件了。下一节只是对GNU自动化工具的介绍。更多信息请查看自动化工具的相关图书,你可以在上免费获得它。

1. GNU自动化工具

也许通过一个实例的讲解你会更容易理解GNU自动化工具是如何工作的。在本例中,我们使用一个简单的程序hello.c来显示一个消息。它已被修改为使用一个库(libhello)函数print_message来执行实际的消息打印操作。此外,这个程序还试图确定编译它的机器使用的是大头字节序还是小头字节序,如果机器是大头字节序,则打印一个可选的欢迎消息(字节序将稍后在本章进行介绍——请继续阅读以发现更多有关乔纳森?斯威夫特如何影响计算机科学的内容)。

下面是hello.c示例程序的源代码:


  
这个程序使用了一个名为libhello的函数库,它只包含一个消息打印函数:
    


建立自动化工具项目

编译这个示例程序和函数库需要若干步骤。其中每个步骤都依赖于GNU自动化工具中的一个不同部分,我们将在后续小节中对它们一一进行解释。当你在上一章中学习如何使用GNU工具链来为自己编译代码和函数库时,你已看到过类似的示例代码。现在,你将学习如何依靠强大的GNU编译工具来为你执行这些操作——如果你愿意的话。请记住GNU自动化工具本身是非常复杂的,但我们并没有在这里涵盖它们的所有复杂性。如果你想了解更多的细节,请查看GNU自动化工具的文档或参考GNU自动化工具图书的在线拷贝。
你需要在示例目录portability中准备一个宏文件aclocal.m4,该文件将根据你的configure.in文件中的内容包含许多用于automake的定义。所幸的是,你可以运行aclocal工具来帮助你完成这一工作:

  

使用autoconf处理configure.in文件并生成一个configure脚本:
 
使用autoheader以准备好config.h.in文件,当此后我们在目标系统中运行configure脚本时,它将用于生成有用的头文件config.h:
 
为libtool准备好函数库,它们将被libtool自动编译:
 
最后,使用automake生成Makefile.in文件,使得其后对configure工具脚本的调用能够为这个项目生成Makefile文件。
 

这些阶段现在看来都非常复杂和难以处理,但没有关系,我们很快就会对其中的每一个阶段进行解释。当阅读完本章后,你可能会有更多有关GNU自动化工具的疑问没有办法在本章中找到答案,但至少你已知道存在这些工具,并且当你建立自己的项目时,知道到哪里去查找进一步的资料,这已成功了一半。

你可以通过调用新创建的configure脚本来启动一个配置周期:

 
 
 
 
 
请注意configure是如何报告它所执行的每个测试的状态的。你可以看到很多类似于checking for stdio.h usability(检查stdio.h可用性)的输出,它们表明configure正在为你执行许多测试。运行完configure之后,你会看到在项目源代码目录的include子目录中创建了一个config.h文件,其内容如下所示:
 
 
每个#define声明对应于配置过程中的一次成功测试。hello.c源代码可以使用这些定义,而且它确实在判断是否应打印一个额外的欢迎消息时这样做了。头文件hello.h也使用这些定义来准确地判断应包含哪些头文件:
 

你可能会觉得这种做法过于迂腐,但当你需要调整自己的源代码以尽可能地适应当地编译环境时,你将使用输出的config.h文件作为一种处理方式。例如,当将源代码移植到其他类UNIX系统中时,你可能会发现缺少一些内存分配函数或它们并没有按照你所期望的方式工作。在这种情况下,你就可以使用configure脚本来判断哪些标准函数库功能丢失了,并在必要的时候提供自己的替代实现。请查看GNU Autoconf文档以获得它所支持的测试和功能的完整列表。


一旦配置好软件,你就可以使用GNU make以正常的方式来编译它了:

 
对make install的快速调用(具备适当的root权限)将把二进制程序hello及其必需的函数库安装为/usr/local/bin/hello(默认位置,如果你不想将它安装到你的开发用机器的主文件系统中,可以通过configure.in或configure脚本的--prefix参数进行定制,例如,你可以选择$HOME/bin):
 
 
此时,你可以尝试运行这个程序:
  

系统找不到刚刚安装的libhello.so.0,为什么?因为动态连接器需要刷新它的缓存,在该缓存中有已知的函数库信息。连接器知道列在文件/etc/ld.so.conf中的目录并将在重建其缓存时包括某些标准目录(如本例中使用的目录/usr/local/lib)。你可以通过运行ldconfig来达到重建缓存的目的:
 
这样做之后,hello程序就可以正常运行了:
 

祝贺你完成了你的第一个GNU自动化工具项目。现在你已沿着这条道路开始学习了,在阅读完后面小节中的解释性资料之后,你就可以开始自己进行试验了。请使用GNU自动化工具所提供的文档来指导你的试验。


如果你建立的项目之后将成为GNU的一部分(即成为自由软件基金会的官方项目),你还需要确保示例项目中包含几个重要文件。每个GNU项目必须包含一个AUTHORS文件——它包含每一个参与这个项目的作者的信息、一个NEWS文件——跟踪项目的新闻、一个README文件——提供项目的基本信息、一个ChangeLog文件——跟踪每个项目代码版本的发布。

阅读(1513) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~