当前位置:Linux教程 - Linux - autoconf手册(二)

autoconf手册(二)

创建输出文件。
在``configure.in''的末尾调用本宏一次。参数file...是一个以空格分隔的输出文件的列表;它可能为空。本宏通过从一个输入文件(缺省情况下名为``file.in'')中复制,并替换输出变量的值以创建每个给出的``file''。关于使用输出变量的详情,请参见Makefile中的替换。关于创建输出变量的详情,请参见设定输出变量。如果输出文件所在的目录不存在,本宏将创建该目录(但不会创建目录的父目录)。通常,``Makefile''是按照这种方式创建的,但其他文件,例如``.gdbinit'',也可以这样创建。

如果调用了AC_CONFIG_HEADER、AC_LINK_FILES或者AC_CONFIG_SUBDIRS,本宏也将创建出现在它们的参数中的文件。

一个典型的对AC_OUTPUT调用如下:

AC_OUTPUT(Makefile src/Makefile man/Makefile X/Imakefile)

你可以通过在file之后添加一个用冒号分隔的输入文件列表以自行设定输入文件名。例如:

AC_OUTPUT(Makefile:templates/top.mk lib/Makefile:templates/lib.mk)
AC_OUTPUT(Makefile:templates/vars.mk:Makefile.in:templates/rules.mk)

这样做可以使得你的文件名能够被MS-DOS接受,或者可以把模板文件(boilerplate)添加到文件的开头或者结尾。

如果你给出了extra-cmds,那么这些命令将被插入到``config.status''中以便在``config.status'' 完成了其他的所有处理之后运行extra-cmds。如果给出了init-cmds,它们就被插入 extra-cmds之前,并且在configure中将对它们进行shell变量、命令和反斜线替换。你可以用 init-cmds把变量从configure中传递到extra-cmds。如果调用了 AC_OUTPUT_COMMANDS,在其中给出的命令将紧贴在由本宏给出的命令之前运行。

宏: AC_OUTPUT_COMMANDS (extra-cmds [, init-cmds])
指定在``config.status''末尾运行的附加的shell命令,以及用于初始化来自于configure 的所有变量的shell命令。本宏可以被调用多次。下面是一个不太实际的例子:

fubar=27
AC_OUTPUT_COMMANDS([echo this is extra $fubar, and so on.], fubar=$fubar)
AC_OUTPUT_COMMANDS([echo this is another, extra, bit], [echo init bit])

如果你在子目录中运行make,你应该通过使用make变量MAKE来运行它。 make的大部分版本把MAKE设置成make的程序名以及它所需要的任何选项。(但许多版本并没有把在命令行中设定的变量的值包括进来,因此它们没有被自动地传递。)一些老版本的 make并不设定这个变量。以下的宏使你可以在这些版本上使用它。
宏: AC_PROG_MAKE_SET
如果make预定义了变量MAKE,把输出变量SET_MAKE定义为空。否则,把 SET_MAKE定义成``MAKE=make''。为SET_MAKE调用AC_SUBST。

为了使用这个宏,在每个其他的、运行MAKE的目录中的``Makefile.in''添加一行:

@SET_MAKE@

Makefiles中的替换
发布版本中每个包含了需要被编译或者被安装的文件的目录都应该含有一个文件``Makefile.in'', configure将利用它在那个目录中创建一个``Makefile''。为了创建``Makefile'',configure进行一个简单的变量替换:用configure 为``@variable@''选取的值,在``Makefile.in''中对它们进行替换。按照这种方式被替换到输出文件中的变量被称为输出变量。在configure中,它们是普通的shell变量。为了让configure把特殊的变量替换到输出文件中,必须把那个变量的名字作为调用 AC_SUBST的参数。其他变量的任何``@variable@''都保持不变。关于使用AC_SUBST创建输出变量的详情,请参见设定输出变量。

使用configure脚本的软件应该发布文件``Makefile.in'',而不是``Makefile'';这样,用户就可以在编译它之前正确地为本地系统进行配置了。

关于应该把哪些东西放入``Makefile''的详情,请参见GNU编码标准中的``Makefile惯例''。

