`
isiqi
  • 浏览: 16557125 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

Automake 使用指南

阅读更多

目录


@dircategory GNU admin @direntry * automake: (automake). Making Makefile.in's

@dircategory Individual utilities @direntry * aclocal: (automake)Invoking aclocal. Generating aclocal.m4

Copyright (C) 1995, 96 Free Software Foundation, Inc.

这是GNU Automake文档的第一版,
并且是针对GNU Automake 1.3的。

自由软件基金会出版
59 Temple Place - Suite 330,
Boston, MA 02111-1307 USA

Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.

Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one.

Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation.

只要版权声明和本许可声明保留在所有副本中,您就被授权制作和发行本手册的 原文副本。

只要整个最终派生工作按照与本手册相同的许可声明发行,您就被授权按照与 发行原文相同的条件复制和发行本手册的修改版本。

除了本许可声明应该使用由基金会批准的译文之外,您被授权按照与上述修改 版本相同的条件复制和发行本手册的其它语言的译文。


本文档由王立翻译。 1999.12.17

译者在此声明:不对任何由译文错误或者对译文的误解承担任何责任。


介绍

Automake是一个从文件`Makefile.am' 自动生成`Makefile.in' 的工具。每个`Makefile.am' 基本上是一系列make 的宏定义 (make规则也会偶尔出现)。生成的`Makefile.in' s服从GNU Makefile标准。

GNU Makefile标准文档(参见GNU编码标准 中的‘Makefile惯例’节) 长、复杂,而且会发生改变。Automake的目的就是解除个人GNU维护者维护Makefile的负担 (并且让Automake的维护者来承担这个负担)。

典型的Automake输入文件是一系列简单的宏定义。处理所有这样的文件以创建 `Makefile.in' 。在一个项目(project)的每个目录中通常包含一个 `Makefile.am'

Automake在几个方面对一个项目做了限制;例如它假定项目使用Autoconf (参见Autoconf手册 ),并且对`configure.in' 的内容施加了某些限制。

为生成`Makefile.in' ,Automake需要perl 。 但是由Automake创建的发布完全服从GNU标准,并且在创建中不需要perl

请把关于Automake的建议和bug发送到 automake-bugs@gnu.org

通用性概念

一些基本概念将有助于理解Automake是如何工作的。

通用操作

Automake读入`Makefile.am' 并且生成`Makefile.in' 。 在`Makefile.am' 中定义的一些宏和目标(targets)指挥automake生成 更多特定的代码;例如一个`bin_PROGRAMS' 宏定义将生成一个需要 被编译、连接的目标。

`Makefile.am' 中的宏定义和目标被复制到生成的文件中。这使得你可以把 任何代码添加到生成的`Makefile.in' 文件中。例如,Automake的发布 包含了非标准的cvs-dist 目标,Automake的维护者用它从他的版本 控制系统中创建发布版本。

Automake不能识别GNU对make的扩展。在`Makefile.am' 中使用这些 扩展将导致错误或者令人不解的行为。

Automake试图明智地把注释和相邻的目标(或者变量定义)关联起来。

`Makefile.am' 中定义的目标通常覆盖了所有由automake 自动生成的拥有相似名字的目标。虽然Automake提供了这一功能,但最好避免使用它, 因为有些时候生成的规则将是十分特别的。

类似地,在`Makefile.am' 中定义的变量将覆盖任何通常由automake 创建的变量定义。该功能比覆盖目标定义的功能要常用得多。需要警告的是许多由 automake 生成的变量都被认为是内部使用的,并且它们的名字可能在未来 的版本中改变。

在检验变量定义的时候,Automake将递归地检验定义中的变量引用。例如,如果Automake 在如下片断中搜索`foo_SOURCES' 的内容。

xs = a.c b.c
foo_SOURCES = c.c $(xs)

它将把文件`a.c'`b.c'`c.c' 作为`foo_SOURCES' 的内容。

Automake还允许给出 被复制到输出中的注释;所有以`##' 开头的行 将被Automake彻底忽略。

作为惯例,`Makefile.am' 的第一行是:

## Process this file with automake to produce Makefile.in

深度

automake 支持三种目录层次: “flat”、“shallow”和“deep”。

一个flat (平)包指的是所有文件都在一个目录中的包。为这类包提供的`Makefile.am' 缺少宏SUBDIRS 。这类包的一个例子是termutils

一个deep (深)包指的是所有的源代码都被储存在子目录中的包;顶层 目录主要包含配置信息。GNU cpio 是这类包的一个很好的例子,GNU tar 也是。deep包的顶层`Makefile.am' 将包括 宏SUBDIRS ,但没有其它定义需要创建的对象的宏。

一个shallow (浅)包指的是主要的源代码储存在顶层目录中,而 各个部分(典型的是库)则储存在子目录中的包。Automake本身就是这类包(GNU make 也是如此,它现在已经不使用automake )。

严格性

Automake的目的是用于维护GNU包,它为适应那些希望使用它的人做出 了一些努力,但并不指望应用所有的GNU惯例。

按照这个目标,Automake支持三级严格性 ---严格性指的是Automake 将如何检查包所服从的标准。

可用的严格性级别有:

`foreign' (外来)
Automake将仅仅检查那些为保证正确操作所必需的事项。例如,尽管GNU标准指出 文件`NEWS' 必须存在,在本方式下,并不需要它。该模式名来自于Automake 是被设计成用于GNU程序的事实的;它放松了标准模式的操作规则。
`gnu'
Automake将尽可能地检查包是否服从GNU标准。这是缺省设置。
`gnits'
Automake将按照还没有完成的Gnits标准进行检查。它们是基于GNU标准的,但更加 详尽。除非你是Gnits标准的参与奉献者,我们建议您在Gnits标准正式出版之前 不要使用这一选项。

关于严格性级别的精确含义的详细说明,参见--gnu--gnits 的效果

统一命名机制

Automake变量通常服从统一的命名机制,以易于确定如何创建和安装程序(和其它派生对象)。 这个机制还支持在运行configure 的时候确定应该创建那些对象。

在运行make 时,某些变量被用于确定应该创建那些对象。 这些变量被称为主(primary) 变量。例如,主变量PROGRAMS 保存了需要被编译和连接的程序的列表。

另一组变量用于确定应该把创建了的对象安装在哪里。这些变量在主变量之后命名, 但是含有一个前缀以指出那个标准目录将作为安装目录。标准目录名在GNU标准中给出 (参见GNU编码标准 中的`为Directory Variables'节)。 Automake用pkglibdirpkgincludedirpkgdatadir 扩展了这个列表;除了把`@PACKAGE@' 附加 其后之外,与非`pkg' 版本是相同的。 例如,pkglibdir 被定义为$(datadir)/@PACKAGE@ .

对于每个主变量,还有一个附加的变量,它的名字是在主变量名之前加一个`EXTRA_' 。 该变量用于储存根据configure 的运行结果,可能创建、也可能不创建 的对象列表。引入该变量是因为Automake必须静态地知道需要创建的对象的完整列表 以创建在所有情况下都能够工作的`Makefile.in'

