Bug 28811 - --with-pic vs static libraries and libstdc++
Summary: --with-pic vs static libraries and libstdc++
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 4.1.2
: P3 normal
Target Milestone: ---
Assignee: Benjamin Kosnik
URL:
Keywords: link-failure
Depends on:
Blocks:
 
Reported: 2006-08-22 20:29 UTC by Pawel Sikora
Modified: 2016-11-20 16:49 UTC (History)
5 users (show)

See Also:
Host: x86_64-linux
Target: x86_64-linux
Build: x86_64-linux
Known to work:
Known to fail: 4.2.3
Last reconfirmed: 2009-01-28 01:41:13


Attachments
makefile for testcase (186 bytes, text/plain)
2006-08-22 20:29 UTC, Pawel Sikora
Details
testcase (106 bytes, text/plain)
2006-08-22 20:30 UTC, Pawel Sikora
Details
relocation X against symbol `Y can not be used... (2.60 KB, text/plain)
2016-11-20 06:02 UTC, Alec Ari
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Pawel Sikora 2006-08-22 20:29:09 UTC
i've configured my gcc with -with-pic option and trying
to build statically linked shared c++ library.

$ make
g++ -O2 -g0 -Wall -z defs test.cpp -o libtest.so -fPIC -shared \
                -nodefaultlibs \
                -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic \
                -lc -lgcc_eh
/usr/bin/ld: libtest.so: undefined versioned symbol name
_ZNKSt14basic_ifstreamIcSt11char_traitsIcEE7is_openEv@GLIBCXX_3.4
/usr/bin/ld: failed to set dynamic section sizes: Bad value
collect2: ld returned 1 exit status
Comment 1 Pawel Sikora 2006-08-22 20:29:55 UTC
Created attachment 12113 [details]
makefile for testcase
Comment 2 Pawel Sikora 2006-08-22 20:30:10 UTC
Created attachment 12114 [details]
testcase
Comment 3 Andrew Pinski 2006-08-22 20:35:13 UTC
How sure are you that this is not a binutils bug?
Comment 4 H.J. Lu 2006-08-22 21:39:48 UTC
libstdc++ doesn't supports building PIC archive properly. The archive
shouldn't include symbol version even if it is compiled with PIC since symbol
version info is generated by linker when building a shared library.

In glibc, we use -DSHARED to indicate if a file is compiled for shared library.
We need to change ./src/compatibility.cc from

#if defined(_GLIBCXX_SYMVER_GNU) && defined(PIC)

to

#if defined(_GLIBCXX_SYMVER_GNU) && defined(SHARED)

and define -DSHARED when compiling for shared library.
Comment 5 Andrew Pinski 2006-08-27 04:55:05 UTC
Confirmed.
Comment 6 Pawel Sikora 2006-09-08 12:48:04 UTC
any idea how to fix this? i can test proposals.
Comment 7 littlestar 2007-09-07 05:58:00 UTC
gcc 4.2.1 have the bug too.
Comment 8 Paolo Carlini 2008-06-06 11:56:28 UTC
HJ, are you willing to prepare and test a patch? Many thanks in advance.
Comment 9 Paolo Carlini 2008-06-06 12:01:09 UTC
Apparently, this issue has to do essentially with compatibility.cc, and I'd like to hear its main author...
Comment 10 Jakub Jelinek 2008-06-06 12:14:39 UTC
Doesn't --with-pic build just one set of *.o files?  If yes, then you are out of luck, either configure libstdc++ without symbol versioning, or you need to use
a version script when linking --with-pic libstdc++.a statically.
If no and --with-pic builds everything twice and it is possible to compile
the *.o's intended for libstdc++.so with -DSHARED, then surely replacing
uses of #ifdef PIC with #ifdef SHARED is the way to go.
Or leave compatibility.o from libstdc++.a (not sure if it is easily doable
with libtool).
Comment 11 H.J. Lu 2008-06-06 13:26:59 UTC
Alan checked in a linker patch:

http://sourceware.org/ml/binutils/2008-06/msg00041.html

to specify a file in archive. Is that possible to exclude a file in
archive?
Comment 12 H.J. Lu 2008-06-08 15:45:03 UTC
(In reply to comment #8)
> HJ, are you willing to prepare and test a patch? Many thanks in advance.
> 

Sorry, I may not have time for it in the near future.
Comment 13 Pawel Sikora 2008-11-14 00:32:06 UTC
(In reply to comment #10)

> If no and --with-pic builds everything twice and it is possible to compile
> the *.o's intended for libstdc++.so with -DSHARED,

i thought about something like this:

$ cat makefile
SRCS := test.cpp
all: libtest.so libtest.a
libtest.so: $(SRCS:.cpp=.os)
        g++ -shared -o $@ $<
libtest.a: $(SRCS:.cpp=.o)
        ar cr $@ $<
%.os: %.cpp
        g++ -c -fpic -DSHARED -o $@ $<
%.o: %.cpp
        g++ -c -fpic -o $@ $<

but i can't transform it into autotools templates :/
i saw that elfutils does such trick within src/makefile.am.
Comment 14 Benjamin Kosnik 2009-01-28 01:41:13 UTC
Mine.
Comment 15 Benjamin Kosnik 2009-01-28 03:25:21 UTC
Here are my thoughts on how to fix this. None of the presented options is workable, IMHO.

The preferred end goal is to only have the compatibilty.cc and compatibilty-ldbl.cc objects in the shared library, and not in the static library.

1) HJ's suggestion in #11, to remove compatibility.cc and compatibility-ldbl.cc archive files from the static library via binutils trickery. Alan responded that the capability is limited to removal, but that's what is wanted here. My preference is to not build the (incorrect) object file in the first place.

2) Adding -DSHARED to LTCXXCOMPILE in src/Makefile.am. This doesn't disambiguate between shared and static objects though. Out.

3) Custom rules for compatibility.o and compatibility.lo in src/Makefile.am. the *.lo rule adds -DSHARED and the *.o rule does not. Replace PIC with SHARED in compatibility.cc
This mostly works, as long as the *.o rule is compiled after the *.lo rule. Seems weak to rely on this ordering though.

4) somehow stuff the compatibility objects into a separate, shared-library-only convenience library

?
Comment 16 Richard Biener 2009-08-04 12:27:53 UTC
GCC 4.3.4 is being released, adjusting target milestone.
Comment 17 Richard Biener 2010-05-22 18:11:12 UTC
GCC 4.3.5 is being released, adjusting target milestone.
Comment 18 __vic 2012-06-27 10:19:18 UTC
GCC 4.7.1 still fails to link .so against static libstdc++.a in 64-bit mode:

$ g++ -shared -fPIC -static-libgcc -static-libstdc++ -o 1.so 1.cpp
/usr/bin/ld: /opt/gcc-4.6.1/lib/gcc/x86_64-unknown-linux-gnu/4.6.1/../../../../lib64/libstdc++.a(globals_io.o): relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC
/opt/gcc-4.6.1/lib/gcc/x86_64-unknown-linux-gnu/4.6.1/../../../../lib64/libstdc++.a: could not read symbols: Bad value
collect2: ld returned 1 exit status
make: *** [1.so] Error 1

32-bit mode is working:

$ g++ -m32 -shared -fPIC -static-libgcc -static-libstdc++ -o 1.so 1.cpp
Comment 19 __vic 2012-06-27 10:27:14 UTC
I'm sorry, compiler version was 4.6.1 in previous example.
Output for 4.7.1:

$ g++ -shared -fPIC -static-libgcc -static-libstdc++ -o 1.so 1.cpp
/usr/bin/ld: /opt/gcc-4.7.1/lib/gcc/x86_64-unknown-linux-gnu/4.7.1/../../../../lib64/libstdc++.a(compatibility.o): relocation R_X86_64_32 against `_ZTIN10__cxxabiv115__forced_unwindE' can not be used when making a shared object; recompile with -fPIC
/opt/gcc-4.7.1/lib/gcc/x86_64-unknown-linux-gnu/4.7.1/../../../../lib64/libstdc++.a: could not read symbols: Bad value
collect2: error: ld returned 1 exit status
Comment 20 Benjamin Kosnik 2012-09-20 02:10:32 UTC
Author: bkoz
Date: Thu Sep 20 02:10:22 2012
New Revision: 191509

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=191509
Log:
2012-09-18  Benjamin Kosnik  <bkoz@redhat.com>

        PR libstdc++/28811
        PR libstdc++/54482
        * configure.ac (glibcxx_lt_pic_flag,
          glibcxx_compiler_pic_flag,
          glibcxx_compiler_shared_flag): New. Use them.
        (lt_prog_compiler_pic_CXX): Set via glibcxx_*_flag(s) above.
        (pic_mode): Set to default.
        (PIC_CXXFLAGS): Remove.
        * Makefile.am (PICFLAG, PICFLAG_FOR_TARGET): Remove. Comment.
        * libsupc++/Makefile.am: Use glibcxx_ld_pic_flag and
          glibcxx_compiler_shared_flag. Comment.
        * src/c++11/Makefile.am: Same.
        * src/c++98/Makefile.am: Same.
        * src/Makefile.am: Use glibcxx_compiler_pic_flag.

        * Makefile.in: Regenerated.
        * aclocal.m4: Same.
        * configure: Same.
        * doc/Makefile.in: Same.
        * include/Makefile.in: Same.
        * libsupc++/Makefile.in: Same.
        * po/Makefile.in: Same.
        * python/Makefile.in: Same.
        * src/Makefile.in: Same.
        * src/c++11/Makefile.in: Same.
        * src/c++98/Makefile.in: Same.
        * testsuite/Makefile.in: Same.

        * src/c++11/compatibility-atomic-c++0x.cc: Use
          _GLIBCXX_SHARED instead of PIC to designate shared-only
          code blocks.
        * src/c++11/compatibility-c++0x.cc: Same.
        * src/c++11/compatibility-thread-c++0x.cc: Same.
        * src/c++98/compatibility-list-2.cc: Same.
        * src/c++98/compatibility.cc: : Same.

        * testsuite/17_intro/shared_with_static_deps.cc: New.

        * doc/xml/manual/build_hacking.xml: Separate configure from
        make/build issues, add build details.

