在包测试的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.m4acconfig.h (但不包括file.topfile.bot)。

--macrodir=dir
-m dir

在目录dir中寻找安装的宏文件和acconfig.h。你还可以把环境变量AC_MACRODIR 设置成一个目录;本选项将覆盖该环境变量。

--version

打印Autoconf的版本号并且退出。