Autoconf - 将程序输出保存在变量中

时间:2017-11-23 15:29:24

标签: autotools configure autoconf

我有一个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

有人能指出我正确的方向吗?

1 个答案:

答案 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扩展,而是使用相同的前缀。