Added:
    trunk/libstdc++-v3/testsuite/17_intro/shared_with_static_deps.cc
Modified:
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/Makefile.am
    trunk/libstdc++-v3/Makefile.in
    trunk/libstdc++-v3/aclocal.m4
    trunk/libstdc++-v3/configure
    trunk/libstdc++-v3/configure.ac
    trunk/libstdc++-v3/doc/Makefile.in
    trunk/libstdc++-v3/doc/xml/manual/build_hacking.xml
    trunk/libstdc++-v3/include/Makefile.in
    trunk/libstdc++-v3/libsupc++/Makefile.am
    trunk/libstdc++-v3/libsupc++/Makefile.in
    trunk/libstdc++-v3/po/Makefile.in
    trunk/libstdc++-v3/python/Makefile.in
    trunk/libstdc++-v3/src/Makefile.am
    trunk/libstdc++-v3/src/Makefile.in
    trunk/libstdc++-v3/src/c++11/Makefile.am
    trunk/libstdc++-v3/src/c++11/Makefile.in
    trunk/libstdc++-v3/src/c++11/compatibility-atomic-c++0x.cc
    trunk/libstdc++-v3/src/c++11/compatibility-c++0x.cc
    trunk/libstdc++-v3/src/c++11/compatibility-thread-c++0x.cc
    trunk/libstdc++-v3/src/c++98/Makefile.am
    trunk/libstdc++-v3/src/c++98/Makefile.in
    trunk/libstdc++-v3/src/c++98/compatibility-list-2.cc
    trunk/libstdc++-v3/src/c++98/compatibility.cc
    trunk/libstdc++-v3/testsuite/Makefile.in
