C ++

Autoconf的AC_COMPILE_IFELSE在不同的编译器下会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运行编译器,但没有讨论主题。 事实上,该文档甚至没有定义AC_COMPILE_IFELSE意思是“成功[ful]”。

我的第一个问题是,编译器返回值是否在某个地方标准化?

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

我的第三个问题是,我们如何在Autoconf中做同样的事情? 除AC_COMPILE_IFELSE之外还有别的东西AC_COMPILE_IFELSE吗?

一个相关的问题是(基于Stefan的回答),我们如何让Autoconf使用改进的AC_COMPILE_IFELSE ? 是否有可能AC_COMPILE_IFELSE当前AC_COMPILE_IFELSE并将其定义为更强大的版本?

提前致谢。


我的第一个问题是,编译器返回值是否在某个地方标准化?

我很确定没有标准定义任何语言的编译器应该返回什么,除了所有退出代码0程序的明显标准意味着成功和其他所有的失败,请参阅exit函数的posix:

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


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

最新的autoconf版本是2.69(2012年起),虽然有些事情可能已经改变,但我会以我的答案为基础。

AC_COMPILE_IFELSE是成功的,当且仅当编译器有一个成功的退出代码(即0 )和对象文件不为空( test -s conftest.$ac_objext ;在运行编译器之前删除)。 如果将AC_LANG_WERROR用于当前语言,它还会确保编译器的stderr输出为空(除了shell跟踪日志行之外)。


我的第三个问题是,我们如何在Autoconf中做同样的事情? 除AC_COMPILE_IFELSE之外还有别的东西AC_COMPILE_IFELSE吗?

请记住,虽然autoconf源代码看起来很神奇,但它们不是 - 只要你知道你想要它们做什么,你就可以建立自己的宏)但是也许AC_LANG_WERROR是一个选项,除了告诉厂商吸引它并修复他们的废话。

我不是AC_LANG_WERROR的粉丝:我AC_LANG_WERROR不得不在多种系统上使用/etc/ld.so.preload来解决flashplayer的问题,而从另一个arch运行二进制文件总是会输出一个错误加载它,虽然没有什么问题 - AC_LANG_WERROR在这样的环境中破坏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])])

AC_COMPILE_IFELSE完成后, conftest.err被删除,因此您需要在内部操作中检查它。

链接地址: http://www.djcxy.com/p/40717.html

上一篇: c++

下一篇: Cloning the object in JavaScript