预定义输出变量
有些输出变量是由Autoconf宏预定义的。一部分Autoconf宏设置一些附加的输出变量,这些变量在对这些宏的描述中被说明。关于输出变量的完整列表,参见输出变量索引。下面是每个预定义变量所包含的内容。关于变量名以``dir''结尾的变量,参见GNU编码标准中的 ``为安装目录而提供的变量''。
变量: bindir
用于安装由用户运行的可执行文件的目录。
变量: configure_input
一个用于说明文件是由configure自动生成的,并且给出了输入文件名的注释。 AC_OUTPUT在它创建的每个``Makefile''文件的开头添加一个包括了这个变量的注释行。对于其他文件,你应该在每个输入文件开头处的注释中引用这个变量。例如,一个输入shell脚本应该以如下行开头:

#! /bin/sh
# @configure_input@

这一行的存在也提醒了人们在编辑这个文件之后需要用configure进行处理以使用它。

变量: datadir
用于安装只读的与结构无关的数据的目录。
变量: exec_prefix
与结构有关的文件的安装前缀。
变量: includedir
用于安装C头文件的目录。
变量: infodir
用于安装Info格式文档的目录。
变量: libdir
用于安装目标代码库的目录。
变量: libexecdir
用于安装由其他程序运行的可执行文件的目录。
变量: localstatedir
用于安装可以被修改的单机数据的目录。
变量: mandir
用于安装man格式的文档的顶层目录。
变量: oldincludedir
用于安装由非gcc编译器使用的C头文件的目录。
变量: prefix
与结构无关的文件的安装前缀。
变量: sbindir
用于安装由系统管理员运行的可执行文件的目录。
变量: sharedstatedir
用于安装可以修改的、与结构无关的数据的目录。
变量: srcdir
包含了由``Makefile''使用的源代码的目录。
变量: sysconfdir
用于安装只读的单机数据的目录。
变量: top_srcdir
包的顶层源代码目录。在目录的顶层,它与srcdir相同。
变量: CFLAGS
为C编译器提供的调试和优化选项。如果在运行configure时,没有在环境中设置它,就在你调用AC_PROG_CC的时候设置它的缺省值(如果你没有调用AC_PROG_CC,它就为空)。 configure在编译程序以测试C的特征时,使用本变量。
变量: CPPFLAGS
为C预处理器和编译器提供头文件搜索目录选项(``-Idir'')以及其他各种选项。如果在运行 configure时,在环境中没有设置本变量,缺省值就是空。configure在编译或者预处理程序以测试C的特征时,使用本变量。
变量: CXXFLAGS
为C++编译器提供的调试和优化选项。如果在运行configure时,没有在环境中设置本变量,那么就在你调用AC_PROG_CXX时设置它的缺省值(如果你没有调用AC_PROG_CXX,它就为空)。 configure在编译程序以测试C++的特征时,使用本变量。
变量: FFLAGS
为Fortran 77编译器提供的调试和优化选项。如果在运行configure时,在环境中没有设置本变量,那么它的缺省值就在你调用AC_PROG_F77时被设置(如果你没有调用AC_PROG_F77,它就为空)。 configure在编译程序以测试Fortran 77的特征时,使用本变量。
变量: DEFS
传递给C编译器的``-D''选项。如果调用了AC_CONFIG_HEADER,configure就用 ``-DHAVE_CONFIG_H''代替``@DEFS@''(参见配置头文件)。在configure进行它的测试时,本变量没有被定义,只有在创建输出文件时候才定义。关于如何检查从前的测试结果,请参见设定输出变量。
变量: LDFLAGS
为连接器提供的Stripping(``-s'')选项和其他各种选项。如果在运行configure时,在环境中没有设置本变量,它的缺省值就是空。 configure在连接程序以测试C的特征时使用本变量。
变量: LIBS
传递给连接器的``-l''和``-L''选项。

创建目录
你可以支持从一个软件包的一份源代码拷贝中为多种结构同时进行编译的功能。为每种结构生成的目标文件都在它们自己的目录中储存。

为了支持这个功能,make用变量VPATH来寻找储存在源代码目录中的文件。 GNU make和其他大部分近来的make程序都可以这样做。老版本的make 程序不支持VPATH;在使用它们的时候,源代码必须与目标代码处于同一个目录。

