强制GCC通知共享库中未定义的引用
我有一个与另一个(第三方)共享库链接的共享库。 我的共享库然后在我的应用程序中使用dlopen加载。 所有这一切工作正常(假设文件是在正确的path等)。
现在,问题是,我甚至不需要指定链接我的库时链接到第三方共享库。 GCC接受它而不报告有关未定义参考的错误。 所以,这个问题; 我如何强制GCC通知我未定义的引用 ?
如果我更改我的库是(暂时)一个可执行文件,我得到未定义的引用(当不提供库到链接器)。 (如果我指定,工作正常。)
即,完成以下工作:
g++ -fPIC -shared -o libb.so bo g++ -fPIC -shared -o liba.so ao g++ -o a.exe a.cpp
如果第二行不发出错误,第三行则报告未定义的引用。
示例代码:
啊:
class a { public: void foobar(); };
a.cpp:
#include "ah" #include "bh" void a::foobar() { b myB; myB.foobar(); } int main() { a myA; myA.foobar(); }
BH:
class b { public: void foobar(); };
b.cpp:
#include "bh" void b::foobar() { }
-Wl, –构build共享库时可以使用no-undefined链接器选项,未定义的符号将显示为链接器错误。
g ++ -shared -Wl,-soname,libmylib.so.5 -Wl, – no-undefined -o libmylib.so.1.1 mylib.o -lthirdpartylib
经过更多的研究,我意识到这些东西的工作方式。 有两个链接器选项来操作未定义的共享库符号:
第一个是--no-undefined
。 它会在链接阶段报告尚未解决的未解决符号。 除非手动(使用-l
开关)或自动( libgcc_s
,C ++运行库; libc
,C运行库; ld-linux-**.so
.so,dynamic链接程序utils)链接的共享库中find该符号, --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
实现的,dynamic加载器(它是可执行文件和共享库)。 除非你以某种方式链接它,否则你会得到这样的东西:
/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 ao -Wl,--no-allow-shlib-undefined /lib64/ld-linux-x86-64.so.2
在Mandriva wiki上也有很好的讨论。
你不能让ld(gcc运行的是什么)注意链接中没有的库。 您可以closuresRTLD_LAZY以获得积极的报告,并且您可以添加一个在链接之后运行的unit testing,以消除这些问题。