After more research, I realized what way the stuff works. There are two linker options to manipulate undefined symbols of shared libraries:
First one is --no-undefined
. It reports the unresolved symbols that are not resolved immediately, at linking stage. Unless the symbol is found in a shared library linked against, either manually (with -l
switch) or automatically (libgcc_s
, C++ runtime; libc
, C runtime; ld-linux-**.so
, dynamic linker utils) picked, --no-undefined
reports it as error. That's the key the questioner needed.
There is another key, --no-allow-shlib-undefined
(whose description also suggests --no-undefined
). It checks if definitions in the shared libraries which you link your shared library against are satisfied. This key is of little use in the case shown in this topic, but it can be useful. However, It has its own obstacles.
The manpage provides some rationale about why it's not default:
--allow-shlib-undefined
--no-allow-shlib-undefined
Allows (the default) or disallows undefined symbols in shared
libraries (It is meant, in shared libraries _linked_against_, not the
one we're creating!--Pavel Shved). This switch is similar to --no-un-
defined except that it determines the behaviour when the undefined
symbols are in a shared library rather than a regular object file. It
does not affect how undefined symbols in regular object files are
handled.
The reason that --allow-shlib-undefined is the default is that the
shared library being specified at link time may not be the same as
the one that is available at load time, so the symbols might actually
be resolvable at load time. Plus there are some systems, (eg BeOS)
where undefined symbols in shared libraries is normal. (The kernel
patches them at load time to select which function is most appropri-
ate for the current architecture. This is used for example to dynam-
ically select an appropriate memset function). Apparently it is also
normal for HPPA shared libraries to have undefined symbols.
The thing is that what is said above is also true, for example, for Linux systems, where some of the internal routines of the shared library is implemented in ld-linux.so
, the dynamic loader (it's both executable and shared library). Unless you somehow link it, you will get something like this:
/lib64/libc.so.6: undefined reference to `_dl_argv@GLIBC_PRIVATE'
/lib64/libc.so.6: undefined reference to `_rtld_global_ro@GLIBC_PRIVATE'
/usr/lib64/gcc/x86_64-suse-linux/4.3/libstdc++.so: undefined reference to `__tls_get_addr@GLIBC_2.3'
/lib64/libc.so.6: undefined reference to `_rtld_global@GLIBC_PRIVATE'
/lib64/libc.so.6: undefined reference to `__libc_enable_secure@GLIBC_PRIVATE'
These are undefined references from the loader, ld-linux.so
. It is platform-specific (for example, on my system the correct loader is /lib64/ld-linux-x86-64.so
). You may link the loader with your library and check even the tricky references shown above:
g++ -fPIC -shared -o liba.so a.o -Wl,--no-allow-shlib-undefined /lib64/ld-linux-x86-64.so.2