autobook 中文版 (三)

5.最小的 GNU Autotools 项目

本章讲述了如何用 GNU Autotools 来管理一个最小的项目。最小的项目是指能充分说明 GNU Autotools 的规则的尽可能小的项目。测过小的项目,我们可以更容易的理解。

本章中的例子是一个叫做 foonly 的虚构的命令解释器。foonly 是用 C 写的,但如同大多数的解释器,使用lex 和 yacc 的词法分析器和语法分析器。这个项目是遵从GNU ‘Makefile’ 标准的,这也是 Automake 的默认行为。

这个项目没有使用 GNU Autotools 的许多功能。最值得关注的是库文件,项目本身没有生成任何库文件,这样我们在本章不会使用 Libtool。最复杂的项目在第九章和第十二章。这两章讲述 Libtool 在项目中的应用。本章的目的让读者对用户写的文件和它们之间的交互有一个高度的概览。

5.1 用户输入文件

The smallest project requires the user to provide only two files. The remainder of the files needed to build the package are generated by the GNU Autotools (see section 5.2).
这个最小的项目只需要用户提供两个文件。其它的文件由GNU Autotools 生成(see section 5.2)。

  • ‘Makefile.am’ 是 automake 的输入文件。
  • ‘configure.in’ 是 autoconf 的输入文件。

我喜欢把 ‘Makefile.am’ 当做一个高度概括的需求说明:要构建什么,安装在哪里。这或许是 Automake 最强大的地方–它的书写最大程度简化。它最终生成用于描述目标 ‘Makefile’。

‘configure.in’是一个执行 autoconf 的 ‘configure’ 生成的宏的模板,和一段一段的shell脚本。(see section C)。 autoconf 把 ‘configure.in’ 的内容复制到 ‘configure’,在输入时展开宏。其它内容直接复制。

让我们来看一下用户输入文件 ‘Makefile.am’:

## Makefile.am -- Process this file with automake to produce Makefile.in
bin_PROGRAMS = foonly
foonly_SOURCES = main.c foo.c foo.h nly.c scanner.l parser.y
foonly_LDADD = @LEXLIB@

这个’Makefile.am’说明程序叫做 ‘foonly’,当 make install 执行时将被安装到 bin 目录。用来生成’foonly’的c源文件是 ‘main.c’, ‘foo.c’, ‘nly.c’ 和 ‘foo.h’,lex 程序在文件 ’scanner.l’ 中,yacc语法在文件 ‘parser.y’ 中。lex 和 yacc 都由它们的输入文件生成中间语言 c。Automake 知道如何构建和连接获得可执行文件。最后,如果 ‘configure’ 需要,我们要连接一个合适的 lex 库。

‘configure.in’内容如下:

dnl Process this file with autoconf to produce a configure script.

AC_PREREQ(2.59)

AC_INIT([foonly], [2.0], [[email protected]])

AM_INIT_AUTOMAKE([1.9 foreign])

AC_PROG_CC
AM_PROG_LEX
AC_PROG_YACC

AC_CONFIG_FILES([Makefile])
AC_OUTPUT

这个 ‘configure.in’ 文件调用一些 Autoconf 命令和 Automake 初始化宏,然后调用一些 Autoconf AC_PROG 宏来寻找合适的 C ,lex,yacc程序。最后,使用宏 AC_OUTPUT 使生成的 ‘configure’ 输出 ‘Makefile’。Automake 由 ‘Makefile.am’ 生成 ‘Makefile.in’,最终生成’Makefile’。(see section C)

5.2 生成输出文件

理解附录 C 的图表,可以明白当生成文件时必须使用什么命令。

首先生成 ‘configure’

    $ aclocal
    $ autoconf

‘configure.in’ 调用了没有在 autoconf 中定义的宏 — 例如 AM_INIT_AUTOMAKE。当生成 ‘configure’ 文件时,有必要搜索所有宏的定义。这是通过 aclocal 程序完成的,它称为 aclocal 是因为它生成 ‘aclocal.m4′ 文件 (see section C)。 查看 ‘aclocal.m4′ 文件的内容,可以找到宏 AM_INIT_AUTOMAKE 的定义。

autoconf 执行后,在当前目录中会生成一个 ‘configure’ 脚本。automake 依赖于 ‘configure.in’ and ‘aclocal.m4′ 文件。在 automake 执行时:

