经过更多的研究,我意识到了处理这种情况的方式。有两个链接器选项可以操作共享库中未定义的符号:
第一个是--no-undefined。它会在链接阶段立即报告未解析的未定义符号。除非该符号在链接的共享库中被手动(使用-l开关)或自动(libgcc_s、C++运行时;libc、C运行时;ld-linux-**.so、动态连接器实用程序)找到,否则--no-undefined将其报告为错误。这就是提问者所需要的关键。
还有另外一个重要的选项,--no-allow-shlib-undefined(描述也建议使用--no-undefined)。它检查您链接共享库时是否满足共享库中的定义。这个选项在本主题中显示的情况下用处不大,但它可能很有用。然而,它也有自己的障碍。
手册提供了一些关于为什么它不是默认值的基本原理:
--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.
问题在于上面所说的也适用于Linux系统,其中一些共享库的内部例程是在ld-linux.so
中实现的,即动态加载器(它既是可执行文件又是共享库)。除非您以某种方式将其链接,否则您将会得到类似以下的输出:
/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'
这些是来自于加载器 ld-linux.so
的未定义引用。它是特定于平台的(例如,在我的系统上,正确的加载器是 /lib64/ld-linux-x86-64.so
)。您可以将加载器链接到您的库并检查上面显示的复杂引用:
g++ -fPIC -shared -o liba.so a.o -Wl,--no-allow-shlib-undefined /lib64/ld-linux-x86-64.so.2