GNU autotools: Debug/Release targets?
I've been looking for this for a while: I'm currently converting a medium-size program to autotools, coming from an Eclipse-based method (with makefiles)
I'm always used to having a "debug" build, with all debug symbols and no optimizations, and a "release" build, without debug symbols and best optimizations.
Now I'm trying to replicate this in some way with autotools, so I can (perhaps) do something like:
./configure
make debug
Which would have all debug symbols and no optimizations, and where:
./configure
make
Would result in the "release" version (default)
PS: I've read about the --enable-debug flag/feature, but in my current (simple) setup, using that is unrecognized by configure
ismail's solution is a common approach, but it suffers from some serious problems. If the user tries to get a debug build by doing './configure --enable-debug', the configure script will set CFLAGS to '-g -O2' and the Makefile will use '-g3 -O0 ... -g -O2' when building any executables. In that case, gcc will use -O2, and some compilers will abort because of the conflicting -O options. Either scenario is not the expected behavior.
Building with debug symbols or not is NOT something the project maintainer should worry about at all. This is an issue for the user. If you are building a project and you want to make a debug build or a release build, you should use different options at configure time. For example,
$ mkdir debug
$ mkdir release
$ cd debug && /path/to/configure --prefix=/dbg \
CPPFLAGS=-DDEBUG CFLAGS="-g -O0" && make && make install
$ cd ../release && /path/to/configure CPPFLAGS=-DNDEBUG && make && make install
This will install a build with `-DDEBUG' and '-g -O0' (a "debug build") in /dbg/bin and a 'release' install in /usr/local/bin
You can reduce the tedium of the necessary typing by using a CONFIG_SITE file. For example, you can do:
echo 'CPPFLAGS=-DDEBUG CFLAGS="-g -O0"' >> /dbg/share/config.site
and then all future invocations of 'configure --prefix=/dbg' will automatically inherit the settings to CPPFLAGS and CFLAGS without needing to be specified on the command line.
If, as the package maintainer, you want to provide the user with an easy way to build a "debug release", it is perfectly acceptable to include a script in the distribution that invokes the configure script with the appropriate arguments and invokes make && make install
, but there is absolutely no need to litter your autotool metafiles with such cruft. It simply does not belong there. And be warned, many packages have made attempts to add --enable-debug
which are simply wrong. If the user invokes configure CFLAGS="-g -O0"
but gets a build that applies unexpected flags then you have a bug and your package is broken. This is an all too common experience, and if you maintain a package (currently thinking about tmux
and curl
) in which the user does not get what any reasonable person would call a "debug build" after invoking configure CFLAGS="-g -O0"
, then your package is broken.
An important point that must always be remembered when maintaining a package with the autotools is that the user may be using a completely different tool chain than you are. It is entirely possible that the user's tool chain will require -DMAKE_IT_A_DEBUG
or -DUSE_DEBUG
or -I/non/standard/path/to/headers
. Perhaps it will need -O145
or -Q
passed to the compiler or -debug
passed to the linker, or ... anything. As the maintainer, you simply do not have the information necessary to even make the phrase "debug build" meaningful for all users. So don't try, because you might make the software unbuildable for a certain set of users.
Add a clause to your configure.in
or configure.ac
file;
AC_ARG_ENABLE(debug,
AS_HELP_STRING([--enable-debug],
[enable debugging, default: no]),
[case "${enableval}" in
yes) debug=true ;;
no) debug=false ;;
*) AC_MSG_ERROR([bad value ${enableval} for --enable-debug]) ;;
esac],
[debug=false])
AM_CONDITIONAL(DEBUG, test x"$debug" = x"true")
Now in your Makefile.in
or Makefile.am
;
if DEBUG
AM_CFLAGS = -g3 -O0
AM_CXXFLAGS = -g3 -O0
else
AM_CFLAGS = -O2
AM_CXXFLAGS = -O2
endif
So when debug
is enabled you can modify your {C/CXX}FLAGS
to enable debug information.
The default Makefile created with autotools produces binaries with debug symbos. Use make install-strip
to produce a release target.
Another example to configure CFLAGS
/CXXFLAGS
without editing Makefile.in
or Makefile.am
. Add this code to your configure.in
or configure.ac
file:
test -z "$SED" && SED=sed
AC_ARG_ENABLE([debug],
[AS_HELP_STRING([--enable-debug],
[whether to include debug symbols (default is no)])],
[enable_debug=$enableval],
[enable_debug=no]
)
if test "x$enable_debug" = xyes; then
dnl Remove all optimization flags from CFLAGS
changequote({,})
CFLAGS=`echo "$CFLAGS" | $SED -e 's/-O[0-9s]*//g'`
CXXFLAGS=`echo "$CXXFLAGS" | $SED -e 's/-O[0-9s]*//g'`
CFLAGS=`echo "$CFLAGS" | $SED -e 's/-g[0-9]*//g'`
CXXFLAGS=`echo "$CXXFLAGS" | $SED -e 's/-g[0-9]*//g'`
changequote([,])
CFLAGS="$CFLAGS -g -O0"
CXXFLAGS="$CXXFLAGS -g -O0"
fi
echo "CFLAGS=$CFLAGS"
Test it:
$ ./configure --enable-debug | grep CFLAGS