例如,在配置时刻cpio 确定创建哪些程序。一部分程序被安装在bindir , 还有一部分程序被安装在sbindir

EXTRA_PROGRAMS = mt rmt
bin_PROGRAMS = cpio pax
sbin_PROGRAMS = @PROGRAMS@

定义没有前缀的主变量(比如说PROGRAMS )是错误的。

在构造变量名的时候,通常省略后缀`dir' ;因此我们使用 `bin_PROGRAMS' 而不是`bindir_PROGRAMS' .

不是每种对象都可以安装在任何目录中。Automake将记录它们以试图找出 错误。Automake还将诊断目录名中明显的拼写错误。

有时标准目录--即使在Automake扩展之后---是不够的。特别在有些时候,为了清晰 起见,把对象安装到预定义目录的子目录中是十分有用的。为此,Automake允许你 扩展可能的安装目录列表。如果定义了一个添加了后缀`dir' 的变量 (比如说`zardir' ),则给定的前缀(比如`zar' ) 就是合法的。

例如,在HTML支持成为Automake的一部分之前,你可以使用它安装原始的HTML文档。

htmldir = $(prefix)/html
html_DATA = automake.html

特殊前缀`noinst' 表示根本不会安装这些有问题的对象。

特殊前缀`check' 表示仅仅在运行make check 命令的时候才创建这些有问题的对象。

可能的主变量名有`PROGRAMS'`LIBRARIES'`LISP'`SCRIPTS'`DATA'`HEADERS'`MANS'`TEXINFOS'

派生变量是如何命名的

有时Makefile变量名是从用户提供的某些文本中派生而来的。例如程序名被重写 到Makefile宏名中。Automake把这些文本规范化,以使它可以不必服从Makefile的 变量名规则。在名字中除了字母、数字和下划线之外的所有字符都将用下划线代替。 例如,如果你的程序被命名为sniff-glue ,那么派生出的变量名 将是sniff_glue_SOURCES ,而不是sniff-glue_SOURCES

一些实例软件包

一个简单的例子,从起点到终点

让我们假定你刚刚写完zardoz ,一个是你的头从一个漩涡漂流 到另一个漩涡的程序。你已经使用了autoconf 以提供一个可移植的框架, 但你的`Makefile.in' 还未完成,所以你需要automake

第一步是更新你的`configure.in' 以包含automake 需要的命令。 完成这一步的最简单方式是在AC_INIT 之后添加AM_INIT_AUTOMAKE

AM_INIT_AUTOMAKE(zardoz, 1.0)

因为你的程序不含有任何复杂性的因素(例如,它不使用gettext ,它 不需要共享库),你已经完成了这一步工作。很容易吧!

现在你必须重新生成`configure' 。但为此,你需要告诉autoconf 如何找到你使用的新宏。完成该任务的最简单的方式是使用aclocal 程序为你 生成你的`aclocal.m4' 。但是等等...你已经有了一个`aclocal.m4' , 这是因为你必须为你的程序写一些宏。aclocal 允许你把你自己的宏放到 `acinclude.m4' 中去,所以简单地改名并且运行:

mv aclocal.m4 acinclude.m4
aclocal
autoconf

现在是你为zardoz 写的`Makefile.am' 的时候了。 zardoz 是一个用户程序,所以你需要把它安装到其它用户程序安装的地方去。 zardoz 还有一些Texinfo文档。你的`configure.in' 脚本使用 AC_REPLACE_FUNCS ,因此你需要与`@LIBOBJS@' 连接。 所以这里你写:

bin_PROGRAMS = zardoz
zardoz_SOURCES = main.c head.c float.c vortex9.c gun.c
zardoz_LDADD = @LIBOBJS@

info_TEXINFOS = zardoz.texi

现在你运行automake --add-missing 以生成你的`Makefile.in' 并且得到任何你可能需要的附加文件,现在你完成了你的任务!

一个经典的程序

hello 因为它经典的简单性和多用性而出名。 本节展示Automake将被如何用于Hello包。 下面的例子来自于最新的GNU Hello,但剔除了所有仅为维护者使用的代码和所有的版权注释。

当然,GNU Hello比您的传统的两行的代码具有更多的特征。GNU Hello是国际化的,进行选项 处理,并且含有一个手册和一个测试套件。GNU Hello是一个deep包。

这里是来自于GNU Hello的`configure.in'

dnl Process this file with autoconf to produce a configure script.
AC_INIT(src/hello.c)
AM_INIT_AUTOMAKE(hello, 1.3.11)
AM_CONFIG_HEADER(config.h)

dnl Set of available languages.
ALL_LINGUAS="de fr es ko nl no pl pt sl sv"

dnl Checks for programs.
AC_PROG_CC
AC_ISC_POSIX

dnl Checks for libraries.

dnl Checks for header files.
AC_STDC_HEADERS
AC_HAVE_HEADERS(string.h fcntl.h sys/file.h sys/param.h)

dnl Checks for library functions.
AC_FUNC_ALLOCA

dnl Check for st_blksize in struct stat
AC_ST_BLKSIZE

dnl internationalization macros
AM_GNU_GETTEXT
AC_OUTPUT([Makefile doc/Makefile intl/Makefile po/Makefile.in \
           src/Makefile tests/Makefile tests/hello],
   [chmod +x tests/hello])

`AM_' 由Automake(或者Gettext库)提供;其它的是标准Autoconf宏。

