I have problems linking executable with C++ library with --as-needed ld flag while linking with gcc succeeds. During investigation I found inconsistency in gcc and g++ calls concerning --as-needed. First I will show you what I do next I'll summarize what is this bug about:
* What I do: First I compile/link objects which will be included in library: libtool --mode=compile i686-pc-linux-gnu-g++ -c -g -O2 -pthread sync.cpp i686-pc-linux-gnu-g++ -c -g -O2 -pthread sync.cpp -fPIC -DPIC -o .libs/sync.o i686-pc-linux-gnu-g++ -c -g -O2 -pthread sync.cpp -o sync.o >/dev/null 2>&1 All objects I linked in the same way. Next library is linked itself (I've edited output to simplify reading so there could be some typos): libtool --mode=link i686-pc-linux-gnu-g++ -o libgigabase_r.la class.lo compiler.lo database.lo replicator.lo hashtab.lo file.lo symtab.lo btree.lo rtree.lo cursor.lo query.lo pagepool.lo wwwapi.lo unisock.lo blob.lo container.lo exception.lo localcli.lo sync.lo -pthread -rpath /usr/lib -version-info 2 i686-pc-linux-gnu-g++ -shared -nostdlib /usr/lib/gcc/i686-pc-linux-gnu/4.1.2/../../../crti.o /usr/lib/gcc/i686-pc-linux-gnu/4.1.2/crtbeginS.o .libs/class.o .libs/compiler.o .libs/database.o .libs/replicator.o .libs/hashtab.o .libs/file.o .libs/symtab.o .libs/btree.o .libs/rtree.o .libs/cursor.o .libs/query.o .libs/pagepool.o .libs/wwwapi.o .libs/unisock.o .libs/blob.o .libs/container.o .libs/exception.o .libs/localcli.o .libs/sync.o -L/usr/lib/gcc/i686-pc-linux-gnu/4.1.2 -L/usr/lib/gcc/i686-pc-linux-gnu/4.1.2/../../../../i686-pc-linux-gnu/lib -L/usr/lib/gcc/i686-pc-linux-gnu/4.1.2/../../.. -lstdc++ -lm -lc -lgcc_s /usr/lib/gcc/i686-pc-linux-gnu/4.1.2/crtendS.o /usr/lib/gcc/i686-pc-linux-gnu/4.1.2/../../../crtn.o -pthread -Wl,-soname -Wl,libgigabase_r.so.2 -o .libs/libgigabase_r.so.2.0.0 (cd .libs && rm -f libgigabase_r.so.2 && ln -s libgigabase_r.so.2.0.0 libgigabase_r.so.2) (cd .libs && rm -f libgigabase_r.so && ln -s libgigabase_r.so.2.0.0 libgigabase_r.so) i686-pc-linux-gnu-ar cru .libs/libgigabase_r.a class.o compiler.o database.o replicator.o hashtab.o file.o symtab.o btree.o rtree.o cursor.o query.o pagepool.o wwwapi.o unisock.o blob.o container.o exception.o localcli.o sync.o i686-pc-linux-gnu-ranlib .libs/libgigabase_r.a creating libgigabase_r.la (cd .libs && rm -f libgigabase_r.la && ln -s ../libgigabase_r.la libgigabase_r.la) Now I link two programs (subsql and guess) against libgigabase_r.so. While subsql builds successfully: i686-pc-linux-gnu-g++ -c -g -O2 -pthread subsql.cpp i686-pc-linux-gnu-g++ -c -g -O2 -pthread server.cpp libtool --mode=link i686-pc-linux-gnu-g++ -Wl,--as-needed -pthread -o subsql subsql.o server.o libgigabase_r.la i686-pc-linux-gnu-g++ -Wl,--as-needed -pthread -o .libs/subsql subsql.o server.o ./.libs/libgigabase_r.so creating subsql guess programm do not: i686-pc-linux-gnu-g++ -c -g -O2 -pthread guess.cpp libtool --mode=link i686-pc-linux-gnu-g++ -Wl,--as-needed -pthread -o guess guess.o libgigabase_r.la i686-pc-linux-gnu-g++ -Wl,--as-needed -pthread -o .libs/guess guess.o ./.libs/libgigabase_r.so ./.libs/libgigabase_r.so: undefined reference to `pthread_key_create' ./.libs/libgigabase_r.so: undefined reference to `pthread_getspecific' ./.libs/libgigabase_r.so: undefined reference to `pthread_create' ./.libs/libgigabase_r.so: undefined reference to `pthread_key_delete' ./.libs/libgigabase_r.so: undefined reference to `pthread_detach' ./.libs/libgigabase_r.so: undefined reference to `pthread_setspecific' ./.libs/libgigabase_r.so: undefined reference to `pthread_join' collect2: ld returned 1 exit status make: *** [guess] Error 1 * What is this bug about: As you noticed libtool links library with -nostdlib and this dependency on libpthread is missed in .libs/libgigabase_r.so. On pthreads mailing list I was assured that it's Ok to avoid this dependency and even sometimes this is useful. Why the first linkage succeeds while second not. I've looked at object files which are used to build final executables and found the differences between them. The object sever.o (which is used to build subsql) has pthread_* functions in elf Symbol table (part of output of readelf -W -a): 00002899 00006602 R_386_PC32 00000000 pthread_create and in .symtab: 102: 00000000 0 NOTYPE GLOBAL DEFAULT UND pthread_create while the only object file guess.o (which is used to build guess) do not have any references to pthread_*(). Why I think this bug is in g++. I found that substitution of g++ to gcc during last linkage fixes compilation problem. While it seems to be wrong to link C++ program with gcc I've compared verbose output of gcc calls and found that difference in the output. g++ as well as gcc call collect2 but with a bit different options. g++ call of collect2 misses this part completely (which follows after other objects): --no-as-needed -lpthread -lc -lgcc --as-needed Just for record both calls here: ============================================================ [pva in ~/gigabase/gigabase] $=> i686-pc-linux-gnu-g++ -Wl,--as-needed -pthread -o .libs/guess guess.o ./.libs/libgigabase_r.so -v Using built-in specs. Target: i686-pc-linux-gnu Configured with: /var/tmp/portage/sys-devel/gcc-4.1.2/work/gcc-4.1.2/configure --prefix=/usr --bindir=/usr/i686-pc-linux-gnu/gcc-bin/4.1.2 --includedir=/usr/lib/gcc/i686-pc-linux-gnu/4.1.2/include --datadir=/usr/share/gcc-data/i686-pc-linux-gnu/4.1.2 --mandir=/usr/share/gcc-data/i686-pc-linux-gnu/4.1.2/man --infodir=/usr/share/gcc-data/i686-pc-linux-gnu/4.1.2/info --with-gxx-include-dir=/usr/lib/gcc/i686-pc-linux-gnu/4.1.2/include/g++-v4 --host=i686-pc-linux-gnu --build=i686-pc-linux-gnu --disable-altivec --enable-nls --without-included-gettext --with-system-zlib --disable-checking --disable-werror --enable-secureplt --disable-libunwind-exceptions --disable-multilib --disable-libmudflap --disable-libssp --disable-libgcj --enable-languages=c,c++ --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu Thread model: posix gcc version 4.1.2 (Gentoo 4.1.2) /usr/libexec/gcc/i686-pc-linux-gnu/4.1.2/collect2 --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o .libs/guess /usr/lib/gcc/i686-pc-linux-gnu/4.1.2/../../../crt1.o /usr/lib/gcc/i686-pc-linux-gnu/4.1.2/../../../crti.o /usr/lib/gcc/i686-pc-linux-gnu/4.1.2/crtbegin.o -L/usr/lib/gcc/i686-pc-linux-gnu/4.1.2 -L/usr/lib/gcc/i686-pc-linux-gnu/4.1.2 -L/usr/lib/gcc/i686-pc-linux-gnu/4.1.2/../../../../i686-pc-linux-gnu/lib -L/usr/lib/gcc/i686-pc-linux-gnu/4.1.2/../../.. --as-needed guess.o ./.libs/libgigabase_r.so -lstdc++ -lm -lgcc_s -lgcc -lpthread -lc -lgcc_s -lgcc /usr/lib/gcc/i686-pc-linux-gnu/4.1.2/crtend.o /usr/lib/gcc/i686-pc-linux-gnu/4.1.2/../../../crtn.o ./.libs/libgigabase_r.so: undefined reference to `pthread_key_create' ./.libs/libgigabase_r.so: undefined reference to `pthread_getspecific' ./.libs/libgigabase_r.so: undefined reference to `pthread_create' ./.libs/libgigabase_r.so: undefined reference to `pthread_key_delete' ./.libs/libgigabase_r.so: undefined reference to `pthread_detach' ./.libs/libgigabase_r.so: undefined reference to `pthread_setspecific' ./.libs/libgigabase_r.so: undefined reference to `pthread_join' collect2: ld returned 1 exit status [pva in ~/gigabase/gigabase] $=> i686-pc-linux-gnu-gcc -Wl,--as-needed -pthread -o .libs/guess guess.o ./.libs/libgigabase_r.so -v Using built-in specs. Target: i686-pc-linux-gnu Configured with: /var/tmp/portage/sys-devel/gcc-4.1.2/work/gcc-4.1.2/configure --prefix=/usr --bindir=/usr/i686-pc-linux-gnu/gcc-bin/4.1.2 --includedir=/usr/lib/gcc/i686-pc-linux-gnu/4.1.2/include --datadir=/usr/share/gcc-data/i686-pc-linux-gnu/4.1.2 --mandir=/usr/share/gcc-data/i686-pc-linux-gnu/4.1.2/man --infodir=/usr/share/gcc-data/i686-pc-linux-gnu/4.1.2/info --with-gxx-include-dir=/usr/lib/gcc/i686-pc-linux-gnu/4.1.2/include/g++-v4 --host=i686-pc-linux-gnu --build=i686-pc-linux-gnu --disable-altivec --enable-nls --without-included-gettext --with-system-zlib --disable-checking --disable-werror --enable-secureplt --disable-libunwind-exceptions --disable-multilib --disable-libmudflap --disable-libssp --disable-libgcj --enable-languages=c,c++ --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu Thread model: posix gcc version 4.1.2 (Gentoo 4.1.2) /usr/libexec/gcc/i686-pc-linux-gnu/4.1.2/collect2 --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o .libs/guess /usr/lib/gcc/i686-pc-linux-gnu/4.1.2/../../../crt1.o /usr/lib/gcc/i686-pc-linux-gnu/4.1.2/../../../crti.o /usr/lib/gcc/i686-pc-linux-gnu/4.1.2/crtbegin.o -L/usr/lib/gcc/i686-pc-linux-gnu/4.1.2 -L/usr/lib/gcc/i686-pc-linux-gnu/4.1.2 -L/usr/lib/gcc/i686-pc-linux-gnu/4.1.2/../../../../i686-pc-linux-gnu/lib -L/usr/lib/gcc/i686-pc-linux-gnu/4.1.2/../../.. --as-needed guess.o ./.libs/libgigabase_r.so -lgcc --as-needed -lgcc_s --no-as-needed -lpthread -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/i686-pc-linux-gnu/4.1.2/crtend.o /usr/lib/gcc/i686-pc-linux-gnu/4.1.2/../../../crtn.o [pva in ~/gigabase/gigabase] $=> ============================================================ That is the inconsistency between gcc and g++. [1] http://groups.google.com/group/comp.programming.threads/browse_thread/thread/5243754283a02465/5d73e8a1425663fe#5d73e8a1425663fe Thank you very much for your time, Peter. -- Summary: inconsitency between gcc and g++ when linking with --as- needed Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: pva at gentoo dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31774