LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1264|回复: 4

The Goat Book 中文版 (第5章)

[复制链接]
发表于 2003-12-30 20:33:07 | 显示全部楼层 |阅读模式
//*************************************************************

译序

初学linux系统,感觉linux底下的编译,链接程序真的很麻烦。
因此想到了用Autoconf等工具。找到了Autobook这本好书。
也不知道有没有人翻译过这本书。
该书由女友Ellen翻译,在此对她表示感谢。
该书原文请参考 http://sources.redhat.com/autobook/...tobook_toc.html
如果翻译时有什么错误请
Ellengut2002@yahoo.com或者jasongut2002@126.com

转载请保留译序,3x.
//***************************************************************
5. 最小的GNU Autotools工程
   本章节描述如何管理使用GNU Autotools的最小工程。所谓的最小工程是指使用这些工具时可能的最小工程,但是它还能用实例解释足够数量的规则。学习的工程越小,当更大的工程要求先进的特性时就越容易理解这些工具之间复杂的相互作用。
    本章节中作为实例使用的工程是叫做foonly的伪指令解释器。foonly是用C语言编写的。像许多解释器一样,它使用用lex、yacc工具表示的词汇分析器和解析器。该软件包开发过程中将遵循GNU `Makefile'标准——Automake的缺省行为。
    这个小工程并没有利用GNU Autotools的许多其他特性。其中最有用的特性是库。这个软件包不产生它自己的库,因此本章节不具体描述Libtool。在9. A Small GNU Autotools Project 和 12. A Large GNU Autotools Project中描述的更复杂的工程将展示Libtool如何在build 系统中起作用。本章节的目的在于概述用户编写的文件以及它们之间如何相互作用。
5.1 用户提供的输入文件
  最小工程要求用户只要提供两个文件。创建软件包时所需的其他文件将由GNU Autotools产生(参见5.2 Generated Output Files)。
   `Makefile.am'是 automake的输入文件 。
   `configure.in'是 autoconf的输入文件。
    我认为`Makefile.am'是工程创建要求的一个高层次、精练的细化:需要创建什么?它又将被安装到何处? 也许Automake'的最大优势就在于——尽可能简单的描述,但是作为最终产品的 Makefile'则带有一系列便利的make目标。
    `configure.in'是宏调用模板和碎片被autoconf用来产生`configure'脚本的shell代码(参见C. Generated File Dependencies)。autoconf将configure.in'的内容拷贝到`configure'中。这样的话,当宏出现在输入中时就对它们进行扩展。其他的文本将逐字拷贝。
   让我们看一下与这个最小工程有关的用户提供的输入文件内容。下面是Makefile.am':

//++++++++++++++++++++
bin_PROGRAMS = foonly
foonly_SOURCES = main.c foo.c foo.h nly.c scanner.l parser.yfoonly_LDADD = @LEXLIB@
//++++++++++++++++++++++

这个`Makefile.am'规定了我们想要创建名为`foonly的程序,并且当make install '运行时将它安装在`bin'目录中。用于创建的foonly'源文件是C语言源文件`main.c', `foo.c', `nly.c',`scanner.l'的lex程序以及parser.y'的yacc语法。这也指出了Automake的一个优势:因为lex和yacc都从它们的输入文件中产生中间的C语言程序,所以Automake知道如何创建这样的中间文件并将它们链接到最终的可执行文件。最后,如果`configure'认为需要lex库,我们必须记得链接一个合适的lex库。
   下面是`configure.in'文件:

//++++++++++++++++
dnl Process this file with autoconf to produce a configure script.
AC_INIT(main.c)
AM_INIT_AUTOMAKE(foonly, 1.0)
AC_PROG_CC
AM_PROG_LEX
AC_PROG_YACC
AC_OUTPUT(Makefile)
//++++++++++++++++

这个`configure.in'激活了一些必要的Autoconf和Automake初始化宏,然后从AC_PROG系列中调用一些Autoconf宏以便找到合适的C编译器,lex和yacc程序。最后AC_OUTPUT宏被用于产生`configure'脚本来输出一个`Makefile'文件。但是从何处呢?它是通过处理Makefile.in中而产生,而这个Makefile.in是由Automake基于你的`Makefile.am'产生的(参见C. Generated File Dependencies)。
 楼主| 发表于 2003-12-30 20:54:18 | 显示全部楼层

The Goat Book (5.2) 产生的输出文件

5.2产生的输出文件

//2003-12-29译   jason@mail800.com ellengut2002@yahoo.com
//希望你能提出意见

通过学习Generated File Dependencies(产生文件的依赖关系)这部分,就可能明白使用哪个命令从输入文件(见上一章节)产生所需的输出文件。

    首先,我们产生 `configure':