为了支持VPATH,每个``Makefile.in''文件都应该包含下列两行:

srcdir = @srcdir@
VPATH = @srcdir@

不要把VPATH设置成其他变量的值,比如说``VPATH = $(srcdir)'',这是因为某些版本的make并不对VPATH的值进行变量替换。

在configure生成``Makefile''的时候,它用正确的值对srcdir进行替换。

除非在隐含规则中,不要使用make变量$<,它将被展开成到源代码目录的文件的路径(通过VPATH找到的)。(诸如``.c.o''的隐含规则用于说明如何从``.c'' 文件创建``.o''文件)有些版本的make在隐含规则中不设置$<;它们被展开成空值。

``Makefile''命令行总是应该通过使用前缀``$(srcdir)/''来引用源代码文件。例如:

time.info: time.texinfo
    $(MAKEINFO) $(srcdir)/time.texinfo

自动地重新创建
你可以在包的顶层目录中的``Makefile.in''文件中添加如下的规则,以使得在你更新了配置文件之后可以自动地更新配置信息。这个例子包括了所有可选的文件,例如``aclocal.m4''和那些与配置头文件有关的文件。从``Makefile.in''规则中忽略所有你的所不需要的文件。

因为VPATH机制的限制,应该包含``${srcdir}/''前缀。

在重新创建不改变``config.h.in''和``config.h''的内容的情况下,就不会改变这两个文件的时间标记,因此需要``stamp-''文件。这个特征避免了不必要的重新编译工作。你应该把文件``stamp-h.in'' 包含在你的包的发布中,以便make能够把``config.h.in''看作是更新了的文件。在一些老的BSD系统中,touch或者任何可能导致空文件的命令不会更改时间标记,所以使用诸如echo 之类的命令。

${srcdir}/configure: configure.in aclocal.m4
    cd ${srcdir} && autoconf

# autoheader might not change config.h.in, so touch a stamp file.
${srcdir}/config.h.in: stamp-h.in
${srcdir}/stamp-h.in: configure.in aclocal.m4 acconfig.h
  config.h.top config.h.bot
    cd ${srcdir} && autoheader
    echo timestamp > ${srcdir}/stamp-h.in

config.h: stamp-h
stamp-h: config.h.in config.status
    ./config.status

Makefile: Makefile.in config.status
    ./config.status

config.status: configure
    ./config.status --recheck

此外,你应该把``echo timestamp > stamp-h''作为extra-cmds参数传递给AC_OUTPUT,以便``config.status''能够确认``config.h''是更新了的。关于AC_OUTPUT的详情,请参见 创建输出文件。

关于处理与配置相关的依赖性问题的更多例子,请参见重新创建一个配置。

配置头文件
在包测试的C预处理器符号比较多的时候,用于把``-D''传递给编译器的命令行就会变得很长。这导致了两个问题。一个是通过观察寻找make输出中的错误变得困难了。更严重的是,命令行可能超过某些操作系统的长度限制。作为把``-D''选项传递给编译器的替代办法,configure 脚本可以创建一个包含了``#define''指令的C头文件。宏AC_CONFIG_HEADER 选择了这种输出。它应该在AC_INIT之后立即调用。

包应该在引入其他任何头文件之前``#include''配置头文件,以防止出现声明中的不一致性(例如,配置头文件可能重定义了const)。使用``#include '' 并且把选项``-I.''(或者是``-I..'';或者是任何包含``config.h'' 的目录)传递给C编译器,而不是使用``#include ""config.h""''。按照这种方式,即使源代码自行进行配置(可能是创建发布版本),其他创建目录也可以在没有找到``config.h''的情况下,从源代码目录进行配置。
宏: AC_CONFIG_HEADER (header-to-create ...)
使得AC_OUTPUT创建出现在以空格分隔的列表header-to-create中的文件,以包含C预处理器#define语句,并在生成的文件中用``-DHAVE_CONFIG_H'' ,而不是用DEFS的值,替换``@DEFS@''。常用在header-to-create 中的文件名是``config.h''。

