创建configure脚本

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

由Autoconf生成的配置脚本通常被称为configure。在运行的时候,configure 创建一些文件,在这些文件中以适当的值替换配置参数。由configure创建的文件有:

一个或者多个'Makefile'文件,在包的每个子目录中都有一个(参见 Makefile中的替换 )

有时创建一个C头文件,它的名字可以被配置,该头文件包含一些#define命令 (参见 配置头文件 )

一个名为'config.status'的shell脚本,在运行时,它将重新创建上述文件。 (参见 重新创建一个配置 )

一个名为'config.cache'的shell脚本,它储存了许多测试的运行结果 (参见 缓存文件 )

一个名为'config.log'的文件,它包含了由编译器生成的许多消息,以便于 在configure出现错误时进行调试。

为了使用Autoconf创建一个configure脚本,你需要编写一个Autoconf的输入文件 'configure.in'并且对它运行autoconf。如果你自行编写了特征测试以补充 Autoconf所提供的测试,你可能还要编写一个名为'aclocal.m4'的文件和一个名为 'acsite.m4'的文件。如果你使用了包含#define指令的C头文件,你可能 还要编写'acconfig.h',并且你需要与软件包一同发布由Autoconf生成的文件 'config.h.in'。

下面是一个说明了在配置中使用的文件是如何生成的图。运行的程序都标以后缀'*'。 可能出现的文件被方括号 '[]')括起来。autoconf和autoheader 还读取安装了的Autoconf宏文件(通过读取'autoconf.m4')。

在准备发布软件包的过程中使用的文件:

你的源文件 --> [autoscan*] --> [configure.scan] --> configure.in

configure.in --. .------> autoconf* -----> configure+---+[aclocal.m4] --+ '---. [acsite.m4] ---' +--> [autoheader*] -> [config.h.in][acconfig.h] ----. +-----'[config.h.top] --+[config.h.bot] --'Makefile.in -------------------------------> Makefile.in

在配置软件包的过程中使用的文件:

.-------------> config.cache configure* ------------+-------------> config.log [config.h.in] -. v .-> [config.h] -.+--> config.status* -+ +--> make*Makefile.in ---' '-> Makefile ---'

编写、configure.in'

为了为软件包创建configure脚本,需要编写一个名为'configure.in' 的文件,该文件包含了对那些你的软件包需要或者可以使用的系统特征进行测试的Autoconf宏的调用。 现有的Autoconf宏可以检测许多特征 对于它们的描述可以参见 现有的测试 。 对于大部分其他特 征,你可以使用Autconf模板宏以创建定制的测试 关于它们的详情,参见 编写测试 。对于特别古怪或者特殊的特征,'configure.in'可能需要包含一些手工编写的shell命令。程序autoscan可以为你编写'configure.in' 开个好头(详情请参见 用 autoscan 创

建'configure.in')。

除了少数特殊情况之外,在'configure.in'中调用Autoconf宏的顺序并不重要。 在每个'configure.in'中,必须在进行任何测试之间包含一个对AC—INIT的调用, 并且在结尾处包含一个对AC—OUTPUT的调用(参见 创建输出文件 )。 此外,有些宏要求其他的宏在它们之 前被调用,这是因为它们通过检查某些变鼠在前面设定的值以决定作些什么。 这些宏在独立的说明中给出(参见 现有的测试 ),而且如果没有 按照顺序调用宏,在生成configure时会向你发出警告。

为了提高一致性,下面是调用Autoconf宏的推荐顺序。通常,在本列表中靠后的项目依赖于表中靠前的项目。 例如,库函数可能受到typedefs和库的影响。

AC—INIT(file) checks for programs checks for librarieschecks for header files checks for typedefschecks for structureschecks for compiler characteristics checks for library functions checks for system services AC—OUTPUT([file...])

最好让每个宏调用在'configure.in'中占据单独的一行。大部分宏并不添加额外的新行 它们依赖于在宏调用之后的新行以结束命令。这种方法使得生成的configure脚本 在不必添加大鼠的空行的情况下比较容易阅读。在宏调用的同一行中设置shell变鼠通常是安全的,这是因为shell允许出现没有用新行间隔的赋值。

