添加动态符号名称不适用于 configure.ac 中的 AC_DEFINE_UNQUOTED

Adding a dynamic symbol name not work with AC_DEFINE_UNQUOTED from configure.ac

配置文件中的 add a new symbol into 生成的 config.h 文件有一个宏。这允许您检查系统并启用 C/C++ 应用程序中的选项。有两种类型的宏:添加动态符号和固定符号。通过使用 AC_DEFINE_UNQUOTED,这是一个添加动态符号的宏,可以设置名称或值来自变量的符号。

这是我的简单 configure.ac 文件

name="test"
AC_DEFINE_UNQUOTED([USE_${name}], [1], [Enable test usage])

我希望将 USE_test 作为 C/C++ 定义添加到 config.h 中。但是,结果 config.h 文件中不存在该定义。

通过 运行ning Autotools 在 configure.status 中有以下行:

D["USE_test"]=" 1"

这意味着 Autotools 将搜索 config.h.in 以用新值替换 USE_test。

但是生成的config.h.in文件不包含如下定义:

#define Use_test 1

所以 Autoheader 没有 运行 正确?!并且无法将可变文本作为符号添加到 config.h?!

哪里有问题或者可以通过configure.ac添加一个带有变量名的交易品种?

But the final config.h file does not contain the following definition [...] config.h.in is generated dynamically and it does not contain the definition too.

后者其实才是关键问题。当您使用 AC_CONFIG_HEADERS 请求将定义记录在 header 文件中而不是通过编译器 command-line 选项表达时,Autoconf 通过处理一个或多个 header 模板来处理它,例如 config.h.in,以生成结果 header(s)。但是,autoconf 命令本身并不生成这些模板。如果愿意,您可以手写它们,但是可以使用一个单独的程序 autoheader 来执行这项工作,并且 autoreconf(不是 autoconf)会自动运行 autoheader为第一个 AC_CONFIG_HEADERS 调用中命名的第一个 header 生成一个模板。

您描述的行为是一个长期已知的问题(不算是错误,本身),您可以找到讨论 in the archives of the bug-autoconf mailing list. The resolution was a documentation change, whose result you can still see in the section of the Autoconf manual that discusses Autoheader:

In order to do its job, autoheader needs you to document all of the symbols that you might use. Typically this is done via an AC_DEFINE or AC_DEFINE_UNQUOTED call whose first argument is a literal symbol and whose third argument describes the symbol (see Defining Symbols).

(强调已添加。)

从技术上讲,这确实是这些细节的合适位置。也就是说,AC_DEFINE_UNQUOTED 的行为确实如广告所示,可以通过禁用 AC_CONFIG_HEADERS(在许多情况下是一种可行的解决方法)或采用文档继续建议的替代方案之一来看出:

you can use AH_TEMPLATE (see Autoheader Macros), or you can supply a suitable input file for a subsequent configuration header file. Symbols defined by Autoconf's builtin tests are already documented properly; you need to document only those that you define yourself.

如果您认为在 AC_DEFINE_UNQUOTED 文档中也提到该问题会很好,那么我完全同意您的看法。但我也确实认为,由于 autoreconf 的引入和流行,现在的情况与首次进行文档更改时有很大不同,这对大多数人隐藏了 autoheader 的参与用户。

无论如何,我将忽略 "supply your own template" 选项,它有点令人担忧,并专注于 AH_TEMPLATE。要使用它来支持问题中出现的特定情况,可以将这些内容添加到 configure.ac:

AH_TEMPLATE([USE_test], [Define to 1 to use test])

也许你会问"What's the point then? I might as well use a regular AC_DEFINE."这个问题很好,你确实应该好好考虑一下。请注意,定义 arbitrary 预处理器宏没有意义,因为只有与出现在一个或多个源中的符号相对应的宏才会被扩展。这并不一定会使 configure 时间的宏名称生成变得无用,但它确实意味着在维护 configure.ac 时,您可以而且应该拥有所有需要支持的生成的宏名称的完整列表。在这种情况下,您确实可以为所有需要的情况编写适当的 AH_TEMPLATE 调用。然而,在大多数情况下,针对每个符号直接进入(有条件的)AC_DEFINEs 可能是更好的选择。