更强大的AC_COMPILE_IFELSE功能测试?

时间:2017-11-07 14:40:38

标签: c++ compiler-warnings autoconf

Autoconf的AC_COMPILE_IFELSE在不同的编译器下错误检测了我们的功能,例如Sun的C ++编译器和IBM的xlC编译器。 AC_COMPILE_IFELSE似乎会检查返回值,但有些编译器无需设置或将其设置为意外值。稍后,我们使用不可用的选项。

在我的非Autoconf构建脚本中,我使用"fatal|error|illegal|unrecognized|not found|not exist"来检测编译器或链接器投诉。它比仅仅检查$?更强大。测试看起来像:

# infile and outfile are temp files that allow testing a feature
SH_ERROR=$($CXX -Wl,--enable-new-dtags -o "$outfile" "$infile" 2>&1 | $EGREP -i -c -E 'fatal|error|illegal|unrecognized|not found|not exist')
if [[ "$SH_ERROR" -eq "0" ]]; then
    CXXFLAGS+="-Wl,--enable-new-dtags"
fi

AC_COMPILE_IFELSE的Autoconf文档位于6.4 Running the Compiler,但未讨论主题。事实上,该文件甚至没有定义AC_COMPILE_IFELSE成功[...]"

的含义。

我的第一个问题是,编译器返回值是否标准化了什么?

我的第二个问题是,Autoconf用什么来确定"成功"?

我的第三个问题是,我们如何在Autoconf中做同样的事情?除AC_COMPILE_IFELSE之外还有其他什么用途吗?

一个相关的问题是(根据Stefan的答案),我们如何让Autoconf使用改进的AC_COMPILE_IFELSE?是否可以取消当前AC_COMPILE_IFELSE并将其定义为更强大的版本?

提前致谢。

1 个答案:

答案 0 :(得分:4)

  

我的第一个问题是,编译器返回值是否标准化了什么?

我非常确定没有标准定义任何语言的编译器应该返回,除了退出代码0的所有程序的明显标准意味着成功和其他一切失败,请参阅{{3功能:

  

参数状态的值为零(或EXIT_SUCCESS,必须为零)通常表示成功终止。这符合ISO C标准中exit()的规范。该约定之后是诸如make和各种shell之类的实用程序,它们将子进程的零状态解释为成功。因此,应用程序在终止失败时不应调用exit(0)_exit(0);例如,在信号捕捉功能中。

  

我的第二个问题是,Autoconf用什么来确定"成功"?

最新的autoconf版本是2.69(从2012年开始),虽然有些事情可能已经改变,但我会根据它做出回答。

posix on the exit成功,如果编译器有一个成功的退出代码(即0)并且目标文件不为空(test -s conftest.$ac_objext;它在运行编译器之前被删除)。如果AC_COMPILE_IFELSE用于当前语言,则还会确保AC_LANG_WERRORthe stderr output of the compiler is empty除外)。

  

我的第三个问题是,我们如何在Autoconf中做同样的事情?除AC_COMPILE_IFELSE之外还有其他什么用途吗?

请记住,虽然autoconf源看起来像魔术,但它们不是 - 你可以建立自己的宏,只要你知道你想要他们做什么:)但也许shell trace log lines是一个选项,除了告诉供应商吮吸它并修复它们的废话。

我不是AC_LANG_WERROR的粉丝:几年前我必须在多系统系统上使用/etc/ld.so.preload来修复flashplayer的问题,并从其他arch中运行二进制文件总是会打印出一个无法加载它的错误,尽管它没有任何问题 - AC_LANG_WERROR在这样的环境中可怕地破坏

作为自定义编译检查宏的示例,请看一下:

# MY_COMPILE_CLEAN_IFELSE(PROGRAM, [ACTION-IF-TRUE], [ACTION-IF-FALSE])
# ---------------------------------------------------------------
# Try to compile PROGRAM.
AC_DEFUN([MY_COMPILE_CLEAN_IFELSE],
[AC_REQUIRE([AC_PROG_EGREP])
AC_COMPILE_IFELSE([$1],[retval=0
if $EGREP -i -c -E 'fatal|error|unrecognized|not found|not exist' conftest.err >/dev/null; then retval=1; fi
],[retval=1])
AS_IF([test $retval = 0],[$2],[$3])])
conftest.err完成后删除

AC_COMPILE_IFELSE,因此您需要在内部操作中进行检查。

相关问题