| 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
|
|
|
|