45fan.com - 路饭网

搜索: 您的位置主页 > 网络频道 > 阅读资讯:怎么样正确使用automake手册?

怎么样正确使用automake手册?

2016-08-26 05:52:09 来源:www.45fan.com 【

怎么样正确使用automake手册?

GNU Automake

For version 1.3, 3 April 1998

David MacKenzie and Tom Tromey
王立 译

目录

  • 介绍
  • 通用性概念
    • 通用操作
    • 深度
    • 严格性
    • 统一命名机制
    • 派生变量是如何命名的
  • 一些实例软件包
    • 一个简单的例子,从起点到终点
    • 一个经典的程序
    • 创建etags和ctags
  • 创建`Makefile.in'
  • 扫描`configure.in'
    • 配置需求
    • Automake能够识别的其它事情
    • 自动生成的aclocal.m4
    • 由Automake支持的Autoconf宏
    • 编写你自己的aclocal宏
  • 顶层`Makefile.am'
  • 创建程序和库
    • 创建一个程序
    • 创建一个库
    • 对LIBOBJS和ALLOCA的特别处理
    • 创建一个共享库
    • 创建一个程序时使用的变量
    • 对Yacc和Lex的支持
    • C++和其它语言
    • 自动de-ANSI-fication
    • 自动的依赖性(dependency)跟踪
  • 其它派生对象
    • 可执行的脚本
    • 头文件
    • 与体系结构无关(Architecture-independent)的数据文件
    • 已创建的源代码
  • 其它GNU工具
    • Emacs Lisp
    • Gettext
    • Guile
    • Libtool
    • Java
  • 创建文档
    • Texinfo
    • Man手册
  • 安装了些什么
  • 清除了些什么
  • 需要发布哪些文件
  • 对测试套件(test suites)的支持
  • 改变Automake的行为
  • 其它规则
    • etags之间的界面
    • 处理新的文件扩展名
  • 条件(Conditionals)
  • --gnu and --gnits的效果
  • --cygnus的效果
  • 什么时候Automake不够用
  • 发布`Makefile.in'
  • 未来的某些想法
  • 索引

@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定义变量PACKAGEVERSIONPACKAGE应该是在捆绑发布的时候使用的包的名称。例如,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'`.y++'转化成`c++'`.yxx'转化成`.cxx';类似地,Lex源文件可以用于生成`C'或者`C++';扩展名 `.l'`.ll'`.l++'`.lxx'都可以被识别。

你不应该在任何`SOURCES'变量中明确地提及中间的(`C'或者`C++')文件;只要列出源文件就可以了。

由yacc(或lex)生成的中间文件将被包含在由它创建的任何发布版本中。这样用户就不需要拥有yacc或lex了。

如果出现了yacc源文件,那么你的`configure.in'必须定义变量`YACC'。完成这个任务最容易的方式是使用宏`AC_PROG_YACC'

相似地,如果出现了lex源文件,那么你的`configure.in' 必须定义变量`LEX'。你可以用宏`AC_PROG_LEX' 来完成这个工作。Automake对lex的支持还要求你使用宏 `AC_DECL_YYTEXT'--automake需要知道 `LEX_OUTPUT_ROOT'的值。

Automake允许在一个程序中使用多个yacc (或lex)源文件。 Automake使用一个称为ylwrap的小程序在子目录中运行 yacc(或者lex)。必须这样做是因为 yacc的输出文件名被修改了,并且并行的make可以同时地处理多于一个的yacc实例。ylwrap和automake一同发布。它应该出现在由`AC_CONFIG_AUX_DIR'给出的目录,如果没有在`configure.in'中给出这个宏,它就应该出现在当前目录中。

对于yacc,仅仅管理锁是不够的。yacc的输出还总是在内部使用相同的符号名,所以不可能把两个yacc解析器(parser)连接到同一个可执行文件中。

我们建议使用如下在gdb中应用的改名方式:

#defineyymaxdepth c_maxdepth
#defineyyparsec_parse
#defineyylexc_lex
#defineyyerrorc_error
#defineyylvalc_lval
#defineyycharc_char
#defineyydebugc_debu

本文地址:http://www.45fan.com/a/question/67651.html
Tags: 手册 GNU automake
编辑:路饭网
关于我们 | 联系我们 | 友情链接 | 网站地图 | Sitemap | App | 返回顶部