Comment 21 Benjamin Kosnik 2012-11-05 23:42:36 UTC
Author: bkoz
Date: Mon Nov  5 23:42:32 2012
New Revision: 193195

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=193195
Log:
2012-11-05  Benjamin Kosnik  <bkoz@redhat.com>

        PR libstdc++/28811
        PR libstdc++/54482
        * configure.ac (glibcxx_lt_pic_flag,
          glibcxx_compiler_pic_flag,
          glibcxx_compiler_shared_flag): New. Use them.
        (lt_prog_compiler_pic_CXX): Set via glibcxx_*_flag(s) above.
        (pic_mode): Set to default.
        (PIC_CXXFLAGS): Remove.
        * Makefile.am (PICFLAG, PICFLAG_FOR_TARGET): Remove. Comment.
        * libsupc++/Makefile.am: Use glibcxx_ld_pic_flag and
          glibcxx_compiler_shared_flag. Comment.
        * src/c++11/Makefile.am: Same.
        * src/c++98/Makefile.am: Same.
        * src/Makefile.am: Use glibcxx_compiler_pic_flag.

        * Makefile.in: Regenerated.
        * aclocal.m4: Same.
        * configure: Same.
        * doc/Makefile.in: Same.
        * include/Makefile.in: Same.
        * libsupc++/Makefile.in: Same.
        * po/Makefile.in: Same.
        * python/Makefile.in: Same.
        * src/Makefile.in: Same.
        * src/c++11/Makefile.in: Same.
        * src/c++98/Makefile.in: Same.
        * testsuite/Makefile.in: Same.

        * src/c++11/compatibility-atomic-c++0x.cc: Use
          _GLIBCXX_SHARED instead of PIC to designate shared-only
          code blocks.
        * src/c++11/compatibility-c++0x.cc: Same.
        * src/c++11/compatibility-thread-c++0x.cc: Same.
        * src/c++98/compatibility-list-2.cc: Same.
        * src/c++98/compatibility.cc: : Same.

        * testsuite/17_intro/shared_with_static_deps.cc: New.

        * doc/xml/manual/build_hacking.xml: Separate configure from
        make/build issues, add build details.


