Default compiler flags with Autotools

30,011

Solution 1

Meanwhile I figured out how to do it. I will give an explanation to this.

The basic thing is that Autoconf substitutes shell variables in Makefile.in. The question is how do I get the value of these variables? The answer is that the initialization command substitutes variables that are told them at command line (like ./configure 'CXXFLAGS=-O0 -g'), and otherwise they are substituted by whatever command defines the default (for example, CXXFLAGS is set by AC_PROG_CXX) if they are not empty. So the solution is to set our new default before AC_PROG_CXX but after substitutions from the command lines are made. For example:

if test -z $CXXFLAGS; then
    CXXFLAGS='-O2'
fi
AC_PROG_CXX

Solution 2

According to autoconf manual (about AC_PROG_CC):

If using the GNU C compiler, set shell variable GCC to ‘yes’. If output variable CFLAGS was not already set, set it to -g -O2 for the GNU C compiler (-O2 on systems where GCC does not accept -g), or -g for other compilers. If your package does not like this default, then it is acceptable to insert the line

: ${CFLAGS=""}

after AC_INIT and before AC_PROG_CC to select an empty default instead.

Similarly, according to autoconf manual (about AC_PROG_CXX):

If using the GNU C++ compiler, set shell variable GXX to ‘yes’. If output variable CXXFLAGS was not already set, set it to -g -O2 for the GNU C++ compiler (-O2 on systems where G++ does not accept -g), or -g for other compilers. If your package does not like this default, then it is acceptable to insert the line

: ${CXXFLAGS=""}

after AC_INIT and before AC_PROG_CXX to select an empty default instead.

Solution 3

If you merely want to have the default flags set for yourself whenever you run configure, there are (at least) 3 good ways to do it. Either set CXXFLAGS in your environment (eg in .login or .bashrc), use a CONFIG_SITE environment variable to specify a config file, or set the value you want for CXXFLAGS in $prefix/share/config.site. If you want to set the default flags to something other than '-O2 -g' for all users of your package, then you need to change what you want because doing so violates the principal of least surprise. Anyone familiar with autoconf expects the default flags to be -O2 -g and you should not change that.

Go with the 3rd option given above, and just do

$ echo 'CXXFLAGS="-O0 -g"' > /usr/local/share/config.site

(or redirect to wherever you typically set $prefix, eg $HOME/share/config.site) As an added bonus, this will set CXXFLAGS for all autoconfiscated projects that you configure, not just your own. (Assuming you set prefix appropriately. If you want a config.site to be valid for all projects regardless of prefix, then use a CONFIG_SITE setting)

Solution 4

You can set target-specific defaults in the Makefile.am, or you can set the default in the configure.ac, and that'll apply to everything you build in the project.

See section 4.8.1 (and 5.10.4) in the autoconf manual.

Note the remarks in 4.8.1 about not second-guessing the eventual package user: if you do want to set flags that the user shouldn't be concerned with then set them using AM_CXXFLAGS, flags such as this that the user should be able to override should be set in CXXFLAGS.

But... do you really want to do this?

  1. You say 'debugging will become impossible'. Have you tried this and seen something go wrong? The compiler/debugger is possibly cleverer than you give it credit for.
  2. What's a good default for you at development time is not necessarily a good default for the eventual user at build time. If it really is necessary to turn off optimisation during development, then just configure your development system with ./configure CXXFLAGS='-O0 -g', exactly as you described. If your configure.ac is written correctly, that'll configure your build without optimisation whilst leaving the (good) default unchanged.

Short version: the way you're doing now is the right way.

Edited to add:

In general, if a shell variable appears as an argument to AC_SUBST (either explicitly or, as in the case of things like CXXFLAGS, implicitly within some other command), then it is substituted into the output files. That is, after AC_SUBST(foo), the value of the $foo variable in the ./configure script will be substituted into @foo@ instances.

Solution 5

Building on the answers above, I added this to configure.ac:

AC_ARG_WITH(debug, [  --with-debug            add the debugging module], [AC_DEFINE(WITH_DEBUG,1,0)
AC_SUBST(WITH_DEBUG,1)
CXXFLAGS="-O0 -ggdb"])

It also defines WITH_DEBUG in the AC_CONFIG_HEADERS(config.h) and adds it to the Makefile with AC_SUBST().

Share:
30,011
petersohn
Author by

petersohn

Updated on February 17, 2020

Comments

  • petersohn
    petersohn about 4 years

    I want to know how to set default compiler/linker/etc. flags if I use Autoconf/Automake combo.

    For example, the default compiler flag is "-O2 -g" if I don't set anything. I can just override it with something else, for example if I want to debug:

    ./configure 'CXXFLAGS=-O0 -g'
    

    But I find the default configuration stupid because if I enable optimization, debugging will become impossible. So the default flags should either be "-O2" or "-O0 -g", if I run configure without arguments. How do I do it?

    Edit: I tried the following solutions:

    • Put progname_CXXFLAGS=whatever to Makefile.am. It doesn't work, because it adds the flags to the default flags instead of replacing them.
    • Put CXXFLAGS=whatever into configure.ac. This works, but then I can't override it later.