如果header-to-create给出的文件已经存在并且它的内容和AC_OUTPUT将要生成的内容完全一致,这些文件就保持不变。这样做就使得对配置的某些修改不会导致对依赖于头文件的目标文件进行不必要的重新编译。

通常输入文件被命名为``header-to-create.in'';然而,你可以通过在header-to-create 之后添加由冒号分隔的输入文件列表来覆盖原输入文件名。例:

AC_CONFIG_HEADER(defines.h:defines.hin)
AC_CONFIG_HEADER(defines.h:defs.pre:defines.h.in:defs.post)

这样做使得你的文件名能够被MS-DOS所接受,或者可以把模板(boilerplate)添加到文件的开头和/或结尾。
配置头文件模板
你的发布版本应该包含一个如你所望的最终的头文件那样的模板文件,它包括注释、以及#define 语句的缺省值。例如,假如你的``configure.in''进行了下列调用:

AC_CONFIG_HEADER(conf.h)
AC_CHECK_HEADERS(unistd.h)

那么你就应该在``conf.h.in''中包含下列代码。在含有``unistd.h''的系统中,configure应该把0改成1。在其他系统中,这一行将保持不变。

/* Define as 1 if you have unistd.h. */
#define HAVE_UNISTD_H 0

如果你的代码使用#ifdef而不是#if来测试配置选项,缺省值就可能是取消对一个变量的定义而不是把它定义成一个值。在含有``unistd.h''的系统中,configure将修改读入的第二行 ``#define HAVE_UNISTD_H 1''。在其他的系统中,(在系统预定义了那个符号的情况下) configure将以注释的方式排除这一行。

/* Define if you have unistd.h. */
#undef HAVE_UNISTD_H

用autoheader创建``config.h.in''
程序autoheader可以创建含有C的``#define''语句的模板文件以供configure使用。如果``configure.in''调用了AC_CONFIG_HEADER(file),autoheader就创建 ``file.in'';如果给出了多文件参数,就使用第一个文件。否则,autoheader就创建 ``config.h.in''。

如果你为autoheader提供一个参数,它就使用给出的文件而不是``configure.in'',并且把头文件输出到标准输出中去,而不是输出到``config.h.in''。如果你把``-''作为参数提供给autoheader ,它就从标准输入中,而不是从``configure.in''中读出,并且把头文件输出到标准输出中去。

autoheader扫描``configure.in''并且找出它可能要定义的C预处理器符号。它从一个名为 ``acconfig.h''的文件中复制注释、#define和#undef语句,该文件与Autoconf一同发布并且一同安装。如果当前目录中含有``acconfig.h''文件,它也会使用这个文件。如果你用AC_DEFINE 定义了任何附加的符号,你必须在创建的那个``acconfig.h''文件中包含附加的符号。对于由 AC_CHECK_HEADERS、AC_CHECK_FUNCS、AC_CHECK_SIZEOF或者 AC_CHECK_LIB定义的符号,autoheader生成注释和#undef语句,而不是从一个文件中复制它们,这是因为可能的符号是无限的。

autoheader创建的文件包含了大部分#define和#undef语句,以及相关的注释。如果``./acconfig.h''包含了字符串``@TOP@'',autoheader就把在包含``@TOP@'' 的行之前的所有行复制到它生成的文件的开头。相似地,如果``./acconfig.h''包含了字符串``@BOTTOM@'', autoheader就把那一行之后的所有行复制到它生成的文件的末尾。这两个字符串的任何一个都可以被忽略,也可以被同时忽略。

产生相同效果的另一种办法是在当前目录中创建文件``file.top''(通常是``config.h.top'')和/或文件``file.bot''。如果它们存在,autoheader就把它们分别复制到它的输出的开头和末尾。不鼓励使用它们是因为它们的文件名含有两个点,并因此不能在MS-DOS中储存;它们在目录中多创建了两个文件。但如果你给出选项``--localdir=dir''以使用在其他目录中的``acconfig.h'',它们就为你提供了一种把定制的模板(boilerplate)放入各个独立的``config.h.in''中的方式。

autoheader接受如下选项:

--help
-h
打印对命令行选项的概述并且退出。
--localdir=dir
-l dir
在目录dir中,而不是在当前目录中,寻找包文件``aclocal.m4''和``acconfig.h'' (但不包括``file.top''和``file.bot'')。
--macrodir=dir
-m dir
在目录dir中寻找安装的宏文件和``acconfig.h''。你还可以把环境变量AC_MACRODIR 设置成一个目录;本选项将覆盖该环境变量。
--version
打印Autoconf的版本号并且退出。
在子目录中配置其它包
在大多数情况下,调用AC_OUTPUT足以在子目录中生成``Makefile''。然而,控制了多于一个独立包的configure脚本可以使用AC_CONFIG_SUBDIRS来为每个子目录中的其他包运行 configure脚本。
宏: AC_CONFIG_SUBDIRS (dir ...)
使得AC_OUTPUT在每个以空格分隔的列表中给出的子目录dir中运行configure。如果没有发现某个给出的dir,不会作为错误报告,所以一个configure脚本可以配置一个大的源代码树中出现的任何一个部分。如果在给出的dir中包含了``configure.in'',但没有包含 configure,就使用由AC_CONFIG_AUXDIR找到的Cygnus configure脚本。

用与本configure脚本完全相同的命令行参数调用子目录中的configure脚本,如果需要,会有较小的修改(例如,为缓冲文件或者源代码目录调整相对路径)。本宏还把输出变量subdirs设置成目录列表``dir...''。``Makefile''规则可以使用该变量以确定需要进入那些子目录。这个宏可以多次调用。

缺省的前缀
在缺省状态下,configure把它所安装的文件的前缀设置成``/usr/local''。 configure的用户可以通过选项``--prefix''和``--exec-prefix''选择一个不同的前缀。有两种方式修改缺省的行为:在创建configure时,和运行configure时。

有些软件包在缺省情况下可能需要安装到``/usr/local''以外的目录中。为此,使用宏AC_PREFIX_DEFAULT。
宏: AC_PREFIX_DEFAULT (prefix)
把缺省的安装前缀设置成prefix,而不是``/usr/local''。

对于用户来说,让configure根据它们已经安装的相关程序的位置来猜测安装前缀,可能会带来方便。如果你希望这样做,你可以调用AC_PREFIX_PROGRAM。
宏: AC_PREFIX_PROGRAM (program)
如果用户没有给出安装前缀(使用选项``--prefix''),就按照shell的方式,在PATH中寻找 program,从而猜出一个安装前缀。如果找到了program,就把前缀设置成包含program 的目录的父目录;否则,就不改变在``Makefile.in''中给定的前缀。例如,如果program是 gcc,并且PATH包括了``/usr/local/gnu/bin/gcc'',就把前缀设置为 ``/usr/local/gnu''。


configure中的版本号
以下的宏为configure脚本管理版本号。使用它们是可选的。
宏: AC_PREREQ (version)
确保使用的是足够新的Autoconf版本。如果用于创建configure的Autoconf的版本比version 要早,就在标准错误输出打印一条错误消息并不会创建configure。例如:

AC_PREREQ(1.8)

如果你的``configure.in''依赖于在不同Autoconf版本中改变了的、不明显的行为,本宏就是有用的。如果它仅仅是需要近来增加的宏,那么AC_PREREQ就不太有用,这是因为程序autoconf已经告诉了用户那些宏没有被找到。如果``configure.in''是由一个在提供AC_PREREQ之前的更旧的 Autoconf版本处理的,也会发生同样的事。

宏: AC_REVISION (revision-info)
把删除了任何美元符或者双引号的修订标记(revision stamp)复制到configure脚本中。本宏使得你的从``configure.in''传递到configure的修订标记不会在你提交(check in) configure的时候被RCS或者CVS修改。你可以容易地决定一个特定的configure 对应与``configure.in''的哪个修订版。

把本宏放在AC_INIT之前是个好主意,它可以使修订号接近``configure.in''和configure 的开头。为了支持你这样做,AC_REVISION就像configure通常作的那样,以 ``#! /bin/sh''开始它的输出。

例如,在``configure.in''中这一行为:

AC_REVISION($Revision: 1.30 $)dnl

在configure中产生了:

#! /bin/sh
# From configure.in Revision: 1.30