顶层`Makefile.am'

EXTRA_DIST = BUGS ChangeLog.O
SUBDIRS = doc intl po src tests

就像你所见到的,这里的所有工作实际上都是在子目录中完成的。

`po'`intl' 目录是gettextize 自动生成的; 在这里我们不讨论它们。

在`doc/Makefile.am'中我们看到:

info_TEXINFOS = hello.texi
hello_TEXINFOS = gpl.texi

它足以创建、安装并且发布Hello手册。

这里是`tests/Makefile.am' :

TESTS = hello
EXTRA_DIST = hello.in testdata

脚本`hello' 是由configure 生成的,并且仅仅在测试时才生成。 make check 将运行这个测试。

最后我们有`src/Makefile.am' ,所有实际工作在此完成:

bin_PROGRAMS = hello
hello_SOURCES = hello.c version.c getopt.c getopt1.c getopt.h system.h 
hello_LDADD = @INTLLIBS@ @ALLOCA@
localedir = $(datadir)/locale
INCLUDES = -I../intl -DLOCALEDIR=\"$(localedir)\"

创建etags和ctags

这里是另一个复杂一些的例子。它展示了如何从同一个源文件(`etags.c' ) 生成两个程序(ctagsetags )。困难的部分是对 `etags.c' 的每个编译需要不同的cpp 选项。

bin_PROGRAMS = etags ctags
ctags_SOURCES =
ctags_LDADD = ctags.o

etags.o: etags.c
        $(COMPILE) -DETAGS_REGEXPS -c etags.c

ctags.o: etags.c
        $(COMPILE) -DCTAGS -o ctags.o -c etags.c

其中ctags_SOURCES 被定义为空--这种方式表明没有替换隐含的值 然而,隐含的值被用于从`etags.o' 生成etags

ctags_LDADD 用于把`ctags.o' 添加到连接行中。 ctags_DEPENDENCIES 由Automake生成。

如果你的编译器不接受`-c'`-o' ,那么上述规则 将不能工作。对此,最简单的修正是引入伪依赖(bogus dependency)(以避免由并行 make 所导致的问题):

etags.o: etags.c ctags.o
        $(COMPILE) -DETAGS_REGEXPS -c etags.c

ctags.o: etags.c
        $(COMPILE) -DCTAGS -c etags.c && mv etags.o ctags.o

同样,如果使用了de-ANSI-fication的特征,这些显式规则将不能工作;支持它需要 一些更多的工作:

etags._o: etags._c ctags.o
        $(COMPILE) -DETAGS_REGEXPS -c etags.c

ctags._o: etags._c
        $(COMPILE) -DCTAGS -c etags.c && mv etags._o ctags.o

创建`Makefile.in'

为了为一个包创建所有的`Makefile.in' ,在顶层目录不带任何参数地运行automakeautomake 将自动地寻找每个合适的`Makefile.am' (通过扫描 `configure.in' ;参见扫描`configure.in' ) 并生成相应的`Makefile.in'automake 认为包的组成是相当简单的; 它假定包仅仅在顶层目录含有一个`configure.in' 。如果你的包含有多个 `configure.in' ,那么你必须在每个含有`configure.in' 的目录 中运行automake

你偶尔可能需要给automake 参数;`.am' 被添加到参数之后 并且其结果将作为输入文件名。该特征通常仅仅用于自动重新创建一个过时的 `Makefile.in'automake 必须总是在项目的最顶层目录中运行, 即使用于重新生成某些子目录中的`Makefile.in' 也是如此。 这是因为automake 必须扫描`configure.in' ,并且因为 在某些情况下,automake 根据`Makefile.in' 在子目录中这一情况 确定它的行为。

automake 接受以下选项:

-a
--add-missing
Automake要求一些通用文件在特定的位置存在。例如如果`configure.in' 运行 了AC_CANONICAL_HOST ,就需要`config.guess' 。 Automake与几个这样的文件一同发布;只要可能,该选项将把缺少的文件自动添加到包中。 通常如果Automake告诉你缺少文件,试一下本选项。
--amdir=dir
dir 中而不是安装目录中,寻找Automake数据文件,它通常用于调试。
--build-dir=dir
告诉Automake创建目录在那里。本选项在把依赖性添加到由make dist 生成的 `Makefile.in' 中的时候使用;在其它情况下不应该使用它。
--cygnus
按照Cygnus规则,而不是GNU或者Gnits规则,生成`Makefile.in' , 详情请参见--cygnus 的效果
--foreign
把全局严格性设置成`foreign' 。详情请参见严格性
--gnits
把全局严格性设置成`gnits' 。详情请参见 --gnu--gnits 的效果
--gnu
把全局严格性设置成`gnu' 。详情请参见 --gnu--gnits 的效果 。 这是缺省严格性。
--help
打印命令行选项的概述并且退出。
-i
--include-deps
包含生成的`Makefile.in' 中所有自动生成的依赖信息(参见自动的依赖性跟踪 )。 通常在制作发布版本时使用;参见需要发布哪些文件
--generate-deps
生成一个连接了所有自动生成的依赖信息的文件(参见 自动的依赖性跟踪 )文件,`.dep_segment' 。 通常在制作发布版本时使用;参见需要发布哪些文件 。 在维护为其它平台所制作的`SMakefile' 或者makefile(`Makefile.DOS' , 等等,)时是有用的。它只能与--include-deps--srcdir-name--build-dir 一同使用。如果给出了本选项,不会实行任何其他处理。
--no-force
通常automake 创建在`configure.in' 中提到的所有 `Makefile.in' 。本选项仅仅更新那些按照它们的依赖性过时了的 `Makefile.in'
-o dir
--output-dir=dir
把生成的`Makefile.in' 放到目录dir 中。 通常每个`Makefile.in' 在对应的`Makefile.am' 所在 的目录中创建。本选项被用于创建发布版本。
--srcdir-name=dir
告诉Automake与当前任务相关的源代码目录名。本选项在把依赖性引入 由make dist 生成的`Makefile.in' 中时使用; 它不应被用于其它情况。
-v
--verbose
让Automake打印关于被读入或创建的文件的信息。
--version
打印Automake的版本号并且退出。

扫描`configure.in'

Automake扫描包的`configure.in' 以确定关于包的一些信息。 Automake需要一些autoconf 宏并且一些变量必须在 `configure.in' 中定义。Automake还用来自`configure.in' 的信息以进一步修整它的输出。

为了简化维护,Automake还支持一些autoconf 宏。 通过使用程序aclocal ,可以自动地把这些宏附加到你的`aclocal.m4' 中。

配置需求

达到Automake要求的最简单方式就是使用宏AM_INIT_AUTOMAKE (参见由Automake支持的Autoconf宏 )。 但是如果你愿意,你可以手工完成所需的各个步骤:

  • AC_SUBST 定义变量PACKAGEVERSION PACKAGE 应该是在捆绑发布的时候使用的包的名称。 例如,Automake把PACKAGE 定义成`automake'VERSION 应该是被开发的版本的版本号。 我们建议你仅仅在你的包中定义版本号的地方创建`configure.in' ; 这使得发布简单化了。 除非在`Gnits' 模式(参见 --gnu--gnits 的效果 ),Automake 不会对PACKAGE 或者VERSION 进行任何解释。
  • 如果要安装一个程序或者一个脚本,使用宏AC_ARG_PROGRAM
  • 如果包不是平(flat)的,使用宏AC_PROG_MAKE_SET
  • 使用宏AM_SANITY_CHECK 以确认创建环境的完整性。
  • 如果包安装了任何脚本(参见可执行的脚本 ), 使用宏AM_PROG_INSTALL 。否则,使用AC_PROG_INSTALL
  • 使用AM_MISSING_PROG 以确认在创建环境中,程序aclocalautoconfautomakeautoheadermakeinfo 是否存在。下面是如何完成这个任务:
    missing_dir=`cd $ac_aux_dir && pwd`
    AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
    AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
    AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
    AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
    AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
    

这里是Automake需要的,但是没有被AM_INIT_AUTOMAKE 运行的 其它宏:

AC_OUTPUT
Automake用它确定创建那个文件。列出的名为Makefile 的文件 作为`Makefile' 处理。对其它列出的文件进行不同的处理。 目前唯一的不同是`Makefile' 将被make distclean 删除,而其它的文件将被make clean 删除。

Automake能够识别的其它事情

Automake还将能够识别某些宏的使用并且适当地修整生成的`Makefile.in' 。 目前能够识别的宏以及它们的效果是:

AC_CONFIG_HEADER
Automake要求使用AM_CONFIG_HEADER ,它类似于AC_CONFIG_HEADER 而且完成一些有用的Automake特定的工作。
AC_CONFIG_AUX_DIR
Automake将在调用本宏时命名的目录中寻找各种求助脚本,例如`mkinstalldirs' 。 如果没找到,将在其它标准的位置(顶层目录中,或者在对应与当前`Makefile.am' 的源代码目录,任何一个都是合适的)中寻找脚本。 请帮助我:以给出寻找该目录的完整列表。
AC_PATH_XTRA
Automake将把由AC_PATH_XTRA 定义的变量的定义插入 每个创建C程序或者库的`Makefile.in' 中。
AC_CANONICAL_HOST
AC_CHECK_TOOL
Automake将确认`config.guess'`config.sub' 的存在。 并且将引入`Makefile' 变量`host_alias'`host_triplet'
AC_CANONICAL_SYSTEM
它类似于AC_CANONICAL_HOST ,此外还定义了`Makefile' 变量`build_alias'`target_alias'
AC_FUNC_ALLOCA
AC_FUNC_GETLOADAVG
AC_FUNC_MEMCMP
AC_STRUCT_ST_BLOCKS
AC_FUNC_FNMATCH
AM_FUNC_STRTOD
AC_REPLACE_FUNCS
AC_REPLACE_GNU_GETOPT
AM_WITH_REGEX
Automake将确认为对应于这些宏的对象生成了适当的依赖关系。 此外,Automake将验证适当的源文件成为发布的一部分。 使用这些宏,Automake并不需要任何C源代码,所以automake -a 将不会安装源代码。 详情请参见创建一个库
LIBOBJS
Automake将检测把`.o' 文件添加到LIBOBJS 中的语句, 并且按照与在AC_REPLACE_FUNCS 中发现的文件相同的方式处理 这些附加的文件。
AC_PROG_RANLIB
如果在包中创建了任何库,就需要它。
AC_PROG_CXX
如果包含了任何C++源代码,就需要它。
AM_PROG_LIBTOOL
Automake将启动为libtool 所做的处理(参见Libtool手册 )。
AC_PROG_YACC
如果找到了Yacc源文件,那么你必须使用这个宏或者在`configure.in' 中定义变量`YACC' 。前者更好一些。
AC_DECL_YYTEXT
如果在包中有Lex源代码,需要使用这个宏。
AC_PROG_LEX
如果找到了Lex源代码,那么必须使用本宏。
ALL_LINGUAS
如果Automake发现在`configure.in' 中设置了该变量, 它将检查目录`po' 以确认所有命名了的`.po' 文件都是存在的,并且所有存在的`.po' 文件都被 命了名。
AM_C_PROTOTYPES
在使用自动de-ANSI-fication时,需要它。参见自动de-ANSI-fication
AM_GNU_GETTEXT
使用了GNU gettext的包需要使用本宏。 (参见Gettext )。 它将与gettext一起发布。如果Automake看到这个宏,Automake将确认包 是否符合gettext的某些要求。
AM_MAINTAINER_MODE
该宏为configure 添加一个`--enable-maintainer-mode' 选项。如果使用了本宏,automake 将关闭在生成的 `Makefile.in' 中缺省的“maintainer-only”规则。 在`Gnits' 模式中,不允许使用本宏。 (参见--gnu--gnits 的效果)。
AC_SUBST
AC_CHECK_TOOL
AC_CHECK_PROG
AC_CHECK_PROGS
AC_PATH_PROG
AC_PATH_PROGS
上述任意一个宏的第一个参数将在每个生成的`Makefile.in' 中自动地被定义为一个变量。