在调用带参数的宏的时候,在宏名和左括号之间不能出现任何空格。如果参数被m4 引用字符'['和']'所包含,参数就可以多于一行。如果你有一个长行, 比如说一个文件名列表,你通常可以在行的结尾使用反斜线以便在逻辑上把它与下一行进行连接 (这是由shell实现 的,Autoconf对此没有进行任何特殊的处理)。

有些宏处理两种情况:如果满足了某个给定的条件就做什么,如果没有满足某个给定的条件就做什么。 在有些地方,你可能希望在条件为真的情况下作些事,在为假时什么也不作。反之亦然。为了忽略 为真的情况,把空值作为参数action—if—found传递给宏。为了忽略为假的情况,可以 忽略包括前面的逗号在内的宏的参数action—if—not—found。

你可以在文件'configure.in'中添加注释。注释以m4预定义宏dnl 开头,该宏丢弃在下一个新行之前的所有文本。这些注释并不在生成的configure脚本中 出现。例如,把下面给出的行作为文件'configure.in'的开头是有好处的:

dnl Process this file with autoconf to produce a configure script.

用autoscan创建、configure.in'

程序autoscan可以帮助你为软件包创建'configure.in'文件。如果在命令行中给出了目录, autoscan就在给定目录及其子目录树中检查源文件,如果没有给出目录,就在当前目录及其子目录树中 进行检查。它搜索源文件以寻找一般的移植性问题并创建一个文

件'configure.scan',该文件就是软件包 的'configure.in'预备版本。

在把'configure.scan'改名为'configure.in'之前,你应该手工地检查它 它可能需要一些调整。 autoscan偶尔会按照相对于其他宏的错误的顺序输出宏,为此autoconf将给出警告 你需要 手工地移动这些宏。还有,如果你希望包使用一个配置头文件,你必须添加一个对AC—CONFIG—HEADER的调用。 (参见 配置头文件 )。可能你还必须在你的程序中修改或者添加一些#if 指令以使得程序可以

与Autoconf合作。(关于有助于该工作的程序的详情,参见 用ifnames列举条件)。

autoscan使用一些数据文件,它们是随发布的Autoconf宏文件一起安装的,以便当它在包中的源文件中发现 某些特殊符号时决定输出那些宏。这些文件都具有相同的格式。每一个都是由符号、空白和在符号出现时应该输出的Autoconf 宏。以'#'开头的行是注释。

只有在你安装了Perl的情况下才安装autoscan。 autoscan接受如下选项:

--help

打印命令行选项的概述并且退出。

--macrodir=dir

在目录dir中,而不是在缺省安装目录中寻找数据文件。你还可以把环境变鼠AC—MACRODIR设置成 一个目录 本选项将覆盖该环境变鼠。

--verbose

打印它检查的文件名称以及在这些文件中发现的可能感兴趣的符号。它的输出可能很冗长。

--version

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

用ifnames列举条件

在为一个软件包编写'configure.in'时,ifnames可以提供一些帮助。它打印出包已经在C预处理条件 中使用的标识符。如果包已经被设置得具备了某些可移植性,该程序可以帮助你找到configure所需要进行 的检查。它可能有助于补足由autoscan生成

的'configure.in'中的某些缺陷。 (参见 用 autoscan 创建 'configure.in')。

ifnames扫描所有在命令行中给出的C源代码文件(如果没有给出,就扫描标准输入)并且把排序后的、由 所有出现在这些文件中

的#if、#elif、#ifdef或者#ifndef 命令中的标识符列表输出到标准输出中。它为每个标识符输出单独的一行,行中标识符之后是一个由空格分隔的、使用 了该标识符的文件名列表。

ifnames接受如下选项:--help-h 打印命令行选项的概述并且退出。--macrodir=dir-m dir

