Re: [Libsigcx-main] Re: [PATCH] libsigcx-0.6.4 build fixes for Cygwin, older libtools
Status: Beta
Brought to you by:
rottmann
From: Steven B. <sw...@uc...> - 2005-04-11 03:04:18
|
Andreas Rottmann wrote: > It seems I know nothing about what undefined sybols in shared > libraries are and what they mean. Do you know of any reference? I > looked up the --no-undefined ld option, but that didn't explain > much. I believe you, however, when you say that -no-undefined cannot > hurt and have applied your patch. As an example, say we have foo.c, bar.c, and main.c as follows: swbrown@activecampus:~/tmp/z$ cat foo.c extern void bar(); void foo() { bar(); } swbrown@activecampus:~/tmp/z$ cat bar.c void bar() { } swbrown@activecampus:~/tmp/z$ cat main.c extern void foo(); int main() { foo(); return 0; } foo.c will be our shared library, main.c will be our application, and bar.c will be the shared library foo.c depends on. We'll build the shared libraries, but not have bar.c available at link time, and not use -no-undefined: swbrown@activecampus:~/tmp/z$ gcc -c bar.c -fPIC -o bar.lo swbrown@activecampus:~/tmp/z$ ld -shared bar.lo -o bar.so swbrown@activecampus:~/tmp/z$ gcc -c foo.c -fPIC -o foo.lo swbrown@activecampus:~/tmp/z$ ld -shared foo.lo -o foo.so The linker actually let us link foo.so without having any knowledge of where the required 'bar' symbol comes from, or if it exists at all. Now we build main.c and try linking with foo.so: swbrown@activecampus:~/tmp/z$ gcc -c main.c -o main.o swbrown@activecampus:~/tmp/z$ gcc main.o foo.so -o main foo.so: undefined reference to `bar' collect2: ld returned 1 exit status Nasty - a link error in a dependency that had sucessfully built. It's almost certainly not what the author of foo.so intended to have happen, and is almost certainly a build error that went uncaught. Now if we had let the linker know about bar.so when we built foo.so, we get a much different result: swbrown@activecampus:~/tmp/z$ ld -shared foo.lo bar.so -o foo.so swbrown@activecampus:~/tmp/z$ gcc main.o foo.so -o main And we can verify that it did the right thing (yay GNU, but obviously, folks would usually be using libtool for this as not all systems are this smart): swbrown@activecampus:~/tmp/z$ ldd main foo.so => foo.so (0xb7fe7000) libc.so.6 => /lib/tls/libc.so.6 (0xb7e9e000) bar.so => bar.so (0xb7e9c000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0xb7fea000) That's probably what the author intended. Now if we had passed in -no-undefined when we tried to build foo.so the wrong way: swbrown@activecampus:~/tmp/z$ ld -shared -no-undefined foo.lo -o foo.so foo.lo(.text+0x13): In function `foo': : undefined reference to `bar' The error was caught when building foo.so rather than building anything using foo.so. That's a much better situation, especially when you've got a symbol mangling bug in C++ - you wind up bald debugging those, that is, if your terminal ever stops scrolling. ;) Note though, that it has no issue with symbols that are defined in another library it knew about at link time: swbrown@activecampus:~/tmp/z$ ld -shared -no-undefined foo.lo bar.so -o foo.so swbrown@activecampus:~/tmp/z$ ldd foo.so bar.so => bar.so (0xb7ffb000) So, having -no-undefined in is really what 99.9% of folks intend, anyway, and is required for some platforms. I'm really not sure who has a need for allowing undefined symbols, but I'd guess it'd be the low-level folks like those working on ld-linux.so, maybe the crt0 stuff, etc.. |