Более надежный AC компилирует тестирование функций IFELSE?
autoconf для Х AC_COMPILE_IFELSE
неправильно определяет функции для нас в разных компиляторах, таких как компилятор Sun C++ и компилятор xlC IBM. 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
документация Autoconf для AC_COMPILE_IFELSE
на 6.4 запуск компилятора, но это не Обсуждение предмета. Фактически, документ даже не определяет, что он означает для AC_COMPILE_IFELSE
быть " успех[ful]".
мой первый вопрос: Являются ли возвращаемые значения компилятора стандартизированными где-то?
мой второй вопрос: что Autoconf использует для определения "успеха"?
мой третий вопрос, как мы это делаем то же самое в Autoconf? Есть ли что-то еще, кроме AC_COMPILE_IFELSE
?
связанный вопрос (основанный на ответе Стефана), как мы получаем Autoconf для использования улучшенного AC_COMPILE_IFELSE
? Можно ли undef текущий AC_COMPILE_IFELSE
и определить его для более надежной версии?
спасибо заранее.
1 ответов
мой первый вопрос: где-то стандартизированы возвращаемые значения компилятора?
я уверен, что нет стандарта, определяющего, какие компиляторы для любого языка должны возвращаться, кроме очевидного стандарта для всех программ, которые выходят из кода 0
означает успех и все остальное провал, см. posix на exit
:
значение нуля (или
EXIT_SUCCESS
, который должен быть равен нулю) для аргумента статус условно означает успешное завершение. Это соответствует спецификацииexit()
в стандарте ISO C. За соглашением следуют утилиты, такие как make и различные оболочки, которые интерпретируют нулевой статус дочернего процесса как успех. По этой причине, приложения не должны вызыватьexit(0)
или_exit(0)
когда они заканчиваются неудачно; например, в функциях улавливания сигналов.
мой второй вопрос, что делает Использование Autoconf для определения "успеха"?
последний выпуск autoconf-2.69 (с 2012 года), и хотя некоторые вещи могли измениться, я собираюсь основывать свой ответ на нем.
AC_COMPILE_IFELSE
успешно, если компилятор имеет успешный код выхода (т. е. 0
) и объектный файл не является пустым (test -s conftest.$ac_objext
; он удаляется перед запуском компилятора). Если AC_LANG_WERROR
используется для текущего языка, он также гарантирует, что the stderr
вывод компилятора пуст (кроме строки журнала трассировки оболочки).
мой третий вопрос: как мы делаем то же самое в Autoconf? Есть ли что-то еще, кроме
AC_COMPILE_IFELSE
?
имейте в виду, что хотя источники autoconf выглядят как магия, они не являются - Вы можете создавать свои собственные макросы, пока вы знаете, что вы хотите, чтобы они делали :) но, возможно,AC_LANG_WERROR
- это вариант, кроме того, чтобы сказать поставщику сосать его и исправить свое дерьмо.
я не фанат 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([],[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
сделано, поэтому вам нужно проверить его во внутренних действиях.