自动生成aclocal.m4

Automake包含了许多可以你的包中使用的的Autoconf宏;其中一些实际上是 Automake在某些情况下需要的。你必须在你的`aclocal.m4' 中定义这些宏; 否则autoconf 将不能找到它们。

程序aclocal 将基于`configure.in' 的内容自动生成文件 `aclocal.m4' 。它提供了一个不必四处寻找而获得Automake提供的宏的 便利方式。此外,aclocal 机制对使用它的其它包来说,是可以扩展的。

在启动时,aclocal 扫描所有它能够找到的`.m4' 文件, 以寻找宏定义。而后它扫描`configure.in' 。任何在第一步中提到的宏, 以及它所需要的宏,将被放到`aclocal.m4' 中。

如果`acinclude.m4' 存在,它的内容将被自动包含在 `aclocal.m4' 中。这对于把本地宏合并到`configure' 是有用的。

aclocal 接受如下选项:

--acdir=dir
在目录dir 中,而不是在安装目录中,寻找宏文件。这通常用于调试。
--help
打印命令行选项的概述并且退出。
-I dir
把目录dir 添加到搜索`.m4' 的目录列表中。
--output=file
把输出储存到文件file 中,而不是`aclocal.m4' 中。
--print-ac-dir
打印aclocal 将搜索`m4' 文件的目录名。当给出 本选项的时候,不实施通常的处理。包可以用本选项确定应该把宏文件安装到哪里。
--verbose
打印它所检测的文件名。
--version
打印Automake的版本号并且退出。

由Automake支持的Autoconf宏

AM_CONFIG_HEADER
Automake将生成规则以自动地重新生成config头文件。如果你使用本宏, 你必须在你的源代码目录中创建文件`stamp-h.in' 。它可以为空。
AM_CYGWIN32
检查本configure 是否是在`Cygwin32' 环境 中运行。(FIXME xref)。如果是,把输出变量EXEEXT 定义为 `.exe' ;否则,把它定义为空字符串。Automake识别该宏 并且用它生成在`Cygwin32' 中可以自动工作的`Makefile.in' 。 在`Cygwin32' 环境中,即使在命令行中没有明确指出,gcc 将生成文件名以`.exe' 结尾的可执行文件。Automake向 `Makefile.in' 添加特定的代码以适当地处理它。
AM_FUNC_STRTOD
如果不能使用函数strtod ,或者不能正确地工作(例如在SunOS 5.4上), 就把`strtod.o' 添加到输出变量LIBOBJS 中。
AM_FUNC_ERROR_AT_LINE
如果没有找到error_at_line 函数,就把`error.o' 添加到LIBOBJS 中。
AM_FUNC_MKTIME
检查函数mktime 。如果没有找到,就把`mktime.o' 添加到`LIBOBJS' 中。
AM_FUNC_OBSTACK
检查GNU obstacks代码;如果没有找到,就把`obstack.o' 添加到`LIBOBJS' 中。
AM_C_PROTOTYPES
检查编译器是否可以识别函数原型。如果可以识别,就定义`PROTOTYPES' 并且把输出变量`U'`ANSI2KNR' 设置为空。否则, 把`U' 设置成`_' ,并且把`ANSI2KNR' 设置成`./ansi2knr' 。Automake使用这些值以实现自动de-ANSI-fication。
AM_HEADER_TIOCGWINSZ_NEEDS_SYS_IOCTL
如果使用TIOCGWINSZ 需要`<sys/ioctl.h>' , 那么定义GWINSZ_IN_SYS_IOCTL 。否则,TIOCGWINSZ 可以在`<termios.h>' 中发现。
AM_INIT_AUTOMAKE
运行大部分`configure.in' 需要的多个宏。本宏有两个参数,包名称 和版本号。缺省情况下,本宏用AC_DEFINE 定义`PACKAGE'`VERSION' 。可以通过添加非空的第三个参数以避免这一行为。
AM_PATH_LISPDIR
搜索程序emacs ,并且,如果找到了,把输出变量lispdir 设置为到Emac的site-lisp目录的完整路径。
AM_PROG_CC_STDC
如果C编译器的缺省状态不是标准C(ANSI C),试图把一个选项添加到输出变量 CC 中以使得C编译器这样做。本宏尝试在各种系统中选择标准C的 各种选项。如果编译器正确地处理函数原型,它就认为编译器处于标准C模式。 如果你使用本宏,你应该在调用它之后检查C编译器是否被设置成接受标准C; 如果不是,shell变量am_cv_prog_cc_stdc 被设置成`no' 。 如果你按照标准C写你的源代码,你可以利用ansi2knr 选项 创建它的非标准C版本。
AM_PROG_INSTALL
类似与AC_PROG_INSTALL ,但还定义了INSTALL_SCRIPT
AM_PROG_LEX
类似与带有AC_DECL_YYTEXTAC_PROG_LEX , 但在没有lex的系统上使用脚本missing`HP-UX 10' 是一个这样的系统。
AM_SANITY_CHECK
它检查并确保在创建目录中被创建的文件比源代码目录中的文件要新。 在时钟设置不正确的系统中它可能失败。本宏在AM_INIT_AUTOMAKE 中自动运行。
AM_SYS_POSIX_TERMIOS
检查系统中,是否可以使用POSIX termios头文件和函数。如果可以,就把shell变量 am_cv_sys_posix_termios 设置为`yes' 。如果不能使用, 就把am_cv_sys_posix_termios 设置为`no'
AM_TYPE_PTRDIFF_T
如果类型`ptrdiff_t' 是在`<stddef.h>' 中定义的, 就定义`HAVE_PTRDIFF_T'
AM_WITH_DMALLOC
增加dmalloc 包支持。如果用户用`--with-dmalloc' 进行配置, 那么定义WITH_DMALLOC 并且把`-ldmalloc' 添加到LIBS 。 包dmalloc 可以在ftp://ftp.letters.com/src/dmalloc/dmalloc.tar.gz 找到。
AM_WITH_REGEX
`--with-regex' 添加到configure 的命令行中。 如果给出`--with-regex' (缺省设置),那么使用 `regex' 常规表达式库,`regex.o' 被添加到`LIBOBJS' 中,并且定义`WITH_REGEX' 。 如果给出`--without-regex' ,那么使用`rx' 常规表达式库,`rx.o' 被添加到`LIBOBJS' 中。

编写你自己的aclocal宏

aclocal不含有任何宏的任何内置信息,所以扩展你自己的宏是十分容易的。

它通常被用于那些需要为使用它的其它程序提供它们自己的Autoconf宏的库。例如gettext 库支持宏 AM_GNU_GETTEXT ,该宏将被任何使用gettext 的任何包所使用。在安装库的时候, 它安装宏以便aclocal 可以找到它。

一个宏文件应该是一系列AC_DEFUN '。aclocal还懂得AC_REQUIRE , 所以把每个宏储存在一个单独的文件中是安全的。

一个宏文件的文件名应该以`.m4' 结尾。这类文件都应该安装在`$(datadir)/aclocal' 中。

