更强大的 AC_COMPILE_IFELSE 功能测试?

More robust AC_COMPILE_IFELSE feature testing?

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

在我的非 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 是什么意思 "success[ful]".

我的第一个问题是,编译器 return 值是否在某处标准化?

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

我的第三个问题是,我们如何在 Autoconf 中做同样的事情?除了AC_COMPILE_IFELSE还有别的用处吗?

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

提前致谢。

My first question is, are compiler return values standardized somewhere?

我很确定没有标准定义任何语言的编译器应该 return,除了所有程序的明显标准,退出代码 0 意味着成功,其他一切都失败,参见 posix on the exit 函数:

A value of zero (or EXIT_SUCCESS, which is required to be zero) for the argument status conventionally indicates successful termination. This corresponds to the specification for exit() in the ISO C standard. The convention is followed by utilities such as make and various shells, which interpret a zero status from a child process as success. For this reason, applications should not call exit(0) or _exit(0) when they terminate unsuccessfully; for example, in signal-catching functions.


My second question is, what does Autoconf use to determine "success"?

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

AC_COMPILE_IFELSE is successful, iff the compiler has a successful exit code (i.e. 0) and the object file is not empty (test -s conftest.$ac_objext; it is removed before running the compiler). If AC_LANG_WERROR was used for the current language it also makes sure the stderr output of the compiler is empty (apart from shell trace log lines).


My third question is, how do we do the same in Autoconf? Is there something else to use besides AC_COMPILE_IFELSE?

请记住,尽管 autoconf 源代码看起来很神奇,但它们并非如此 - 只要您知道自己想要它们做什么,就可以构建自己的宏 :) 但也许 AC_LANG_WERROR 是一个选项,除了告诉供应商吸它并修复他们的废话。

我不是 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([],[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],[],[])])

conftest.err是在AC_COMPILE_IFELSE完成后被删除的,所以需要在内部操作中查看。