【问题标题】:Autoconf -- save program output in variableAutoconf -- 将程序输出保存在变量中
【发布时间】:2017-11-23 15:29:24
【问题描述】:

我有一个自动配置问题。在 ./configure 期间,我需要编译并运行一个小 C 程序,并将它的标准输出捕获并修剪成一个变量,然后确认该变量已成功设置。感觉这应该很简单,但我已经挣扎了几个小时。

我希望解析标准输出:

hello "world"

并将引用字符串的内容存储在变量GREETING中。反而 我的 sn-p 生成错误“无法检测问候语”。

这是我目前所拥有的:

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

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

【问题讨论】:

  • 您过度引用了许多宏参数,而低估了另一个。在任何情况下,至少出于测试目的,我建议添加代码以更直接地验证采用AC_RUN_IF_ELSE 的哪个分支。您可以为此使用AC_MSG_NOTICE,或AC_MSG_CHECKING / AC_MSG_RESULT 对。

标签: autotools configure autoconf


【解决方案1】:

我目前正在使用autoconf 2.69,并且我使用AC_RUN_IFELSE 实现了一个缓存测试,该测试#defines 一个要由我的程序使用的宏。这通过一个环境变量,所以如果你也只需要它,它就很有用。

我发现AC_RUN_IFELSE 的一个问题是它没有写入文件(如文档中的示例所建议的那样);它似乎只是为了测试程序是否编译、链接和运行(即退出代码为 0)。

如果您确信您的程序在编译和链接时会运行,您不妨使用AC_LINK_IFELSE,它也会生成一个二进制文件 - 但不会测试它是否返回退出代码 0。

做缓存,使用AC_CACHE_CHECK,测试程序只有在之前没有做的时候才会被编译、链接和运行;但结果仍然被打印出来(又名:

检查问候消息...世界(缓存)

其中 'world' 是缓存值。换句话说,这会打印缓存的值。然而AC_RUN_IFELSE 将程序输出打印到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 扩展的,而是使用相同的前缀。

【讨论】:

    猜你喜欢
    • 2020-03-29
    • 2011-11-10
    • 2013-01-03
    • 2021-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-12
    • 1970-01-01
    相关资源
    最近更新 更多