petersohn
petersohn

Reputation: 11730

Default compiler flags with Autotools

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:

Upvotes: 32

Views: 34128

Answers (7)

Dylan Cali
Dylan Cali

Reputation: 1479

The points regarding not surprising the user are valid, but some flags are reasonable to turn on by default (e.g. -Wall -Wextra), and other flags are code base specific and are sometimes needed (e.g. -std=gnu99).

The question then becomes how to do this portably. I personally steal the flag check macros from the libuv project. To do this I add libuv-check-flags.m4 to the m4 directory of my project. I can then do the following in my configure.ac:

m4_include([m4/libuv-check-flags.m4])
AM_INIT_AUTOMAKE([-Wall -Werror foreign 1.11.2])

# Checks for programs.
AC_PROG_CC
CC_CHECK_CFLAGS_APPEND([-std=gnu99])
CC_CHECK_CFLAGS_APPEND([-Wall])
CC_CHECK_CFLAGS_APPEND([-Wextra])
AC_PROG_LIBTOOL

My generated configure file then produces a compiler command line of:

gcc -g -O2 -std=gnu99 -Wall -Wextra

I can still override the -g -O2 default using the solutions above, e.g.:

./configure CFLAGS='-O0 -g'

Produces a command line of:

gcc -O0 -g -std=gnu99 -Wall -Wextra

And leveraging gcc semantics I can still disable base flags if necessary. For example I can disable warnings if I really really want to with:

./configure CFLAGS='-Wno-all -Wno-extra'

You may say, "well what if the compiler doesn't support those flags?" That's why these macros are so useful and great, since they ensure compiler features are checked first, so -Wall and -Wextra wouldn't be added in the first place if they weren't supported.

libuv is one of the most portable and widely used C libraries on the planet, so I think following their lead is reasonable. And while these macros are pure C specific, adapting them for use with CXXFLAGS would be trivial.

References:

Upvotes: 0

Annesley Newholm
Annesley Newholm

Reputation: 36

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().

Upvotes: 1

William Pursell
William Pursell

Reputation: 212544

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)

Upvotes: 9

malex984
malex984

Reputation: 329

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.

Upvotes: 22

krico
krico

Reputation: 5728

On your Makefile.am you can define them with

programname_CXXFLAGS=-O0 -g

Updated: 20100628

You should try and add the CXXFLAGS in configure.in before calling AC_PROG_CXX. I did not test it, but your configure.in should look something like

AC_INIT
...
CXXFLAGS=-MY -FLAGS
...
AC_PROG_CXX

Please, let me know if this works since I am curious :-)

Upvotes: 0

Norman Gray
Norman Gray

Reputation: 12514

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.

Upvotes: 3

petersohn
petersohn

Reputation: 11730

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

Upvotes: 7

Related Questions