初始化和输出文件

优质
小牛编辑
134浏览
2023-12-01

Autoconf生成的configure脚本需要一些关于如何进行初始化,诸如如何寻找包的源文件,的信息 以及如何生成输出文件的信息。本节叙述如何进行初始化和创建输出文件。

寻找configure的输入文件

所有configure脚本在作任何其他事情之前都必须调用AC—INIT。此外唯一必须调用的宏是 AC—OUTPUT(参见 创建输出文件 )。 宏: AC_INIT unique—file—in—source—dir)

处理所有命令行参数并且寻找源代码目录。unique—file—in—source—dir是一些在包的源代码目录中文件 configure在目录中检

查这些文件是否存在以确定该目录是否包含源代码。 入们可能偶尔会用'--srcdir'给出错误的目录 这是一种安全性检查。 详情请参见 运行 configure 脚本 。

对于需要手工配置或者使用install程序的包来说,虽然在缺省源代码位置在大部分情况 下看起来是正确的,包还是可能需要通过调用AC—CONFIG—AUX—DIR来告诉 configure到那里去寻找一些其他的shell脚本。

宏 : AC_CONFIG_AUX_DIR dir)

在目录dir中使用'install-sh'、'config.sub'、'config.guess'和 Cygnus configure配置脚本。它们是配置中使用的辅助文件。dir既可以是绝对路径, 也可以是相对于'飞rcdir'的相对路径。缺省值是在'飞rcdir'或者 '飞rcdir/..'或者'飞rcdir/../..'中首先找到'install-sh' 的目录。不对其他文件进行检查,以便使AC—PROG—INSTALL不会自动地发布其他

辅助文件。它还要 检查'install.sh',但因为有些make程序包含了在没有'Makefile'的情况下 从'install.sh'中创建'install'的规则,所以那个名字过时了。

创建输出文件

每个Autoconf生成的configure脚本必须以对AC—OUTPUT的调用结尾。它是一个创建 作为配置结果的'Makefile'以及其他一些可能的文件的宏。此外唯一必须调用的宏是AC—INIT (参见 寻找 configure 的输入文件 )。

宏: AC_OUTPUT [file... [, extra—cmds [, init—cmds]]])

创建输出文件。在'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=27AC—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.botcd ${srcdir} && autoheaderecho timestamp > ${srcdir}/stamp-h.inconfig.h: stamp-hstamp-h: config.h.in config.status./config.statusMakefile: Makefile.in config.status./config.statusconfig.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 <config.h>' 并且把选项'-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'。