当在 m4_foreach_w 中调用 AC_CHECK_HEADERS 时,autoheader(2.65) 似乎生成了一个伪造的模板。例如:
m4_foreach_w([hdr],[[foo.h] [bar.h]],
[AC_DEFINE([HAVE_]m4_translit(m4_toupper(hdr),[/.],[__]),[1],
[Define to 1 if ]hdr[ is available])]
[AC_CHECK_HEADERS([hdr])]
)
原因config.h.in
(假设 AC_CONFIG_HEADERS([config.h])
)有一个模板:
/* Define to 1 if you have the <hdr> header file.*/
#undef HAVE_HDR
有什么办法可以避免这个假模板吗?请注意 m4_foreach_w
正在宏内调用,实际文本为 m4_foreach_w([hdr],[$1],
我想知道我是否有 m4 引用问题,但我怀疑这个问题更根本。也就是说,我总是认为我错误地引用了 m4——但这似乎不是这里的问题。相反,autoheader
正在扫描文本而不遵守 m4_foreach_w
。我不认为模板会引起任何问题,但最终的结果看起来很奇怪 config.h
.
最佳答案
请注意,autoheader
不会“扫描”configure.ac
。相反,它在跟踪模式下通过 m4
运行 configure.ac
,以便捕获对 AC_DEFINE_TRACE_LITERAL
的低级调用(由AC_DEFINE
)和AH_OUTPUT
(由AC_CHECK_HEADERS
调用)。因此,因为一切都经过 m4
,所以 autoheader
不会忽略 m4_foreach
。然而,它以宏实际接收参数的方式看待参数。
您可以通过跟踪 configure.ac
中对 AC_DEFINE
和 AC_CHECK_HEADERS
的调用来查看代码中的问题:
% cat configure.ac AC_INIT(somelib.so, 1.0, [email protected]) m4_foreach_w([hdr],[[foo.h] [bar.h]], [ AC_DEFINE([HAVE_]m4_translit(m4_toupper(hdr),[/.],[__]),[1], [Define to 1 if ]hdr[ is available]) AC_CHECK_HEADERS([hdr]) ]) AC_CONFIG_HEADERS([config.h]) AC_OUTPUT % autoconf -t AC_DEFINE -t AC_CHECK_HEADERS configure.ac:3:AC_DEFINE:HAVE_FOO_H:1:Define to 1 if foo.h is available configure.ac:3:AC_CHECK_HEADERS:hdr configure.ac:3:AC_DEFINE:STDC_HEADERS:1:Define to 1 if you have the ANSI C header files. configure.ac:3:AC_CHECK_HEADERS:sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h inttypes.h stdint.h unistd.h:::$ac_includes_default configure.ac:3:AC_DEFINE:HAVE_BAR_H:1:Define to 1 if bar.h is available configure.ac:3:AC_CHECK_HEADERS:hdr
So we see that AC_CHECK_HEADERS
is called twice with hdr
as argument. While in the call to AC_DEFINE, hdr
has been correctly expanded. That's because hdr
is quoted one more time in your call to AC_CHECK_HEADERS
, preventing its expansion.
I'd fix it this way:
m4_foreach_w([hdr],[[foo.h] [bar.h]], [
AC_DEFINE([HAVE_]m4_translit(m4_toupper(hdr),[/.],[__]),[1],
[Define to 1 if ]hdr[ is available])
AC_CHECK_HEADERS(hdr)
])
(但这仍然假设名称 foo.h 和 bar.h 永远不会触发任何宏。)
关于autotools - 抑制不必要的输出到 config.h.in,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12570402/