我的第一个问题是,编译器返回值是否在某处标准化?
我很确定除了所有退出代码的程序的明显标准之外,没有标准定义任何语言的编译器应该返回什么0
意味着成功,其他一切都失败,请参阅POSIX 上exit http://pubs.opengroup.org/onlinepubs/000095399/functions/exit.html功能:
值为零(或EXIT_SUCCESS
,要求为零),参数状态通常表示成功终止。这对应于规范exit()
在 ISO C 标准中。该约定之后是 make 和各种 shell 等实用程序,它们将子进程的零状态解释为成功。因此,应用程序不应调用exit(0)
or _exit(0)
当它们终止失败时;例如,在信号捕获功能中。
我的第二个问题是,Autoconf 使用什么来确定“成功”?
最新的 autoconf 版本是 2.69(从 2012 年开始),尽管有些事情可能发生了变化,但我的答案将基于它。
AC_COMPILE_IFELSE http://git.savannah.gnu.org/gitweb/?p=autoconf.git;a=blob;f=lib/autoconf/general.m4;hb=refs/tags/v2.69#l2568成功,当且仅当编译器有成功的退出代码(即0
)并且目标文件不为空(test -s conftest.$ac_objext
;它在运行编译器之前被删除)。如果AC_LANG_WERROR https://www.gnu.org/software/autoconf/manual/autoconf-2.67/html_node/Generic-Compiler-Characteristics.html#index-AC_005fLANG_005fWERROR-833用于当前语言它也确保the stderr编译器的输出为空 http://git.savannah.gnu.org/gitweb/?p=autoconf.git;a=blob;f=lib/autoconf/general.m4;hb=refs/tags/v2.69#l2575(除了shell 跟踪日志行 http://git.savannah.gnu.org/gitweb/?p=autoconf.git;a=blob;f=lib/autoconf/general.m4;hb=refs/tags/v2.69#l2320).
我的第三个问题是,我们如何在 Autoconf 中做同样的事情?除了还有什么可以用的吗AC_COMPILE_IFELSE
?
请记住,虽然 autoconf 源看起来很神奇,但事实并非如此 - 只要您知道您想要它们做什么,您就可以构建自己的宏:)但也许AC_LANG_WERROR https://www.gnu.org/software/autoconf/manual/autoconf-2.67/html_node/Generic-Compiler-Characteristics.html#index-AC_005fLANG_005fWERROR-833除了告诉供应商忍住并修复他们的垃圾之外,这是一个选择。
我不喜欢AC_LANG_WERROR
: 我必须使用/etc/ld.so.preload
几年前,在多架构系统上修复 flashplayer 的问题,从另一个架构运行二进制文件总是会打印一个无法加载它的错误,尽管它没有任何问题 -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
已经完成了,所以需要在内部actions中检查一下。