Linker error: std::time_put_w@@GLIBCPP_3.2

138 views
Skip to first unread message

Laurent Birtz

unread,
Mar 13, 2005, 9:43:27 PM3/13/05
to
Hi, I'm getting the following error

.../bin/ld: bin/libsnowjuscan.so: undefined versioned symbol name std::time_put_w@@GLIBCPP_3.2
.../bin/ld: failed to set dynamic section sizes: Bad value

when I try to compile a static shared library using the following command

g++ -shared -Wl,-static -static-libgcc -o libsnowjuscan.so [bunch of .o] /usr/lib/libboost_regex.a

The compilation works fine when I don't attempt the static link. I'm using gcc-3.3.5 (latest version).
I emerged gcc (gentoo linux), emerged glibc, emerged gcc again, emerged lib-compat, emerged boost.
Nothing works.

I'm seeing 2003 posts about the problem. Apparently it is a compiler bug. It appears that either
the bug is still there in the latest versions, or something else is wrong.

Anyone have information about this?

Thanks in advance,
Laurent Birtz

Paul Pluzhnikov

unread,
Mar 13, 2005, 10:26:15 PM3/13/05
to
Laurent Birtz <lauren...@usherbrooke.ca> writes:

> Hi, I'm getting the following error ...

> when I try to compile a static shared library using the following command
>
> g++ -shared -Wl,-static -static-libgcc -o libsnowjuscan.so [bunch of .o] /usr/lib/libboost_regex.a