顶层`Makefile.am'

在非平(non-flat)包中,顶层`Makefile.am' 必须告诉Automake 应该在那个子目录中进行创建。这通过变量SUBDIRS 来完成。

SUBDIRS 保存了需要进行各种创建的子目录列表。在生成 的`Makefile' 中的许多目标(例如,all )即需要 在本目录下运行,也需要在所有特定的子目录下运行。需要指出,出现在 SUBDIRS 中的子目录并不一定含有`Makefile.am' ; 只要在配置(运行configuration)之后含有`Makefile' 就行了。 这使得你可以从不使用Automake的软件包(例如,gettext )中引入库。 在SUBDIRS 中提到的目录必须是当前目录的直接子目录。 例如,你可以把`src/subdir' 添加到SUBDIRS 中。

在一个深(deep)包中,顶层`Makefile.am' 通常十分简短。 例如,下面是Hello发布版中的`Makefile.am'

EXTRA_DIST = BUGS ChangeLog.O README-alpha
SUBDIRS = doc intl po src tests

就像在GNU Inetutils 中的情况一样,如果你只需要创建整个 包的一个子集,你可以覆盖变量SUBDIRS 。在你的 `Makefile.am' 中包含:

SUBDIRS = @SUBDIRS@

而后在你的`configure.in' 中,你可以指明:

