Unix Programming - Problems with static linking

This is Interesting: Free IT Magazines  
Home > Archive > Unix Programming > April 2005 > Problems with static linking





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author Problems with static linking
John Smith

2005-04-19, 8:01 am

Under Redhat 9.0 (x86) I compiled a file with g++. I'm compiling mixed C and
C++ code with gcc and g++ and using g++ as frontend driver for the linker.

When done I used ldd and got:
[root@localhost Linux]# ldd foobar
libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x40058000)
libm.so.6 => /lib/tls/libm.so.6 (0x4010b000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x4012d000)
libc.so.6 => /lib/tls/libc.so.6 (0x42000000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x80000000)

Actually I both got a execuable and a shared-object where I want to do
static linking and remove libstdc++ and libgcc_s.

However I didn't succeed in removing either of them. I read that I should be
able to remove libgcc_s by adding "-static-libgcc" however it seems not to
have any effect. ldd shows the same with or without it.

I also tried to add "-Wl,-static -lstdc++ -Wl,-dynamic" to the end of the
linker command but it didn't do any difference either. ldd shows the same.
When adding "-static" to the linker line I got the following linker errors
(which I do not understand):

temp/Linux/foobar.o(.text+0x87fe): In function
`MyClass::MyClass[not-in-charge]()':
: undefined reference to `pthread_mutex_init'
temp/Linux/foobar.o(.text+0x881e): In function
`MyClass::MyClass[in-charge]()':
: undefined reference to `pthread_mutex_init'
temp/Linux/foobar.o(.text+0x883c): In function `MyClass::~MyClass
[not-in-charge]()':
: undefined reference to `pthread_mutex_destroy'
temp/Linux/foobar.o(.text+0x885c): In function `MyClass::~MyClass
[in-charge]()':
: undefined reference to `pthread_mutex_destroy'
temp/Linux/foobar.o(.text+0x887d): In function `MyClass::~MyClass [in-charge
deleting]()':
: undefined reference to `pthread_mutex_destroy'

I don't understand why I get pthread errors since it works fine otherwise. I
tried adding a "-lpthread" to the commandline but it didn't seem to help.

My linker line currently looks like the following:

g++ -o temp/Linux/foobar temp/Linux/foobar.o ... other objects

Thanks in advance.
--John


Paul Pluzhnikov

2005-04-19, 6:06 pm

"John Smith" <john.smith@x-formation.com> writes:

> Actually I both got a execuable and a shared-object where I want to do
> static linking and remove libstdc++ and libgcc_s.


For a recipe that actually works, see this thread:
http://groups-beta.google.com/group...fd688b59988567c

> I read that I should be
> able to remove libgcc_s by adding "-static-libgcc" however it seems not to
> have any effect. ldd shows the same with or without it.


That's because libstdc++.so.5 *itself* depends on libgcc_s.so.1

Since you didn't (yet) get rid of libstdc++.so dependency, and since
ldd lists all dependent libraries, whether your executable depends on
them directly or indirectly, ldd still showed the (indirect)
libgcc_s dependency.

The flag did have an effect, you just didn't observe it.
If you want to see the effect (or see what libraries you depend on
directly), do this:

g++ junk.cc && objdump -p | grep ' NEED'
g++ junk.cc -static-libgcc && objdump -p | grep ' NEED'

> I also tried to add "-Wl,-static -lstdc++ -Wl,-dynamic" to the end of the


That's bogus: linker '-static' and '-dynamic' flags are mutually
exclusive, and the last one wins, so your command is equivalent to
just adding '-lstdc++'.

As the thread above says, it is surprisingly difficult to get rid
of libstdc++.so ... Many people think that adding

-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic

should do the trick, but that doesn't work either :-(

I have not seen any problems with my "create symlink" trick though

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

2005-04-19, 6:06 pm

>
> I have not seen any problems with my "create symlink" trick though
>


Thanks for the explanation and thanks for answering the last couple of posts
I've had in this group. :-) Without your help I'd still probably be stuck
where I started. Now I'm almost done with all the problems I've faced when
porting my software. So I should send you a beer by now. ;-)

I didn't have time to look at the last suggestion yet with symlink but from
what I understand the symlink is only to get the full path of the libstdc++
binary. However this could be achived in other ways then creating symlinks.
However the "-L." part I assume only is needed for the linking command and
not actual compilation. Am I right?

-- John


Paul Pluzhnikov

2005-04-20, 2:59 am

"John Smith" <john.smith@x-formation.com> writes:

