我有一个autoconf问题。在。/configure
期间,我需要编译并运行一个小的C程序,并将其stdout捕获并修剪为变量,然后确认变量已成功设置。感觉这应该很简单,但我已经挣扎了几个小时。
我希望解析stdout:
hello "world"
并将引用字符串的内容存储在变量GREETING中。代替 我的代码片段会生成错误“无法检测到问候语”。
这是我到目前为止所拥有的:
AC_RUN_IFELSE(
[AC_LANG_PROGRAM(
[[#include <stdio>]],
[[printf("hello \"world\"\n");]])
],
[AC_SUBST(GREETING,
[[`./conftest$EXEEXT | sed 's/.*"\(.*\)".*/\1/'`]])
]
)
if test -z "${GREETING}"; then
AC_MSG_ERROR([Cannot detect greeting])
fi
有人能指出我正确的方向吗?
答案 0 :(得分:0)
我当前正在使用autoconf 2.69
,并且使用AC_RUN_IFELSE
实现了一个缓存测试,该测试#定义了我的程序要使用的MACRO。这是通过一个环境变量进行的,因此如果您也只需要它,将很有用。
我在AC_RUN_IFELSE
中发现的一个问题是它没有写入文件(如文档中的示例所建议);似乎只打算测试程序是否可以编译,链接和运行(即退出代码为0)。
如果您确信程序在编译和链接时将运行,则不妨使用AC_LINK_IFELSE
,它也会生成一个二进制文件-但不会测试它是否返回退出代码0。
使用AC_CACHE_CHECK
进行缓存,仅在之前未完成的情况下编译,链接和运行测试程序;但结果仍会打印(又名:
正在检查问候消息...世界(已缓存)
其中“ world”是缓存的值。换句话说,这将打印缓存的值。但是AC_RUN_ELSEIF
也 将程序输出打印到stdout
!因此,如果尚未缓存该值,则将产生两次输出。如
正在检查问候语...世界
世界
此问题的解决方案似乎将您的输出打印到stderr
,并将其输出到日志文件而不是屏幕。
然后一个完整的autoconf宏变成类似
AC_DEFUN([CW_SYS_GREETING],
[AC_CACHE_CHECK(
[for greeting message],
[cw_cv_system_greeting],[dnl
AC_LANG_PUSH(C)
AC_RUN_IFELSE([dnl
AC_LANG_PROGRAM(
[#include <stdio.h>],
[fprintf(stderr, "hello \"world\"\n")])],
[cw_cv_system_greeting=$(./conftest$EXEEXT 2>&1 | sed 's/.*"\(.*\)".*/\1/')],
[AC_MSG_ERROR(Failed to compile a test program!?)])
AC_LANG_POP(C)])
eval "CW_GREETING=$cw_cv_system_greeting"
AC_SUBST(CW_GREETING)
m4_pattern_allow(CW_GREETING)
AC_DEFINE_UNQUOTED([CW_GREETING], $cw_cv_system_greeting, [The greeting to use.])
])
哪个会添加
/* The greeting to use. */
#define CW_GREETING world
到config.h
。
注意,我为宏使用了前缀CW_
,以免与autoconf定义的宏发生冲突。为了确保一切都得到扩展,因此我还添加了我的configure.ac:
dnl Detect unexpanded macros.
m4_pattern_forbid([^AX_]) dnl These macros are defined in the package 'autoconf-archive' available from the ubuntu "universe" repository.
m4_pattern_forbid([^CW_])
m4_pattern_forbid([^LT_])
这就是为什么我还需要/添加m4_pattern_allow(CW_GREETING)
的原因,因为此C宏不会被m4扩展,而是使用相同的前缀。