SUBDIRS = "src doc lib po"
AC_SUBST(SUBDIRS)

以上修改的结果是:automake将创建包以获得subdirs,但 实际上在运行configure 之前并没有把目录 列表包括进来。

SUBDIRS 可以包含配置替换(例如,`@DIRS@' ); Automake本身并不实际检查这个变量的内容。

如果定义了SUBDIRS ,那么你的`configure.in' 必须包含AC_PROG_MAKE_SET

SUBDIRS 的使用并不限于顶层目录中的`Makefile.am' 。 Automake可以用于构造任意深度的包。

创建程序和库

Automake的大部分功能的目的是使创建C程序和库变得容易些。

创建一个程序

在一个含有将被创建成一个程序(而不是创建成一个库)的源代码的目录中, 要使用主变量`PROGRAMS' 。程序可以安装到`bindir'`sbindir'`libexecdir'`pkglibdir' 中, 或者根本不安装(`noinst' )。

例如:

bin_PROGRAMS = hello

在这种简单的情况下,最终的`Makefile.in' 将含有代码以生成 名为hello 的一个程序。变量hello_SOURCES 用于确定哪些源代码应该被创建到可执行文件中去:

hello_SOURCES = hello.c version.c getopt.c getopt1.c getopt.h system.h 

它将导致所有提及的`.c' 文件被编译成对应的`.o' 文件。而后被一同连接以生成`hello'

如果需要`prog_SOURCES' ,但并未定义它,那么它被缺省地设置 成单个文件`prog.c' 。在上面的例子中,对hello_SOURCES 的定义实际上是多余的。

可以把多个程序创建到一个目录中。多个程序可以共享一个源代码文件。 源代码文件必须在需要它的每个`_SOURCES' 中列出。

出现在`_SOURCES' 中的头文件将被包含在发布版本中,其它的头文件将被忽略。 因为它并不明显,你不应该把由`configure' 生成的头文件包含在变量`_SOURCES' 中; 不应该发布这个文件。也可以列出lex(`.l' )和yacc(`.y' )文件; 参见对Yacc和Lex的支持

即使不是所有的文件在所有的情况下都需要被创建,Automake也必须知道 所有可能被连接到程序中的源文件。所有仅仅是可能被创建的文件应该被适当 地添加到变量`EXTRA_' 中。例如,如果`hello-linux.c' 是有条件地被包含在hello 中,`Makefile.am' 应该包括:

EXTRA_hello_SOURCES = hello-linux.c

类似地,有时候需要在配置的时刻确定创建那些程序。例如GNU cpio 仅仅在特殊情况下才创建mtrmt

在这种情况下,你必须把可能创建的所有程序都告诉automake , 但同时使生成的`Makefile.in' 使用由configure 指明的程序。这可以通过在EXTRA_PROGRAMS 中列出所有可能创建的程序的同时, 把configure 提供的值的替换到每个`_PROGRAMS' 变量的定义中,来完成。

如果你需要和configure 没有找到的库相连接,你可以使用LDADD 来完成。 该变量实际上可以用于把任何选项添加到连接器的命令行中。

有时,要在一个目录中创建多个程序,但并不共享相同的连接时刻需求(link-time requirement)。 在这种情况下,你可以使用变量`prog _LDADD' (其中prog 是出现在某些`_PROGRAMS' 变量 中的程序名)来覆盖全局的LDADD 。(对于某个程序来说, 如果存在这个变量,那么那个程序的连接就不使用LDADD 。)

例如,在GNU cpio中,paxcpiomt 需要和库`libcpio.a' 连接。然而,rmt 在同一个目录 中创建,并且不需要与`libcpio.a' 连接。此外,mtrmt 也仅仅在这种结构下创建。这里是cpio的`src/Makefile.am' 内容(有删节):

bin_PROGRAMS = cpio pax @MT@
libexec_PROGRAMS = @RMT@
EXTRA_PROGRAMS = mt rmt

LDADD = ../lib/libcpio.a @INTLLIBS@
rmt_LDADD =

cpio_SOURCES = ...
pax_SOURCES = ...
mt_SOURCES = ...
rmt_SOURCES = ...

变量`prog_LDADD' 并不适用与传递程序特定的连接器选项 (除了`-l'`-L' 之外)。所以,为此请使用 变量`prog_LDFLAGS'

有时候,是否创建一个程序依赖于不属于那个程序的某些其它目标。 通过使用变量`prog_DEPENDENCIES' 可以实现该功能。 每个程序都依赖于这个变量的内容,但是不对它进行进一步的解释。