//+++++++++++++++++
$ aclocal
$ autoconf
//++++++++++++

   因为`configure.in'包含了autoconf不认识的初始宏:AM_INIT_AUTOMAKE就是个合适的例子,这时有必要收集所有的宏定义供autoconf 产生`configure'时使用。这一步由aclocal程序来完成。aclocal之所以叫aclocal是因为它产生aclocal.m4'文件(参见C. Generated File Dependencies)。检查`aclocal.m4'的内容,你会发现它包含了AM_INIT_AUTOMAKE宏的定义。

    在运行autoconf之后,你将在当前目录下发现`configure'脚本。因为automake依赖`configure.in'和`aclocal.m4'的内容,所以首先运行aclocal就显得很重要。
//+++++++++++++++++++++
$ automake --add-missing
automake: configure.in: installing ./install-sh
automake: configure.in: installing ./mkinstalldirs
automake: configure.in: installing ./missing
automake: Makefile.am: installing ./INSTALL
automake: Makefile.am: required file ./NEWS not found
automake: Makefile.am: required file ./README not found
automake: Makefile.am: installing ./COPYING
automake: Makefile.am: required file ./AUTHORS not found
automake: Makefile.am: required file ./ChangeLog not found

//+++++++++++++++++++++
    选项`--add-missing'从你的Automake安装处将一些样板文件拷贝到当前目录。例如COPYING'(该文件包含GNU General Public License)这种文件,由于不经常改变,它们的产生就无须用户干涉。一系列有用的脚本也被安装——它们被产生的Makefile's文件,特别是`install目标使用。注意一些所需文件仍然缺少。它们分别是:

    `NEWS'
    记录用户可见的软件变化。它的格式并不严格,但是对最近版本的变化应该出现在文件的开头。

`README'
    用户可最先查看此处来了解软件包用途,以及特殊的安装指示。

AUTHORS'
    列举软件包编写者的名字,通常还包括他们的mail地址。

ChangeLog'
    ChangeLog'是一个重要的文件,因为它记录了对软件包所做的修改。该文件的格式相当严格(参见 5.5 Documentation and ChangeLogs)。

现在,我们将做足够的工作来满足Automake的要求:
//+++++++++++++++
$ touch NEWS README AUTHORS ChangeLog
$ automake --add-missing
++++++++++++++++++++

Automake现在产生了一个`Makefile.in'文件。此时,你可能希望在我们详细讲解自动产生文件前对这个目录有一个总体印象。

现在,目录的内容看起来比较完整,并且使你回忆你过去可能安装过的GNU软件包的上层目录:
//+++++++++
AUTHORS
INSTALL
NEWS
install-sh
mkinstalldirs
COPYING
Makefile.am
README
configure     
missing ChangeLog  
Makefile.in  
aclocal.m4  
configure.in
//+++++++++++++
   现在应该可能把你的目录树打包在一个tar文件中,而其他的用户也可以用它来安装他们自己的系统。Automake在`Makefile.in文件中产生的其中一个make目标使得产生发布包(distrubition)变得容易(参见13. Rolling Distribution Tarballs)。用户只要解压tar文件,运行configure(参见 3. How to run configure and make),最后输入make all:

//+++++++++++++++++
$ ./configure
creating cache ./config.cache
checking for a BSD compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking whether make sets ${MAKE}... yes
checking for working aclocal... found
checking for working autoconf... found
checking for working automake... found
checking for working autoheader... found
checking for working makeinfo... found
checking for gcc... gcc
checking whether the C compiler (gcc  ) works... yes
checking whether the C compiler (gcc  ) is a cross-compiler... no
checking whether we are using GNU C... yes
checking whether gcc accepts -g... yes
checking how to run the C preprocessor... gcc -E
checking for flex... flexchecking for flex... (cached) flex
checking for yywrap in -lfl... yeschecking lex output file root... lex.yychecking whether yytext is a pointer... yes
checking for bison... bison -yupdating cache ./config.cachecreating ./config.status
creating Makefile

$ make all
gcc -DPACKAGE=\"foonly\" -DVERSION=\"1.0\" -DYYTEXT_POINTER=1  -I. -I. \
  -g -O2 -c main.c
gcc -DPACKAGE=\"foonly\" -DVERSION=\"1.0\" -DYYTEXT_POINTER=1  -I. -I. \
-g -O2 -c foo.c
flex   scanner.l && mv lex.yy.c scanner.c
gcc -DPACKAGE=\"foonly\" -DVERSION=\"1.0\" -DYYTEXT_POINTER=1  -I. -I. \
-g -O2 -c scanner.c
bison -y   parser.y && mv y.tab.c parser.c
if test -f y.tab.h; then \
if cmp -s y.tab.h parser.h; then rm -f y.tab.h; \  
else mv y.tab.h parser.h; fi; \
else :; fi
gcc -DPACKAGE=\"foonly\" -DVERSION=\"1.0\" -DYYTEXT_POINTER=1  -I. -I. \
-g -O2 -c parser.c
gcc  -g -O2  -o foonly  main.o foo.o scanner.o parser.o -lfl
//++++++++++++++++++++++++++++
 楼主| 发表于 2003-12-30 20:57:23 | 显示全部楼层

The Goat Book (5.3) 维护输入文件

