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
--coveragetoCXXFLAGSwhen running./configure. Indeed, though it didn’t work for that poster, it works for me: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:
On the assumption that
GCOV_CFLAGSgets included into the effectiveCXXFLAGS(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 inconfigure.acsomewhere. This, actually, also did not work unless the line is placed above theAC_PROG_CXXcall that selects the compiler.So now we gain a little insight.
AC_PROG_CXXis altering something when it sees--coverage, which is very likely why the placement inGCOV_CFLAGSdidn’t work: it was too late.Looking carefully through the logs, it appears the secret sauce is the automatic inclusion of
-lgcovin the failing linking step. I’m not sure this library needed to be such a secret, but if I change my variables as so:..and ensure
GCOV_LIBSis included inLIBS, then it all works, on all my platforms.EDIT: See also this thread.