如果没有给出`prog_DEPENDENCIES' ,它就由Automake来计算。 自动获取的值是进行了大部分配置替换后的`prog_LDADD' 内容,即删除 了`-l'`-L' 选项。没有进行的配置替换仅仅是 `@LIBOBJS@' and `@ALLOCA@' ;没有进行这些 替换是因为它们不会使生成的`prog_DEPENDENCIES' 含有非法的值。

创建一个库

创建库与创建程序十分类似。在这种情况下,主变量的名字是`LIBRARIES' 。 库可以安装到libdirpkglibdir 之中。

关于如何使用Libtool和主变量`LTLIBRARIES' 创建共享库的详情, 请参见创建共享库

每个`_LIBRARIES' 变量都是需要被创建的库的列表。 例如创建一个名为`libcpio.a' 的库,但并不安装它,你可以写:

noinst_LIBRARIES = libcpio.a

确定那些源代码应该被创建到库中的方式与创建程序的情况完全相同,是通过 变量`_SOURCES' 。需要指出的是,库的名字是规范化的 (参见派生变量是如何命名的 ), 所以对应与`liblob.a'`_SOURCES' 变量对应的 变量名为`liblob_a_SOURCES' ,而不是`liblob.a_SOURCES'

通过使用变量`library_LIBADD' ,可以把额外的对象添加到库中。 这应该由configure 确定的对象使用。再看看cpio:

libcpio_a_LIBADD = @LIBOBJS@ @ALLOCA@

对LIBOBJS和ALLOCA的特别处理

Automake显式地识别对@LIBOBJS@@ALLOCA@ 的使用,并用该信息,以及从 `configure.in' 中派生出的LIBOBJS 文件列表,把适当的源文件自动添加到发布版本中。 (参见需要发布哪些文件 )。 这些源文件还按照依赖跟踪机制进行自动处理,参见自动依赖跟踪

在任何`_LDADD'`_LIBADD' 变量中, @LIBOBJS@@ALLOCA@ 都将被自动识别出来。

创建一个共享库

创建共享库是一件相对复杂的事情。为此,提供了GNU Libtool以使我们 可以按照与平台无关的方式创建共享库(参见Libtool手册 )。

Automake使用Libtool来创建在主变量`LTLIBRARIES' 中声明的库。 每个`_LTLIBRARIES' 变量都是一个需要创建的共享库的列表。 例如,为了创建一个名为`libgettext.a' 的库和它对应的共享库, 并且把它安装到`libdir' ,可以写:

lib_LTLIBRARIES = libgettext.la

需要指出的是:共享库必须 被安装,所以不允许使用 `noinst_LTLIBRARIES'`check_LTLIBRARIES'

对于每个库,变量`library_LIBADD' 包含了需要被添加到共享 库中的额外的libtool对象(`.lo' 文件)。 变量`library_LDFLAGS' 包含了所有附加的libtool选项, 例如`-version-info' 或者`-static'

普通的库可能需要使用@LIBOBJS@ ,而libtool库必须是使用 @LTLIBOBJS@ 。必须这样做是因为libtool所操作的目标文件 并不仅仅是`.o' 。libtool手册包含了关于这个问题的细节。

对于安装在某些目录中的库,automake 将自动提供适当的 `-rpath' 选项。然而,对于那些在配置时刻才能都确定的库 (因而必须在EXTRA_LTLIBRARIES 中给出),automake 并不知道它们最终安装的目录;对于这类库,你必须把 `-rpath' 选项手工地添加到适当的`_LDFLAGS' 变量中去。

详情请参见Libtool手册

创建一个程序时使用的变量

有时有必要知道那个`Makefile' 变量被Automake用于编译; 例如在某些特殊情况下,你可能需要完成你自己的编译任务。

有些变量是从Autoconf中继承而来的;它们是CCCFLAGSCPPFLAGSDEFSLDFLAGSLIBS

还有一些附加的变量是Automake自行定义的:

INCLUDES
一个`-I' 选项的列表。如果你需要包含特殊的目录, 你可以在你的`Makefile.am' 中设置它。 automake 已经自动地提供了一些`-I' 选项。 特别地,它生成`-I$(srcdir)' 和一个指向保存了 `config.h' 的目录的`-I' 选项(如果你已经 使用了AC_CONFIG_HEADER 或者AM_CONFIG_HEADER )。 除了`-I' 以外,INCLUDES 实际上还可以用于添加任何cpp 选项。 例如,有时用它把任意的`-D' 选项传递给编译器。
COMPILE
实际用于编译C源文件的命令。文件名被添加到它的后面以形成完整的命令行。
LINK
实际用于连接C程序的命令。

对Yacc和Lex的支持

Automake对Yacc和Lex有一些特殊的支持。

