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
被删除,因此您需要在内部操作中检查它。
上一篇: c++