在目录dir中,而不是缺省安装目录中寻找Autoconf宏文件。仅仅被用于获取版本号。 你还可以把环境变鼠AC—MACRODIR设置成一个目录 本选项将覆盖该环境变鼠。

--version

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

用autoconf创建configure

为了从'configure.in'生成configure,不带参数地运行程序autoconf。 autoconf用使用Autoconf宏的m4宏处理器处

理'configure.in'。 如果你为autoconf提供了参数,它读入给出的文件而不是'configure.in'并且 把配置脚本输出到标准输出而不是configure。如果你给autoconf以参数'-', 它将从标准输入,而不是'configure.in'中读取并且把配置脚本输出到标准输出。

Autoconf宏在几个文件中定义。在这些文件中,有些是与Autconf一同发布的 autoconf首先读入它们。 而后它在包含了发布的Autoconf宏文件的目录中寻找可能出现的文件'acsite.m4',并且在当前目录中寻找 可能出现的文件'aclocal.m4'。这些文件可以包含你的站点的或者包自带的Autoconf宏定义(详情请参见 编写宏)。如果宏在多于一个由autoconf读入了的文件中被 定义,那么后面的定义将覆盖前面的定义。

autoconf接受如下参数:--help-h 输出命令行选项的概述并且退出。--localdir=dir-l dir

在目录dir中,而不是当前目录中寻找包文件'aclocal.m4'。

--macrodir=dir-m dir

在目录dir中寻找安装的宏文件。你还可以把环境变鼠AC—MACRODIR设置成 一个目录 本选项将覆盖该环境变鼠。

--version

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

用autoreconf更新configure脚本

如果你有大鼠由Autoconf生成的configure脚本,程序autoreconf可以保留你的一些工作。 它重复地运行autoconf(在适当的情况下还运行autoheader)以重新创建以当前目录为根 的目录树的Autoconf configure脚本和配置头文件。在缺省情况下,它只重新创建那些比对应的 'configure.in'或者(如果出现)'aclocal.m4'要旧的文件。由于在文件没有被改变的情况下, autoheader并不改变它的输出文件的时间标记(timestamp)。这是为了使工作鼠最小化,修改时间标记是不必要的。 如果你安装了新版本的Autoconf,你可以以 选项'--force'调用autoreconf而重新创建 所有的文件。

如果你在调用autoreconf时给出选项'--macrodir=dir'或者 '--localdir=dir',它将把它们传递给autoconf和autoheader (相对路径将被正确地调整)。

在同一个目录树中,autoreconf不支持两个目录作为同一个大包的一部分(共享'aclocal.m4'和 'acconfig.h'),也不支持每个目录都是独立包(每个目录都有它们自己的'aclocal.m4'和 'acconfig.h')。 如果你使用了'--localdir',它假定所有的目录都是同一个包的一部分。如果你没有使用 '--localdir',它假定每个目录都是一个独立的包,这条限制在将来可能被取消。

关于在configure脚本的源文件发生变化的情况下自动地重新创建它们的'Makefile'规则的细节, 参见自动地重新创建。这种方法正确地处理了配置头文件模板的时间标记,但并不 传递'--macrodir=dir'或者'--localdir=dir'。autoreconf接受如下选项:--help-h 打印命令行选项的概述并且退出。--force-f 即使在'configure'脚本和配置头文件比它们的输入文件('configure.in',如果出现 了'aclocal.m4',也包括它)更新的时候,也要重新创建它们。--localdir=dir-l dir让autoconf和autoheader在目录dir中,而不是在每个包含'configure.in' 的目录中寻找包文件'aclocal.m4'和(仅指autoheader)'acconfig.h' (但不包括'file.top'和'file.bot')。--macrodir=dir-m dir

在目录dir中,而不是缺省安装目录中寻找Autoconf宏文件。你还可以把环境变鼠 AC—MACRODIR设置成一个目录 本选项将覆盖该环境变鼠。

--verbose

打印autoreconf运行autoconf(如果适当,还有autoheader) 的每个目录的目录名。

--version

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