Creating a dynamic library that has some dependencies statically linked in.

50 views
Skip to first unread message

Kannan Goundan

unread,
Aug 29, 2006, 9:25:47 PM8/29/06
to
I'm creating a dynamic library for use with JNI. It's a C++ library
compiled with GCC on Linux, Solaris, and AIX. The .so file has
dependencies on libc, libstdc++, libm, libgcc, and a couple others.

I'd like to make it so that the .so only has dependencies on some of
those libraries; the rest should be statically linked in. I can't
figure out what options to pass to GCC (I'm linking with the "g++"
command) to make that happen. I tried using "-static" (in addition to
"-shared"), but that didn't work:

g++ -shared -static -o MyLib.so file1.o file2.o

The resulting "MyLib.so" file still has same dependencies as when I
didn't pass in "-static".

I did find the option to statically link libgcc ("-static-libgcc") but
am unsure if this will work correctly. The man page says that
exceptions will not work across shared libraries. If I manage to
statically link all the C++-based libraries, then it is safe to use
"-static-libgcc", right?

Paul Pluzhnikov

unread,
Aug 30, 2006, 12:00:43 AM8/30/06
to
"Kannan Goundan" <cak...@yahoo.com> writes:

> I tried using "-static" (in addition to
> "-shared"), but that didn't work:

The '-static' is meaningless when you are building a *shared* library.
Besides, you should almost never use '-static' (unless you *really*
really know what you are doing).

A complete recipe is:

ln -s $(g++ -print-file-name=libstdc++.a) ./
g++ -shared -o MyLib.so file1.o file2.o -L. -static-libgcc
rm -f ./libstdc++.a

You may also find advice to do "-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic".
Ignore that advice, it doesn't work.

> I did find the option to statically link libgcc ("-static-libgcc") but
> am unsure if this will work correctly. The man page says that
> exceptions will not work across shared libraries.

Correct.
But you aren't going to throw exceptions across JNI libraries,
are you?

Usually, people try to reduce complexity by linking all native code
into a single JNI library. And if you do that, then all exceptions
should stay within the library, which works fine.

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

Kannan Goundan

unread,
Sep 8, 2006, 12:04:37 AM9/8/06
to
Paul Pluzhnikov wrote:
> "Kannan Goundan" <cak...@yahoo.com> writes:

> A complete recipe is:
>
> ln -s $(g++ -print-file-name=libstdc++.a) ./
> g++ -shared -o MyLib.so file1.o file2.o -L. -static-libgcc
> rm -f ./libstdc++.a

Thanks for the help. The commands you provided work for me on a couple
Linux machines but fail on one Linux machine and on both Solaris 8 and
9.

-------- Linux failure --------
/usr/bin/ld: Output/libHelper.so: undefined versioned symbol name
std::time_put_w@@GLIBCPP_3.2
/usr/bin/ld: failed to set dynamic section sizes: Bad value

------- Solaris 8/9 failure --------
Text relocation remains referenced
against symbol offset in file
<unknown> 0x98 links/libstdc++.a(locale.o)
<unknown> 0x9c links/libstdc++.a(locale.o)
<unknown> 0xa0 links/libstdc++.a(locale.o)
[...snip...]
std::ctype<wchar_t>::~ctype() 0xc links/libstdc++.a(ctype.o)
std::ctype<wchar_t>::~ctype() 0x8 links/libstdc++.a(ctype.o)
__trans_upper 0x34 links/libstdc++.a(ctype.o)
[...10,000 more of the same type of entries...]
ld: fatal: relocations remain against allocatable but non-writable
sections

Any idea what the problem could be?

> You may also find advice to do "-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic".
> Ignore that advice, it doesn't work.

When should that form be used? Will it work for libraries other than
"libstdc++"?

Paul Pluzhnikov

unread,
Sep 8, 2006, 10:56:53 AM9/8/06
to
"Kannan Goundan" <cak...@yahoo.com> writes:

>> A complete recipe is:
>>


> Thanks for the help. The commands you provided work for me on a couple
> Linux machines but fail on one Linux machine

*Why* are you building on multiple machines?
You should build this library on just *one* Linux machine (with the
lowest revision of glibc you plan to support).

> -------- Linux failure --------
> /usr/bin/ld: Output/libHelper.so: undefined versioned symbol name
> std::time_put_w@@GLIBCPP_3.2
> /usr/bin/ld: failed to set dynamic section sizes: Bad value

A bug in gcc-3.2; see this thread for discussion:
http://groups.google.com/group/gnu.gcc.help/msg/cd63e2ff1e16536e

> ------- Solaris 8/9 failure --------
> Text relocation remains referenced
> against symbol offset in file
> <unknown> 0x98 links/libstdc++.a(locale.o)
> <unknown> 0x9c links/libstdc++.a(locale.o)

The problem here is that libstdc++.a is not built with -fPIC.
You'll also hit that same problem on Linux x86_64, and any other
non-x86 UNIX where -fPIC and non-fPIC code is different.

The best solution is to rebuild libstdc++.a with -fPIC.

Alternatively, you can link with '-Wl,-z,textoff'.
Unfortunately. 'g++' adds '-z text' on its own, and ld complains:
ld: fatal: option -ztextoff and -ztext are incompatible
To overcome that, you'll have to either modify gcc "specs" file,
or simply "capture" the link like that g++ uses (you can see it with
"g++ -v"), and replace '-z text' with '-z textoff' in it.

>> You may also find advice to do "-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic".
>> Ignore that advice, it doesn't work.
>
> When should that form be used? Will it work for libraries other than
> "libstdc++"?

It will work for any library that is not automatically added to
the link by the compiler driver.

Reply all
Reply to author
Forward
0 new messages