c++ - 更强大的 AC_COMPILE_IFELSE 功能测试?

标签 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 是“成功[ful]”的含义。

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

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

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

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

提前致谢。

最佳答案

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

我很确定没有标准定义任何语言的编译器应该返回什么,除了所有退出代码 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 是成功的,如果编译器有一个成功的退出代码(即 0)并且目标文件不为空(test -s conftest.$ac_objext;它在运行编译器之前被删除)。如果 AC_LANG_WERROR 用于当前语言,它还会确保 the stderr output of the compiler is empty(除了 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 在这样的环境中严重崩溃/p>

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

# 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.errAC_COMPILE_IFELSE完成后被删除,所以需要在内部 Action 中查看。

关于c++ - 更强大的 AC_COMPILE_IFELSE 功能测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47160617/

相关文章:

c++ - 模板匹配屏幕截图在断言时失败

c++ - 具有多值的无序映射及其查找

ios - Xcode 警告 : Ignoring file libxml2. 2.dylib,为不受支持的文件格式构建,这不是被链接的体系结构

c - 当 .h 文件清楚可用时,为什么 autoconf 不通过 AC_CHECK_HEADER 测试?

makefile - 使用 GCC 和 autotools 为各个源文件设置编译标志的最佳方法是什么?

c++ - gcc 编译无效的 C 代码

c++ - 对 int 类型和无符号整数的值应用模运算

c - 警告 : Variable is unitialized in this function

c# - 警告 MSB3276 - 奇怪的 Mono.Cairo 版本控制行为

c++ - 使用 autoconf 找不到 boost 库 1.52