$ 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 安装文件中复制一些模板到当前目录。文件如包含 GNU General Public License 的 ‘COPYING’,基本不变, 可以不用用户干预地生成。另外一些功能脚本也会被安装 — 用于 ‘Makefile’ 文件。所需文件还没有:

‘NEWS’
记录软件变动。对格式没有要求,但是应该最接近现在的放在前面。

‘README’
用户会最先看的文件,包含软件包的目的,或者安装方法等。

‘AUTHORS’
软件作者的名字邮件等。

‘ChangeLog’
ChangeLog 文件非常重要 –它记录的软件的惊变。 它对格式有严格要求(see section 5.5)。

现在准备充分:

    $ 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

A user would merely have to unpack the tar file, run and finally type :
现在可能用一个 tar 文件来打包目录,分发组别的用户进行安装。Automake 生成 ‘Makefile.in’ 一个目的就是使分发更加容易。(see section 13)。用户只需要解压文件,进行 configure (see section 3),最后输入 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... flex
checking for flex... (cached) flex
checking for yywrap in -lfl... yes
checking lex output file root... lex.yy
checking whether yytext is a pointer... yes
checking for bison... bison -y
updating cache ./config.cache
creating ./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

5.3 维护输入文件

如果你编辑了 GNU Autotools 的输入文件,要想使之生效必须重新生成输出文件。例如,在 ‘Makefile.am’ 的 foonly_SOURCES 变量里加入新的源文件,必须重新生成 ‘Makefile.in’。你需要重新执行 configure 和 make 编译新的文件。

可以一次执行所需程序来重新生成所有的文件。计算依赖性是困难的。一个小的改变需要运行 aclocal 吗?一个小的改变需要运行 autoconf吗?有两个方法可以解决这个问题。

第一个方法是使用 autoreconf 命令。这个工具执行所有所需的程序来重新生成文件。这是一个野蛮的方法,但是非常有效,尤其是你不想程序使用于其它的维护者,或者进行日常的维护。

另外一个选择是 Automake’ 的 ‘maintainer mode’。调用 ‘configure.in’ 里的 AM_MAINTAINER_MODE 宏, automake 会激活 ‘configure’ 的 ‘–enable-maintainer-mode’ 选项。在第八章详细讲解。

5.4 打包生成文件

在互联网的邮件列表里关于生成文件要做什么的问题有强烈的争议。有两种观点,我都会介绍使你可以选择你认为对的。

一种说法是生成文件不应该包含在软件包里。软件包里只应该包含源文件。显然,’configure’ 是一个生成文件,它不应该存在于软件包里。这样,用户要先使用 GNU Autotools 来构建软件。

另外一种观点是提供这些文件的好处要大于上面提到的保持良好的软件工程方法。包含这些文件,用户不必担心不同版本的升级问题。这点在 Autoconf 中特别明显,因为 ‘configure’ 脚本经常是维护人员用修改后的 autoconf 版本和本地安装的宏库生成的。用户再执行 ‘configure’,会产生不同的结果。当然,这种方法在实践方面不好,但它反映了实际。

我认为当软件包分发时,提供生成文件较好。当开发人员使用时,前一种方法更好。因为软件就是基于开发人员的环境的。

5.5 文档和 changelog

对于任何软件来说,在软件发展过程中维护文档是非常重要的。文档要反应出软件的当前状态,还要准确地记录过去的更改。GNU 代码标准严格地实施文档的维护。实际上,Automake 在执行时检查 ‘ChangeLog’ 是否存在来实施标准。

在GNU包里的许多文件使用标准化的文件名。GNU代码标准有许多有用的见解,完整版可以在http://www.gnu.org/prep /standards.html找到。

其它的项目,可以使用一些可靠的技术。在5.2节可以看到一些其它标准的文档 。但是’ChangeLog’ 另当别论。

‘ChangeLog’ 每一条是单人写的。功能上的改变是小组一起写的。明显的改变用一个空白行分隔。这是 Automake 的 ‘ChangeLog’ 例子:

1999-11-21  Tom Tromey

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

        * m4/init.m4 (AM_INIT_AUTOMAKE): Use AM_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’ 准则。

你可能感兴趣的:(autobook 中文版 (三))