"Hidden symbol `atexit' is referenced by DSO" when using libtool with gcov

phs picture phs · Jul 28, 2012 · Viewed 11.6k times · Source

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?

Answer

phs picture phs · Jul 28, 2012

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.