Как установить специфичные для компилятора флаги с помощью autotools

В качестве инфраструктуры сборки мы используем autotools, а в качестве компиляторов - clang и gcc. Недавно мы получили предупреждение gcc, которое требовало

--param max-vartrack-size=100000000

для отключения звука (без полного отключения отслеживания vartracking в gcc). Clang не принимает этот вариант и производит

argument unused during compilation: '--param max-vartrack-size=100000000'

Чтобы заставить это замолчать, нужно лязгать

-Qunused-arguments

и это вызывает ошибку в gcc:

unrecognized command line option ‘-Qunused-arguments’
  1. Каков наилучший способ определить специфичные для компилятора флаги в configure.ac после того, как компилятор был выбран, например AC_PROG_CXX? Мы AC_SUBST(AM_CXXFLAGS), поэтому я полагаю, что я бы расширил переменную, специфичную для компилятора, в AM_CXXFLAGS.

  2. Как правильно включить параметр для каждой цели в Makefile.am только для одного компилятора? Я думал о:

    if HAVE_GCC
        SPECIFIC_CXXFLAGS = --param...
    endif
    if HAVE_CLANG
        SPECIFIC_CXXFLAGS = -Q...
    endif
    libfoo_la_CXXFLAGS = $(AM_CXXFLAGS) $(SPECIFIC_CXXFLAGS)
    

но мне нужно было бы заменить HAVE_* vars из configure.ac. Возможно, AC_PROG_CXX/CC уже определяют что-то подобное?


person Irfy    schedule 10.06.2015    source источник


Ответы (2)


AM_CXXFLAGS не то, что вам следует AC_SUBST. Он зарезервирован для использования automake. Если вы посмотрите на Makefile, сгенерированный для цели C ++, вы найдете определения для CXXCOMPILE и LTCXXCOMPILE, которые всегда включают переменную AM_CXXFLAGS.

Вы хотите добавить (условный) флаг компилятора к AM_CXXFLAGS или libfoo_la_CXXFLAGS. Первое повлияет на все компиляции C ++, а второе - только на компиляции для каждой библиотеки. Так что это просто вопрос получения SPECIFIC_CXXFLAGS прямо в configure.ac.

AC_PROG_CXX
...
FOO_SPECIFIC_CXXFLAGS=;
if `$CXX -v 2>&1 | grep 'gcc version' >/dev/null 2>&1` ; then
  FOO_SPECIFIC_CXXFLAGS="--param max-vartrack-size=100000000"
fi

AC_SUBST(FOO_SPECIFIC_CXXFLAGS, $FOO_SPECIFIC_CXXFLAGS)

Тест GXX недостаточен, поскольку autoconf просто проверяет макрос __GNUC__ (AFAIK), поэтому clang ++ установит: GXX=yes

Проблема в том, что не существует переносимого способа определения неизвестных параметров командной строки. Intel icc -v даже воспроизведет строку gcc version. Возможно, вам придется добавить еще один фильтр, например: | grep -v 'icc'

При желании вы можете проверить, работает ли флаг так, как было объявлено до AC_SUBST, но это не поможет, если компилятор только выдает предупреждение:

saved_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS $FOO_SPECIFIC_CXXFLAGS"

AC_LANG_PUSH([C++])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])],,[FOO_SPECIFIC_CXXFLAGS=;])
AC_LANG_POP([C++])
CXXFLAGS="$saved_CXXFLAGS"

Затем в Makefile.am:

AM_CXXFLAGS = $(FOO_SPECIFIC_CXXFLAGS)

or:

libfoo_la_CXXFLAGS = $(FOO_SPECIFIC_CXXFLAGS)
person Brett Hale    schedule 10.06.2015
comment
Я озадачен вашим утверждением, что нельзя AC_SUBST AM_CXXFLAGS. Чем это отличается от установки AM_CXXFLAGS во всех 15Makefile.am вручную? AC_SUBSTing AM_CXXFLAGS - идеальное решение для таких вещей, как включение предупреждений для всего проекта по умолчанию или выбор более старого ABI с gcc 5.1 (который должен быть одинаковым для всех объектов). Как еще я мог бы этого добиться, кроме установки AM_CXXFLAGS в каждом из Makefile.am? - person Irfy; 11.06.2015
comment
Я решил добавить два AM_CONDITIONAL в свой configure.ac, HAVE_GCC и HAVE_CLANG с условным тестом, эквивалентным вашей проверке grep. Спасибо! - person Irfy; 11.06.2015
comment
@Irfy - вот для чего нужен CXXFLAGS. Вы можете передать специфические флаги компилятора configure через CXXFLAGS или добавить / изменить CXXFLAGS флаги в configure.ac. Эта переменная также включена в правила сборки C ++. - person Brett Hale; 17.06.2015

Если какой-либо флаг вызывает ошибку, легко написать макрос m4, чтобы определить, поддерживает ли компилятор этот флаг.

Проверьте ax_check_compile_flag из архива autoconf.

person arved    schedule 10.06.2015
comment
Я уверен, что это правильный способ сделать это, но поскольку это внутренний проект, а не распределенный, я выбрал самый простой вариант, которым оказались два AM_CONDITIONALs. - person Irfy; 11.06.2015