3.1.2 Autoconf语言

Autoconf语言与许多其他计算机不同语言,因为它将实际代码视为纯文本。鉴于例如,在C语言中,数据和指令有不同的语法状态,在Autoconf中,它们的状态完全相同。因此,我们需要一种方法来区分文字字符串和要扩展的文本:报价单。

调用带参数的宏时,不能有任何白色宏名称和左括号之间的空格。

AC_INIT([oops],[1.0])#不正确AC_INIT([你好],[1.0])#good

参数应该用引号括起来'['和']',并且是用逗号分隔。参数中的任何前导空格或换行符都将被忽略,除非报价。你应该总是引用一个论点可能包含宏名称、逗号、括号或前导空格或换行。此规则递归应用于每个宏调用,包括从其他宏调用的宏。有关的更多详细信息引用规则,请参阅M4编程.

例如:

AC_CHECK_HEADER([标准o.h],[AC_DEFINE([HAVE_STDIO_H],[1],[如果您有<stdio.h>.])],[AC_MSG_ERROR([抱歉,无法为您做任何事情])]

正确引用。您可以放心地将其报价简化为:

AC_CHECK_HEADER([标准o.h],[AC_DEFINE([HAVE_STDIO_H],1,[如果您有<stdio.h>.])],[AC_MSG_ERROR([抱歉,无法为您做任何事情])]

因为'1'不能包含宏调用。这里,关于AC_MSG_错误必须报价;否则,它的逗号将是解释为参数分隔符。此外,第二个和第三个论点第页,共页'AC_检查_头'必须引用,因为它们包含宏调用。三个参数HAVE_STDIO_H公司’, ‘标准件。小时’,和'如果有<stdio.h>,则定义为1。“不需要报价,但如果您不明智地定义了一个名为“”的宏定义'或标准偏差“那么他们需要报价。谨慎的Autoconf用户会保留报价,但许多Autoconf用户发现了此类预防措施令人讨厌,并且会将示例重写如下:

AC_CHECK_HEADER(标准,[AC_DEFINE(HAVE_STDIO_H,1,[如果您有<stdio.h>.])],[AC_MSG_ERROR([抱歉,无法为您做任何事情])]

这是安全的,只要您采用良好的命名约定并且不定义名称类似“”的宏HAVE_STDIO_H公司’, ‘标准件',或小时’. 虽然这里省略引号也很安全如果有<stdio.h>,则定义为1。“不建议这样做,因为消息字符串更有可能无意中包含逗号。

以下示例错误且危险,因为它被低估了:

AC_CHECK_HEADER(标准,AC_DEFINE(HAVE_STDIO_H,1,如果有<stdio.h>,则定义为1。),AC_MSG_ERROR([抱歉,无法为您做任何事情])

在其他情况下,您可能希望使用与宏类似的文本呼叫。您必须引用该文本(无论是潜在问题,还是整行),即使它没有作为宏参数传递;还有你可能还必须使用m4_图案_允许(请参见禁止的图案),声明您希望生成的配置文件将具有类似于其他保留内容的文字宏名称。例如:

dnl模拟未来可能的autoconf宏m4_define([AC_DC],[oops])dnl报价不足:echo“硬石在这里!--AC_DC”dnl正确引用:m4_pattern_allow([AC_DC])echo“硬石在这里!--[AC_DC]”[echo“硬石在这里!--AC_DC”]

这将导致此文本配置:

echo“坚硬的岩石在这里!——哎呀”echo“硬石在这里!--AC_DC”echo“硬石在这里!--AC_DC”

因此,当在宏参数中使用相同的文本时,必须额外的引用级别(因为宏删除了一个替换)。一般来说,这样做是一个好主意使用double引用所有文字字符串参数,要么就在有问题的部分,或整个论点:

m4_图案_允许([AC_DC])AC_MSG_WARN([[AC_DC]臭--铁娘子])AC_MSG_WARN([[AC_DC臭气熏天--铁娘子]])

也可以避免第一种模式中的问题模式位置,通过使用附加转义(四边形或创造性外壳构造),在这种情况下,不再需要使用m4_图案_允许:

echo“硬石在这里!--AC”“_DC”AC_MSG_WARN([[AC@&t@_DC臭--铁娘子]])

您现在能够理解Autoconf的一个构造一直被误解...经验法则是无论何时你期望宏扩展,期望报价扩展;即,预计会丢失一级报价。例如:

AC_COMPILE_IFELSE(AC_LANG_SOURCE([char b[10];])、[],[AC_MSG_ERROR([您输了])]

不正确:这里是的第一个参数AC_LANG_来源字符b[10];'并展开一次,这将导致字符b10;’; AC_LANG_来源之前也进行了扩展被传递给AC_COMPILE_IFELSE公司(有一个习语很常见在Autoconf的过去通过M4解决此问题变更报价单基本的,但不是使用它!)让我们仔细看看:作者指的是第一个论点被理解为字面意思,因此必须引用两次;同样,中间产物AC_LANG_来源应引用宏一次,这样它只会在身体的其余部分膨胀AC_COMPILE_IFELSE公司已到位:

AC_COMPILE_IFELSE([AC_LANG_SOURCE([[字符b[10];]])],[],[AC_MSG_ERROR([您输了])]

对了,你真的生产了'字符b[10];“这次!

另一方面,描述(例如AC_定义AS_帮助_字符串)不是文字-他们例如,可能会出现换行,并且不应重复引用。即使这些描述很简短,实际上并没有中断,也要加倍引用它们会产生奇怪的结果。

一些宏采用可选参数,本文档表示了这些参数作为[参数](不要与引号字符混淆)。你可以只需将其留空,或使用“[]“使参数显式,或者您可以简单地省略后面的逗号。这个以下三行相当:

AC_CHECK_HEADERS([stdio.h],[],[],[)AC_CHECK_HEADERS([标准o.h],,,)AC_CHECK_HEADERS([标准o.h])

最好将每个宏调用放在配置.ac。大多数宏不会添加额外的换行符;他们依赖宏调用后的换行来终止命令。此方法使生成的配置写一点脚本不插入大量空行,更易于阅读。一般来说在宏调用的同一行上设置shell变量是安全的,因为shell允许在不插入换行符的情况下进行赋值。

您可以在中包含注释配置.ac通过启动文件带有“#’. 例如,开始配置.ac带有如下行的文件:

#使用autoconf处理此文件以生成配置脚本。