This command line is totally bogus. It tells g++ to build a shared
library and tells 'ld' (behind gcc's back) to use static linking,
which is impossible if you are building a *dynamic* (aka shared,
aka DSO -- dynamic shared object) library.

> Apparently it is a compiler bug.

It's not a compiler bug. It's a case of "pilot error":
http://catb.org/~esr/jargon/html/P/pilot-error.html

Cheers,
--
In order to understand recursion you must first understand recursion.
Remove /-nsp/ for email.

Laurent Birtz

unread,
Mar 14, 2005, 12:12:41 AM3/14/05
to
> This command line is totally bogus. It tells g++ to build a shared
> library and tells 'ld' (behind gcc's back) to use static linking,
> which is impossible if you are building a *dynamic* (aka shared,
> aka DSO -- dynamic shared object) library.
>
>
>>Apparently it is a compiler bug.
>
>
> It's not a compiler bug. It's a case of "pilot error":
> http://catb.org/~esr/jargon/html/P/pilot-error.html

I refer you to this Wiki: http://www.wlug.org.nz/SharedLibraryNotes

I'm trying to create a static dynamic library. That means that while
the library is dynamically linked, its dependencies are statically
linked. I'm pasting the relevant text here:


In some cases you may not want your shared library to have any extra
dependencies. In such a case you want your shared library to have its
dependencies statically linked in. Even a simple shared library will
have a couple of dependences.

The obvious way to statically link these dependencies would be:

gcc -shared -static -o libsam.so sam.c

This will either not work, or give an error message like:

gcc: -shared and -static|pie|fPIE|fpie|fno-PIC|fno-pic|nopie are incompatible

However, it is possible to directly tell the linker we want static linking,
and then magic will happen:

gcc -shared -Wl,-static -o libsam.so sam.c

ldd ./libsam.so
statically linked

libsam.so is still a valid shared library, it just lacks any external dependency.
In some cases you might need the command-line option -static-libgcc for this to work.


I need to do this because the applications in my distributed computing system
are distributed using shared libraries. I do not want the shared libraries to
depend on the librairies installed on the user computers.

The command above works fine for simple C++ applications. Trouble seemingly arises
when I try to link against the Boost libraries.

Thanks,
Laurent Birtz

Paul Pluzhnikov

unread,
Mar 14, 2005, 2:26:48 AM3/14/05
to
Laurent Birtz <lauren...@usherbrooke.ca> writes:

> I refer you to this Wiki: http://www.wlug.org.nz/SharedLibraryNotes

Internet is full of pages "which contain many omissions, and contain
much that is apocryphal, or at least wildly inaccurate" (just as HHttG).

The page you are citing is but one sad example.

> I'm trying to create a static dynamic library.

There ain't no such thing [1]. You better stop using this term.

> That means that while
> the library is dynamically linked, its dependencies are statically
> linked.

That's no "static shared library". That's just a *regular* shared
library, with more objects linked into it then there normally
would be.

> I'm pasting the relevant text here:

And thus propagate inaccurate information further.
That doesn't make it any more correct.

> However, it is possible to directly tell the linker we want static linking,
> and then magic will happen:

As you have observed, the magic does *not* happen. It doesn't work,
and it doesn't make sense for it work. The fact that it *happens*
to work for some libraries on some systems doesn't make this correct.

The author of this wiki page is practicing "Cargo Cult Science":
http://www.physics.brocku.ca/etc/cargo_cult_science.html

> I need to do this because the applications in my distributed computing system
> are distributed using shared libraries.

Ok, now that you have told us what it is you *really* are trying
to do, I can offer some advice. The correct command line would be:

g++ -shared -static-libgcc -o libsnowjuscan.so [bunch of .o] /usr/lib/libboost_regex.a

This should get rid of all undefined symbols from libboost_regex.a

If you want to also get rid of libstdc++ dependencies, that's a
bit trickier. Detailed instructions could be found here:

http://groups-beta.google.com/group/comp.os.linux.development.apps/msg/ba5e8db73b87e97f?dmode=source

[1] Actually there did exist such a thing long long time ago, but
none of the modern systems use "static shared libraries" anymore.
You can read about what this term really means here:
http://www.iecc.com/linker/linker09.html

Laurent Birtz

unread,
Mar 14, 2005, 2:59:36 PM3/14/05
to
>> I'm trying to create a static dynamic library.
>
> There ain't no such thing [1]. You better stop using this term.
>
> That's no "static shared library". That's just a *regular* shared
> library, with more objects linked into it then there normally
> would be.

OK, thanks for correcting me.

> As you have observed, the magic does *not* happen. It doesn't work,
> and it doesn't make sense for it work. The fact that it *happens*
> to work for some libraries on some systems doesn't make this correct.
>
> The author of this wiki page is practicing "Cargo Cult Science":
> http://www.physics.brocku.ca/etc/cargo_cult_science.html

Got it.

>> I need to do this because the applications in my distributed computing system
>> are distributed using shared libraries.
>
>
> Ok, now that you have told us what it is you *really* are trying
> to do, I can offer some advice. The correct command line would be:
>
> g++ -shared -static-libgcc -o libsnowjuscan.so [bunch of .o] /usr/lib/libboost_regex.a
>
> This should get rid of all undefined symbols from libboost_regex.a
>
> If you want to also get rid of libstdc++ dependencies, that's a
> bit trickier. Detailed instructions could be found here:

I've read the threads and tried what you said:

> ls -l libstdc++.a
... libstdc++.a -> /usr/lib/gcc-lib/i386-pc-linux-gnu/3.3.5/libstdc++.a

> g++ -shared -o bin/libsnowjuscan.so [the .o] /usr/lib/libboost_regex.a ./libstdc++.a
OR
> g++ -shared -o bin/libsnowjuscan.so [the .o] /usr/lib/libboost_regex.a -L . -lstdc++
OR
> same with -static-libgcc, -m386



.../bin/ld: bin/libsnowjuscan.so: undefined versioned symbol name std::time_put_w@@GLIBCPP_3.2
.../bin/ld: failed to set dynamic section sizes: Bad value

As you said, "it is surprizingly difficult to get rid of dynamic libstdc++ dependency".
I checked if the symbol was in libstdc++:

> nm -g libstdc++.a | grep GLIBC

00000000 B _ZSt10time_put_w@@GLIBCPP_3.2

I think it is defined there, in the BSS section. The dynamic link shows that my library has the
following dependencies:

> ldd bin/libsnowjuscan.so

libstdc++.so.5 => /usr/lib/gcc-lib/i386-pc-linux-gnu/3.3.5/libstdc++.so.5 (0x400a2000)
libm.so.6 => /lib/libm.so.6 (0x4015c000)
libgcc_s.so.1 => /usr/lib/gcc-lib/i386-pc-linux-gnu/3.3.5/libgcc_s.so.1 (0x40180000)
libc.so.6 => /lib/libc.so.6 (0x40188000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x80000000)

What I can't find is the place where the symbol is used. Using 'nm' on the boost library and
on my object files does not return any reference to time_put_w.

I did a minimal program that triggers the problem (file name is test.cc):

#include <iostream>

int main()
{
std::cout << "forcing to use libstdc++\n";
return 0;
}

Compilation command:

> g++ -shared test.cc -o libtest.so -L . -l stdc++

...bin/ld: libtest.so: undefined versioned symbol name std::time_put_w@@GLIBCPP_3.2

I'm not sure what to try next.


Thanks for the help thus far,
Laurent Birtz

Paul Pluzhnikov

unread,
Mar 14, 2005, 11:07:22 PM3/14/05
to
Laurent Birtz <lauren...@usherbrooke.ca> writes:

> I did a minimal program that triggers the problem (file name is test.cc):

Great. I've reproduced the problem (although I get a different symbol):

/usr/local/gcc-3.3.2/bin/g++ -fPIC -shared -o junk.so junk.cc -L.
/usr/bin/ld: junk.so: undefined versioned symbol name std::time_get_c@@GLIBCPP_3.2

> I'm not sure what to try next.

The bad news is that this is a bug in the way gcc-3.3.x libstdc++.a
is built. The bug does not show up in gcc-3.2.x, nor in gcc-3.4.x.

> What I can't find is the place where the symbol is used.

It's not being used. It is mistakenly defined in an archive library,
which the linker is not expecting.

So, if you can build with gcc-3.4.x (which I am guessing you could,
as you are trying to eliminate C++ dependencies to begin with,
and your users (in theory) should not care which version you used),
then that's the cleanest solution.

If for whatever reason you have to build with gcc-3.3.5, then you
need to figure out how versioned symbols get into the
libstdc++.a(globals.o), and fix the build so they don't.

Here is what the picture of "versioned symbols in libstdc++.a" looks like:

$ for i in gcc*; do
echo $i:
nm -A $($i/bin/g++ -print-file-name=libstdc++.a) | grep @ | head -1
done

gcc-2.95.3:
gcc-3.1:
gcc-3.2:
gcc-3.3:
gcc-3.3/bin/../lib/gcc-lib/i686-pc-linux-gnu/3.3/../../../libstdc++.a:globals.o:00000000 R _ZNSt10__num_base8_S_atomsE@@GLIBCPP_3.2
gcc-3.3.2:
gcc-3.3.2/bin/../lib/gcc-lib/i686-pc-linux-gnu/3.3.2/../../../libstdc++.a:globals.o:00000000 R _ZNSt10__num_base8_S_atomsE@@GLIBCPP_3.2
gcc-3.4.0:
gcc-3.4.3:
gcc-4.0:

Laurent Birtz

unread,
Mar 17, 2005, 7:10:37 PM3/17/05
to
> The bad news is that this is a bug in the way gcc-3.3.x libstdc++.a
> is built. The bug does not show up in gcc-3.2.x, nor in gcc-3.4.x.

Good! Thanks for tracking down the problem. I linked with
libstdc++ of gcc-3.4.3, and the trouble has gone away.

I'll tell my users to use gcc-3.4 explicitely (until gcc-3.4 or later
becomes the norm).

Thanks for your time,
Laurent Birtz

Reply all
Reply to author
Forward
0 new messages