> I didn't have time to look at the last suggestion yet with symlink but from
> what I understand the symlink is only to get the full path of the libstdc++
> binary.


It's not. While you can easily find which directory libstdc++.a is
in, the problem is that libstdc++.so is (in default installations)
*also* in that same directory, e.g.

$ gcc -print-file-name=libstdc++.a
/usr/lib/gcc-lib/i386-redhat-linux/3.3.3/libstdc++.a
$ gcc -print-file-name=libstdc++.so
/usr/lib/gcc-lib/i386-redhat-linux/3.3.3/libstdc++.so

And the linker will prefer .so, unless -Bstatic is in effect;
and you can't put -Bstatic in the right place on the command line
(without also forcing libc.a), because g++ adds -lstdc++ at the
very end of the link line.

The reason for creating a symlink is to have a directory that
contains libstdc++.a but not libstdc++.so, and then give that
directory to the linker (with -L flag) *before* the standard ones.

> However the "-L." part I assume only is needed for the linking command and
> not actual compilation.


Correct.

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

2005-04-21, 7:52 am

Hmm ... very weird!

When I use your symlink trick nothing seems to happen.

My linking command looks like the following:

ln -f -s `g++ -print-file-name=libstdc++.a` ~
g++ -o temp/Linux/foobar -static-libgcc temp/Linux/foobar.o -L~/
rm -f ~/libstdc++.a

[root@localhost lmxdev]# ls -l ~/libstdc++.a

lrwxrwxrwx 1 root root 52 Apr 21 14:05 /root/libstdc++.a ->
/usr/lib/gcc-lib/i386-redhat-linux/3.2.2/libstdc++.a

The filesize of the resulting file stays the same though and it still
depends on libstdc++.so.5

Thanks in advance for any help.

-- John



John Smith

2005-04-21, 7:52 am

Weird!

It seems it's related to the path I used "~". When I use "." it works
(atleast testing on a small hello world program). However I'm compiling from
a network drive so the system says it can't create a symlink in ".".

I wouldn't have imagined the path makes a difference.

Maybe I'm missing something?

-- John


Paul Pluzhnikov

2005-04-21, 5:59 pm

"John Smith" <john.smith@x-formation.com> writes:

> I wouldn't have imagined the path makes a difference.


It doesn't.

> Maybe I'm missing something?


You are: '~' is not a path; it's a "magic" character expanded to
the value of $HOME by _some_ shells under certain conditions.

Try this:

echo -- -L~
echo -- -L ~

From the Makefile, you should _always_ use $(HOME) instead of '~',
lest your Makefile doesn't work on systems where /bin/sh doesn't
understand '~' at all.

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

2005-04-22, 7:53 am

Great!

Thanks for the explanation. Now it works fine for execuable binaries. I'm
trying to do the same for an .so file but it gave me some weird errors.

I assume it could be related to relocation but this is just a guess.

ln -f -s `g++ -print-file-name=libstdc++.a` /root

g++ -o
temp/linux/foo.so -static-libgcc -shared -Wl,--version-script=linux_exports.
txt temp/Linux/foo.o -L/root

/usr/bin/ld: temp/linux/foo.so: undefined versioned symbol name
std::time_put_w@@GLIBCPP_3.2

/usr/bin/ld: failed to set dynamic section sizes: Bad value

collect2: ld returned 1 exit status

It's really weird because I'm doing exactly the same steps as for normal
binaries.

Thanks in advance.

-- John


Paul Pluzhnikov

2005-04-22, 6:00 pm

"John Smith" <john.smith@x-formation.com> writes:

> /usr/bin/ld: temp/linux/foo.so: undefined versioned symbol name
> std::time_put_w@@GLIBCPP_3.2


This is apparently a bug in the way libstdc++.a is built with
gcc-3.3 and 3.3.2 on Linux.

See this message (and thread):
http://groups-beta.google.com/group...d63e2ff1e16536e

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

2005-04-23, 5:51 pm

> This is apparently a bug in the way libstdc++.a is built with
> gcc-3.3 and 3.3.2 on Linux.
>
> See this message (and thread):
> http://groups-beta.google.com/group...d63e2ff1e16536e
>


Thanks again. Compiling the same code under Fedora core 3 (gcc 3.4.2) made
the problem disapear.

However the object files I'm creating still have a dependency for
libgcc_s.so.1. I see this with ldd once linked with user code.
Do I need to worry about this like libstdc++? Maybe I should do a relinking
(ld -r ... libgcc...) on the object files to avoid any dependency? What is
libgcc good for anyway?

Thanks in advance.
-- John


Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com