有一个宏,它可以从配置文件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文件中不存在该问题。
通过运行Autotools,configure.status中包含以下行:
D["USE_test"]=" 1"
这意味着Autotools将搜索config.h.in以将USE_test替换为新值。
但是生成的config.h.in文件不包含以下定义:
#define Use_test 1
所以自动标题无法正确运行?!而且不可能将可变文本作为符号添加到config.h?!
问题出在哪里,或者可以通过configure.ac添加带有变量名的符号吗?
但是最终的config.h文件不包含以下定义[...] config.h.in是动态生成的,它不包含也有定义。
后者实际上是关键问题。当您使用AC_CONFIG_HEADERS
要求将定义记录在头文件中而不是通过编译器命令行选项表达时,Autoconf通过处理一个或多个头模板(例如config.h.in
)来处理它,以产生结果头( s)。但是,autoconf
命令本身不会产生这些模板。您可以根据需要手工编写它们,但是可以使用单独的程序autoheader
来执行此作业,并且autoreconf
(not autoconf
)自动运行autoheader
以生成输入模板对于第一个AC_CONFIG_HEADERS
调用中命名的第一个标头。
您描述的行为是一个长期已知的问题(未解决错误,本身),您可以找到已讨论的in the archives of the bug-autoconf mailing list。该决议是对文档的更改,您仍然可以在the section of the Autoconf manual that discusses Autoheader中看到其结果:
为了完成其工作,
autoheader
需要您记录所有您可能会使用的符号。通常,这是通过AC_DEFINE
完成的或AC_DEFINE_UNQUOTED
调用其第一个参数是文字的symbol,其第三个参数描述该符号(请参见定义符号)。
((添加了强调。)
这确实是那些细节的技术上适当的地方。也就是说,AC_DEFINE_UNQUOTED
的行为确实如广告所示,可以通过禁用AC_CONFIG_HEADERS
(在许多情况下是可行的解决方法)或采用文档建议的一种替代方法来看到:
您可以使用
AH_TEMPLATE
(请参阅自动标题宏),或者您可以为后续提供适当的输入文件配置头文件。 Autoconf的内置测试定义的符号已经正确记录;您只需要记录那些您定义自己。
[如果您认为AC_DEFINE_UNQUOTED
文档中提到的问题也很好,那么我完全同意您的观点。但是我也确实认为,由于autoreconf
的引入和普及,现在的情况与首次进行文档更改时相比已经有了很大的不同,这使大多数用户都无法使用autoheader
。
在任何情况下,我都会忽略“供您自己使用的模板”选项,这有点令人生厌,而将重点放在AH_TEMPLATE
上。为了使用它来支持问题中提出的特殊情况,可以在configure.ac
中添加以下内容:
AH_TEMPLATE([USE_test], [Define to 1 to use test])
也许您问“那是什么意思?我不妨使用常规的AC_DEFINE
。”这是一个好问题,您确实应该仔细考虑。请注意,没有必要定义arbitrary预处理程序宏,因为只有与出现在一个或多个源中的符号相对应的那些宏才会被扩展。这并不一定会使configure
-时间宏名称的生成变得无用,但这确实意味着在维护configure.ac
时,您可以而且应该拥有所有需要支持的所有生成的宏名称的完整列表。在那种情况下,您可能为所有需要的情况编写适当的AH_TEMPLATE
调用确实是合理的。但是,在大多数情况下,直接将每个符号设为(有条件)AC_DEFINE
可能是一个更好的选择。