I have a C++ project that uses the GNU Autotools for its build scripts and libtool for linking. Recently I have added code coverage instrumentation with gcov, by ensuring that
GCOV_CFLAGS="-fprofile-arcs -ftest-coverage"
GCOV_LDFLAGS="-fprofile-arcs -ftest-coverage"
..get included in my CFLAGS
and LDFLAGS
respectively. On OS X 10.7.4 using g++-4.2 (installed by homebrew), everything works fine.
On Ubuntu 12.04 using g++ 4.6.3, libtool fails to link one of my tests:
/bin/bash ./libtool --tag=CXX --mode=link g++ -Wall -Wextra -Werror -ansi -fprofile-arcs -ftest-coverage -g -O0 -fprofile-arcs -ftest-coverage -L/usr/local/lib -Wl,-rpath -Wl,/usr/local/lib -o myproj/inttests/locale_test myproj/inttests/locale_test.o myproj/app/libapp.la -lboost_thread-mt -lboost_system-mt -pthread -llog4cplus
libtool: link: g++ -Wall -Wextra -Werror -ansi -fprofile-arcs -ftest-coverage -g -O0 -fprofile-arcs -ftest-coverage -Wl,-rpath -Wl,/usr/local/lib -o myproj/inttests/.libs/locale_test myproj/inttests/locale_test.o -pthread -L/usr/local/lib myproj/app/.libs/libapp.so -lboost_thread-mt -lboost_system-mt /usr/lib/liblog4cplus.so -pthread
/usr/bin/ld: myproj/inttests/.libs/locale_test: hidden symbol `atexit' in /usr/lib/x86_64-linux-gnu/libc_nonshared.a(atexit.oS) is referenced by DSO
/usr/bin/ld: final link failed: Bad value
collect2: ld returned 1 exit status
make[2]: *** [myproj/inttests/locale_test] Error 1
How do I fix my build on ubuntu/g++ 4.6?
After googling around I see this thread, which suggests adding --coverage
to CXXFLAGS
when running ./configure
. Indeed, though it didn't work for that poster, it works for me:
./configure CXXFLAGS="--coverage"
However this variable is reserved for the package installer, not the maintainer (me.) The question reduces to "How do I incorporate this into the build properly?"
Here's what's not enough:
GCOV_CFLAGS="-fprofile-arcs -ftest-coverage --coverage"
GCOV_LDFLAGS="-fprofile-arcs -ftest-coverage"
On the assumption that GCOV_CFLAGS
gets included into the effective CXXFLAGS
(not shown, but it does), it seems like this fix should work. It doesn't.
Digging in further, it seems we should at least get some traction if we drop CXXFLAGS="--coverage"
from the command line and instead place it in configure.ac
somewhere. This, actually, also did not work unless the line is placed above the AC_PROG_CXX
call that selects the compiler.
So now we gain a little insight. AC_PROG_CXX
is altering something when it sees --coverage
, which is very likely why the placement in GCOV_CFLAGS
didn't work: it was too late.
Looking carefully through the logs, it appears the secret sauce is the automatic inclusion of -lgcov
in the failing linking step. I'm not sure this library needed to be such a secret, but if I change my variables as so:
GCOV_CFLAGS="-fprofile-arcs -ftest-coverage --coverage"
GCOV_LDFLAGS="-fprofile-arcs -ftest-coverage"
GCOV_LIBS="-lgcov"
..and ensure GCOV_LIBS
is included in LIBS
, then it all works, on all my platforms.
EDIT: See also this thread.