Automake假定由yacc(或lex)生成的`.c' 文件 是以输入文件名为基础命名的。就是说,对于yacc源文件`foo.y' , automake将认为生成的中间文件是`foo.c' (而不是更加传统的 `y.tab.c' )。

yacc源文件的扩展名被用于确定生成的`C'`C++' 文件的扩展名。使用扩展名`.y' 的文件将被转化成 `.c' 文件;类似地,扩展名`.yy' 转化成 `.cc'

分享到:
评论

相关推荐

    automake最新手册

    #### Automake 使用指南 1. **配置文件**: - `Makefile.am`:包含变量定义和规则的文件,用于生成 `Makefile.in`。 - `configure.ac`:与 Autoconf 配合使用,用于生成 `configure` 脚本。 2. **基本用法**: ...

    Autoconf/Automake配置脚本指南

    ### Autoconf/Automake配置脚本指南 #### 1. 概述 本文档旨在指导开发者如何为自己的程序创建一个基于GNU Autoconf/Automake的配置脚本。使用这一工具链能够有效地帮助开发者构建跨平台的软件项目,尤其是在Linux...

    automake1.13

    在Linux和类UNIX操作系统中,`automake` 是开发者常用的工具,它与`autoconf` 配合使用,帮助创建可移植的源代码发布。`automake-1.13` 是`automake` 的一个特定版本,可能包含了针对该版本的改进、修复和特性。 在...

    automake-1.9.6.tar.gz

    1. `INSTALL`:一份指南,解释如何在目标系统上安装和使用Automake。 2. `NEWS`:列出自上一版本以来的更改和改进。 3. `README`:提供项目的一般信息,包括使用提示和贡献指南。 4. `configure.ac`:这是配置脚本的...

    automake1.11

    automake通常会提供升级指南,帮助用户平滑过渡。 总之,automake 1.11是一个强大的自动化工具,它简化了GNU构建系统的使用,提高了跨平台构建的效率和可靠性。对于大型或复杂的项目,尤其是那些需要高度可移植性的...

    automake中文手册

    这个手册是由王立(Charles)翻译的,为中文用户提供了详细的指南,帮助理解并使用automake。 **automake的核心概念:** 1. **GNU Build System**:automake是GNU构建系统的一部分,与autoconf、libtool等工具配合...

    automake手册

    总体上,Automake手册是一个关于如何使用GNU Automake工具来自动化编译过程的详尽指南,涵盖了从基础到高级的构建策略,帮助开发者创建高效、标准化的软件包构建系统。通过学习这个手册,开发者可以更好地理解和掌握...

    automake官方手册

    总之,Automake作为一款高度自动化且功能丰富的构建工具,不仅简化了Makefile的生成,还提供了丰富的配置选项和最佳实践指南,是任何大型项目不可或缺的构建伙伴。通过深入了解其工作原理和使用技巧,开发者能够显著...

    GNU+Autoconf+Automake+and+Libtool.pdf

    《GNU Autoconf、Automake 和 Libtool》是针对开源软件开发者的必备指南,由Vaughan V. Gary、Ben Elliston、Tom Tromey和Ian Lance Taylor等专家共同编写,旨在帮助开发者掌握这些关键工具,提升开发效率和应用程序...

    automake-1.13.3.tar.gz

    例如,`automake.info`文件(在解压后的automake-1.13.3目录下)包含了详细的用户指南和参考手册。 8. **最佳实践** - 保持Makefile.am简洁明了,避免过于复杂的规则。 - 使用automake的内置宏,如`AM_INIT_...

    automake-1.12.5.tar.gz

    使用Automake,开发者可以轻松地创建符合GNU标准的软件项目,使得用户能够通过简单的`./configure; make; sudo make install`命令来构建和安装软件。这对于开源社区尤其重要,因为它降低了用户参与和贡献的门槛,...

    automake-1.12.6.tar.gz

    在实际项目开发中,`automake` 和 `autoconf` 通常与其他工具(如 `libtool` 和 `pkg-config`)一起使用,以构建复杂的软件项目。这些工具共同为开发者提供了强大的自动化构建环境,减少了手动配置的工作量,提高了...

    automake-1.12.1.tar.gz

    描述中的"automake-1.12.1.tar"可能是原始的未压缩文件名,但通常在下载时,为了减小传输大小,会使用gzip进行压缩,所以实际下载的文件名是"automake-1.12.1.tar.gz"。 在解压"automake-1.12.1.tar.gz"后,你会...

    automake-1.11.3.tar.gz

    2. **运行automake**:使用automake工具处理`Makefile.am`,生成`Makefile.in`。 3. **生成configure脚本**:通常使用`autoconf`工具,根据`configure.ac`文件生成`configure`脚本。 4. **配置项目**:用户在目标...

    automake-1.11.4.tar.gz

    ### 安装和使用 automake 在大多数 Linux 发行版中,automake 可以通过包管理器安装,如 `apt-get`(Ubuntu/Debian)或 `yum`(Fedora/CentOS)。安装完成后,可以在项目目录下运行以下命令: ```bash autoreconf ...

    Autotools.A.Practioner's.Guide.to.GNU.Autoconf.Automake.and.Libtool

    ### Autotools:实践者的指南—GNU Autoconf、Automake与Libtool #### 知识点一:Autotools概述 - **定义**:Autotools是一套用于辅助跨平台软件构建过程的工具集合,主要由GNU Autoconf、Automake与Libtool组成。...

    Autotools_A Practitioner's Guide to GNU Autoconf, Automake, and Libtool

    《Autotools:GNU Autoconf、Automake 和 Libtool 实践指南》是 John Calcote 所著的一本面向软件开发者的教程书,专门讲解了如何使用 GNU Autotools 构建系统。Autotools 是一组工具,包括 Autoconf、Automake 和 ...

    automake-manual-zh:GNU automake 手册的中文翻译版,HTML单页面格式

    《GNU automake 手册中文版》是针对automake工具的详尽指南,旨在帮助开发者理解和使用这个自动化构建系统。automake是GNU项目的一部分,它与autoconf、libtool等工具一起,为C语言为主的软件项目提供了一套自动化的...

    CEDAR 用户使用指南1

    CEDAR 用户使用指南 CEDAR 用户使用指南是基于 OceanBase 0.4.2 版本开发的可扩展的关系数据库,旨在支持数百 TB 的海量数据,数十万 TPS、数百万 QPS 的访问量,并且支持跨行跨表事务。CEDAR 系统中有四个重要的...

Global site tag (gtag.js) - Google Analytics