//2003-12-29译 jason@mail800.com ellengut2002@yahoo.com
//希望你能提出意见。原文出处见最顶
5.3维护输入文件
   如果要在你的软件包中编辑任何一个GNU Autotools的输入文件,为了使这些改变起作用你需要重新产生那些机器产生的文件。例如,如果你向`Makefile.am'的foonly_SOURCES变量中增加一个新的源文件,你就有必要重新产生派生的Makefile.in'文件。如果你正在创建你的软件包,你需要运行configure来重新产生特定目录(site-specific)的`Makefile',然后运行make来编译新的源文件并将它链接到foonly'。
    也能够通过运行所要求的工具来逐个产生这些文件。但是,正如从上文中所述,计算依赖关系是相当困难的——一个具体的变化需要运行alocal或autoconf吗?有两种方案可以解决这个问题?
   第一种方案是使用autoreconf命令。这个工具通过按正确顺序重新运行所有必要工具来产生所有的派生文件。这个方法虽然是生硬强制的,但是它很实用,特别是当你不用试着去适应其他的维护者也不用适应使这一命令变得麻烦的常规维护。
    另一种方案是Automake's 的`maintainer mode'。通过激活`configure.in'文件中AM_MAINTAINER_MODE宏的,automake将激活在`configure'中的`--enable-maintainer-mode'选项。8. Bootstrapping将详细解释这一点。
 楼主| 发表于 2003-12-30 20:59:04 | 显示全部楼层

The Goat Book中文版(5.4) 打包产生的文件

//2003-12-29译 jason@mail800.com ellengut2002@yahoo.com
//希望你能提出意见。原文出处见最顶
   在相关的Internet邮件列表中对于如何处理产生文件的争论是十分激烈的。我将对两种对立的观点都进行阐述以便你为你的项目决定最好的策略。
    一种观点认为:软件包应该只包括源代码的首选形式,而不包括产生文件。基于这种定义,`configure'是派生文件,即相当于一个目标文件,因此它不应该包括在其中。这样,用户应该在创建软件包之前使用GNU Autotools来引导GNU Autotools。我认为这种方法是有些优点的,因为它不鼓励打包派生文件的做法。
    另一种观点则认为:提供这些文件的优势远远大于打破上述的软件工程实践。通过包括产生的文件,用户就不必更新所使用的不同版本的工具。这一点特别适用于Autoconf,因为configure脚本通常是由维护者利用本地修改过的autoconf版本和本地安装的宏产生的。如果`configure'是由使用者产生,那么结果就会与预想的不同。当然,这是很糟糕的做法,但是它恰巧反映了现实。
    我认为答案应该是:当软件包即将被散布到广泛的用户社区(例如:一般大众)时,将产生的文件包含在该软件包中。既然可以对工具进行版本控制,第一种观点可能更适用于in-house软件包。
 楼主| 发表于 2003-12-30 21:03:25 | 显示全部楼层

The Goat Book中文版(5.5) 文档和修改日志

(5.5) 文档和修改日志

//2003-12-29译 jason@mail800.com ellengut2002@yahoo.com
//希望你能提出意见

   对于任何一个软件工程来说,在改进该工程时很重要的一点便是维护文档——该文档必须反映软件的当前状态,但它也必须精确记录过去对工程所做的改动。GNU编码标准强制对文档的维护。事实上,当automake运行时,它通过确认`ChangeLog'文件的存在来执行GNU的某些标准。
一系列标准化命名的文件将文档储存在GNU软件包中。完整的GNU编码标准可以提供相关信息,详情见http://www.gnu.org/prep/standards.html。
其他的工程(包括in-house工程)可以使用这些已由实践检验的技巧。尽管5.2 Generated Output Files已经概述了多数标准文档文件的目的,但是对`ChangeLog'需要另作处理。
    每个人都写一个条目以便在`ChangeLog'中记录软件变化。逻辑变化按组放置;逻辑上差别明显的变化(例如`change sets')由单一空白行分隔。下面的例子是Automake'的`ChangeLog':
//+++++++++++++++++
1999-11-21  Tom Tromey  <tromey@cygnus.com>

* automake.in (finish_languages): Only generate suffix rule
  when not doing dependency tracking.

* m4/init.m4 (AM_INIT_AUTOMAKE): UsAM_MISSING_INSTALL_SH.      
* m4/missing.m4 (AM_MISSING_INSTALL_SH): New macro.
* depend2.am: Use @SOURCE@, @OBJ@, @LTOBJ@, @OBJOBJ@,
and @BASE@.  Always use -o.
//++++++++++++++++++++++++
  另外需要指出的是:`ChangeLog'条目都必须是简洁的。一个条目并不需要详细解释一个变化的原因,但是需要解释这个变化的内容。如果一个变化不是显而易见的,那么就由源代码解释这个变化的原因。GNU编码标准就如何写`ChangeLog's提供了一套完整的指导。虽然任何一个文本编辑器都可以被用于创建修改日志条目,Emacs为你提供了主流模式。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表