Added:
    branches/gcc-4_7-branch/libstdc++-v3/testsuite/17_intro/shared_with_static_deps.cc
Modified:
    branches/gcc-4_7-branch/libstdc++-v3/ChangeLog
    branches/gcc-4_7-branch/libstdc++-v3/Makefile.am
    branches/gcc-4_7-branch/libstdc++-v3/Makefile.in
    branches/gcc-4_7-branch/libstdc++-v3/configure
    branches/gcc-4_7-branch/libstdc++-v3/configure.ac
    branches/gcc-4_7-branch/libstdc++-v3/doc/Makefile.in
    branches/gcc-4_7-branch/libstdc++-v3/doc/xml/manual/build_hacking.xml
    branches/gcc-4_7-branch/libstdc++-v3/include/Makefile.in
    branches/gcc-4_7-branch/libstdc++-v3/libsupc++/Makefile.am
    branches/gcc-4_7-branch/libstdc++-v3/libsupc++/Makefile.in
    branches/gcc-4_7-branch/libstdc++-v3/po/Makefile.in
    branches/gcc-4_7-branch/libstdc++-v3/python/Makefile.in
    branches/gcc-4_7-branch/libstdc++-v3/src/Makefile.am
    branches/gcc-4_7-branch/libstdc++-v3/src/Makefile.in
    branches/gcc-4_7-branch/libstdc++-v3/src/c++11/Makefile.am
    branches/gcc-4_7-branch/libstdc++-v3/src/c++11/Makefile.in
    branches/gcc-4_7-branch/libstdc++-v3/src/c++11/compatibility-atomic-c++0x.cc
    branches/gcc-4_7-branch/libstdc++-v3/src/c++11/compatibility-c++0x.cc
    branches/gcc-4_7-branch/libstdc++-v3/src/c++11/compatibility-thread-c++0x.cc
    branches/gcc-4_7-branch/libstdc++-v3/src/c++98/Makefile.am
    branches/gcc-4_7-branch/libstdc++-v3/src/c++98/Makefile.in
    branches/gcc-4_7-branch/libstdc++-v3/src/c++98/compatibility-list-2.cc
    branches/gcc-4_7-branch/libstdc++-v3/src/c++98/compatibility.cc
    branches/gcc-4_7-branch/libstdc++-v3/testsuite/Makefile.in
Comment 22 Benjamin Kosnik 2012-11-05 23:43:32 UTC
Fixed on trunk and 4.7 branch
Comment 23 __vic 2013-11-15 06:19:19 UTC
What actual status of this bug is? Is it fixed or still not?
Comment 24 Paolo Carlini 2013-11-15 15:15:07 UTC
Fixed
Comment 25 Alec Ari 2016-11-20 06:02:15 UTC
Created attachment 40087 [details]
relocation X against symbol `Y can not be used...

I still have this problem, just ran git pull on master branch, this is my configure line:

$ cd gcc && mkdir build && cd build

$ ../configure --prefix=/home/<scrubbed>/git-toolchain-bin/usr --with-local-prefix=/home/<scrubbed>/git-toolchain-bin/usr --with-native-system-header-dir=/home/<scrubbed>/git-toolchain-bin/usr/include --disable-nls --disable-shared --disable-multilib --disable-libatomic --disable-libgomp --disable-libmpx --disable-libquadmath --disable-libssp --disable-libvtv --disable-libstdcxx-pch --enable-languages=c,c++ --disable-werror --without-isl --disable-libcilkrts --disable-libitm --disable-libsanitizer --disable-lto --disable-gold

Replacing --disable-libstdcxx-pch with --disable-libstdcxx brings me this:

xg++: error: unrecognized command line option '-funconfigured-libstdc++-v3'

Adding/removing c++ from enabled languages seems to have no effect. Recompiling Binutils (2.27 branch) with CFLAGS="-O2 -fPIC" and CXXFLAGS="${CFLAGS}" added to configure line did not fix the issue (nor change it in any way) and compiling GCC with that same option causes it to die much earlier.

This is as far as I've got so far trying to build a toolchain sysroot, very close!
Comment 26 Alec Ari 2016-11-20 16:49:32 UTC
To avoid fully recompiling GCC, I modified libstdc++-v3/configure (not .ac) and made the following change:

--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -15014,8 +15014,8 @@ if test "$enable_shared" = yes; then
   glibcxx_compiler_shared_flag="-D_GLIBCXX_SHARED"
 
 else
-  glibcxx_lt_pic_flag=
-  glibcxx_compiler_pic_flag=
+  glibcxx_lt_pic_flag="-prefer-pic"
+  glibcxx_compiler_pic_flag="$lt_prog_compiler_pic_CXX"
   glibcxx_compiler_shared_flag=
 fi

Special thanks to the guys in this thread, problem solved.

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58638