Autoconf学习笔记

来源:互联网 发布:汉邦尚品 知乎 编辑:程序博客网 时间:2024/05/19 13:09

Autoconf介绍

Autoconf是一个用于产生shell脚本来自动配置软件源码包的M4宏扩展包。这些脚本可以适应众多的类UNIX系统源码包而不需要用户手动干预。Autoconf通过模板文件以M4宏调用方式为每个源码包创建一个配置脚本,这个模板文件列出了源码包可以使用的操作系统特性。     

使用Autoconf产生脚本需要GUN M4工具。在配置Autoconf前,需要先安装GUN M4(至少是1.4.6版本,推荐1.4.13及其以后的版本),这样Autoconf的配置脚本才能找到它。通过Autoconf产生的配置脚本是自包含的,因此,他们的使用者并不一定要有Autoconf(或者GUN M4)。

下载Autoconf

GUN Autoconf工具的发布版本可以在http://ftp.gun.org/gun/autoconf/[http]以及ftp://ftp.gun.org/gun/autoconf[ftp]上找到。Autoconf的使用手册在http://www.gun.org/software/autoconf/manual上找到。

创建configure脚本

由Autoconf产生的配置脚本被称作configure。当运行configure时,它会创建多个文件,并由合适的值替换配置参数。configure创建的文件如下:

  1. 一个或多个Makefile文件,通常源码包的一个子目录拥有一个Makefile文件。
  2. 可选择的,一个C头文件,它的名字是可配置的,包含#define宏指令。
  3. 一个config.status的shell脚本文件,当运行时,重新创建上面的文件。
  4. 一个可选的通常叫做config.cache文件(当使用configure–config-cache时创建),它保存许多测试的运行结果。
  5. 一个config.log的日志文件,它包含编译器产生的消息,当configure出错时,可用来帮助调试。

为了使用Autoconf创建configure文件,需要编写Autoconf输入文件configure.ac(或者configrue.in)并运行在它之上autoconf。如果你编写自己的功能测试来补充Autoconf,你可能需要编写名为aclocal.m4和acsite.m4的文件。如果你使用C头文件来保护#define指令,你可能需要运行autoheader,你可以将生成的config.h.in文件包含在源码包中。

编写configure.ac

为了为每个软件包产生一个configure脚本,需要创建一个名为configure.ac的文件,该文件包含用于测试软件包需要或者可能使用到的系统特性的Autoconf宏调用。现有的Autoconf宏调用包含许多的特性;参考第五章现有的测试。对于其他的特性,可以使用Autoconf模板宏产生自动检测;参考第六章编写测试。对于棘手或者专业的特性,configure.ac可能需要包含一些手写的shell命令;参考第十一章可移植shell编程。autoscan可以为你提供一个编写configure.ac好的开始(参看第3.2部分autoscan调用)。

 早期版本的Autoconf命令使用configure.in,这可能会使人产生疑惑(工具所处理的文件并不是由文件后缀名来描述的),这容易与config.h.in等文件产生混淆(.in意味着是由configure来处理的)。目前推荐使用configure.ac。

Autoconf语言

Autoconf语言不同于其他计算机编程语言,因为它将代码视作明文文本。然而,在C语言中,数据和指令有不同的语义地位,在Autoconf中,他们的地位是相同的。因此,我们需要一种方法用于区别字符串和文本扩展:方括号。

 当调用含有参数的宏是,一定不能在宏名称和右括号前包含任何空白字符。

AC_INIT ([oops], [1.0]) # incorrectAC_INIT([hello], [1.0]) # good

参数应该位于封闭的方括号之间,并且由逗号隔开。除非在方括号中,否则参数中的任何空白或者换行都将被忽略。你应该总是将包含宏名称、逗号、圆括号或者包含空白字符和换行的参数使用方括号括起来。这条规则适用于递归地对每个宏调用,包括来自其他宏的宏调用。参看第八章M4编程。

例如:

AC_CHECK_HEADER([stdio.h],                [AC_DEFINE([HAVE_STDIO_H],[1],                   [Defeine to 1 if you have<stdio.h>.])],                [AC_MSG_ERROR([sorry, can’t doanything for you])])
上面的引用是正确的。你也可以安全的简化上面的引用:

 AC_CHECK_HEADER([stdio.h],

                [AC_DEFINE([HAVE_STDIO_H], 1,                   [Defeine to 1 if you have <stdio.h>.])],                [AC_MSG_ERROR([sorry, can’t do anything for you])])

因为1并不包含宏调用。AC_MSG_ERROR的参数必须括起来;否则,逗号就被解释为参数分隔符。同样的AC_CHECK_HEADER的第二个和第三个参数也必须括起来,因为它们包含宏调用。“HAVE_STDIO_H“、“stdio.h”h 和“Define to 1 if you have <stdio.h>.”这三个参数可以不用括起来。但是如果你定义了 “Define”或者“stdio”宏,那么他们需要被括起来。谨慎的Autoconf用户总是使用括号,但是多数Autoconf认为这种预防措施非常烦人,并会将上面的重写为下面的形式:

AC_CHECK_HEADER(stdio.h,                [AC_DEFINE(HAVE_STDIO_H, 1,                   [Defeine to 1 if you have <stdio.h>.])],                [AC_MSG_ERROR([sorry, can’t do anything for you])])
只要你采用良好的命名约定并且没有定义类似于“HAVE_STDIO_H”,“stdio”或者“h”这样的宏,那么这就是安全的。尽管省略“Define to 1 if you have <stdio.h>.”的括号在此处是安全的,但并不建议这样做,因为消息字符串可能无意中会包含逗号。

 在某些情况下,你可能不得不使用类似于宏调用的文本。在这种情况下,即使它不是作为宏调用的参数,你也必须使用方括号将其括起来。例如,configure.ac中的下面两种方法都可以保护你的脚本,假设autoconf在之前添加过AC_DC宏:

echo “Hard rock was here!     --[AC_DC]”[echo “Hard rock was here!    --AC_DC”]
它们在configure之后的结果为:

echo “Hard rock was here!    --AC_DC”echo “Hard rock was here!    --AC_DC”

当你在宏参数中使用相同的文本时,必须有个额外的方括号。一般情况下,为所有的文字字符串参数使用双重方括号是一个好主意。

AC_MSG_WARN([[AC_DC] stink –Iron Maiden])AC_MSG_WARN([[AC_DC stink –Iron Maiden]])

然而,当运行autoconf时,上面的例子可能会触发不能展开宏的警告,因为它与Autoconf语言的宏保留命名空间相冲突。为了实现真正的安全,你可以使用附加的转移符来避免特定的警告:

echo “Hard rock was here! –AC””_DC”AC_MSG_WARN([[AC@&t@_DC stinks –Iron Maiden]])

一些宏带有可选参数,使用[arg]的方式给出(不要与方括号混淆)。你可以将其置为空或者使用[],或者不写出来。例如,下面三行都是相等的:

AC_CHECK_HEADERS([stdio.h], [], [], [])AC_CHECK_HEADERS([stdio.h], , , )AC_CHECK_HEADERS([stdio.h])
 最好把每个宏调用放在一行。大多数宏不需要添加额外的行;它们依靠宏调用的换行来终止命令。这种方法使得生成的configure脚本更容易阅读不需要插入大量的空白行。

 你可以在configure.ac文件中包含注释,注释以’#‘字符开头。例如,在configure.in文件中使用下面的内容是有帮助的:

# Process this file with autoconf toproduce a configure script.



0 0