Search code examples
gccclangautotoolscompiler-options

How to set compiler-specific flags with autotools


We use autotools as our build infrastructure, and we use clang and gcc as compilers. Recently we hit a gcc warning that needed

--param max-vartrack-size=100000000

to silence (without completey disabling gcc's vartracking). Clang doesn't accept that option and produces

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

To silence that, clang needs

-Qunused-arguments

and that produces an error under gcc:

unrecognized command line option ‘-Qunused-arguments’
  1. What is the best way to define compiler-specific flags in configure.ac, after a compiler has been selected with, e.g. AC_PROG_CXX? We AC_SUBST(AM_CXXFLAGS) so I guess I'd be expanding a compiler specific variable within AM_CXXFLAGS.

  2. What is the right way to enable a per-target option in a Makefile.am for just one compiler? I'm thinking of:

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

but I'd need the HAVE_* vars subst'ed from configure.ac. Do AC_PROG_CXX/CC perhaps already define something like this?


Solution

  • AM_CXXFLAGS isn't something you should AC_SUBST. It is reserved for use by automake. If you look at the Makefile generated for a C++ target, you will find definitions for CXXCOMPILE and LTCXXCOMPILE, which always include the AM_CXXFLAGS variable.

    You want to add the (conditional) compiler flag to AM_CXXFLAGS or to libfoo_la_CXXFLAGS. The former will affect all C++ compilations, and the latter just the per-library compilations. So it's just a matter of getting SPECIFIC_CXXFLAGS right in 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)
    

    The GXX test is insufficient as autoconf just tests for the __GNUC__ macro (AFAIK), so clang++ will set: GXX=yes

    The problem is, there isn't a portable way of detecting command line options that are unknown. Intel's icc -v will even reproduce the gcc version string. So you might have to add another filter, like: | grep -v 'icc'

    You could optionally check that the flag works as advertised before AC_SUBST, but this doesn't really help if the compiler only generates a warning:

    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"
    

    Then in Makefile.am:

    AM_CXXFLAGS = $(FOO_SPECIFIC_CXXFLAGS)
    

    or:

    libfoo_la_CXXFLAGS = $(FOO_SPECIFIC_CXXFLAGS)