强制 GCC 通知共享库中未定义的引用
Posted
技术标签:
【中文标题】强制 GCC 通知共享库中未定义的引用【英文标题】:Force GCC to notify about undefined references in shared libraries 【发布时间】:2010-03-01 13:46:28 【问题描述】:我有一个与另一个(第三方)共享库链接的共享库。然后在我的应用程序中使用 dlopen 加载我的共享库。所有这些都可以正常工作(假设文件位于正确的路径等中)。
现在,问题是当我链接我的库时,我什至不需要指定链接到第三方共享库。 GCC 接受它而不报告关于未定义引用的错误。所以,问题; 如何强制 GCC 通知我未定义的引用?
如果我将库更改为(临时)可执行文件,我会得到未定义的引用(当不将库提供给链接器时)。 (如果我指定它可以正常工作。)
即完成以下操作:
g++ -fPIC -shared -o libb.so b.o
g++ -fPIC -shared -o liba.so a.o
g++ -o a.exe a.cpp
第二行没有给出错误,第三行抱怨未定义的引用。
示例代码:
啊哈:
class a
public:
void foobar();
;
a.cpp:
#include "a.h"
#include "b.h"
void a::foobar()
b myB;
myB.foobar();
int main()
a myA; myA.foobar();
b.h:
class b
public:
void foobar();
;
b.cpp:
#include "b.h"
void b::foobar()
【问题讨论】:
【参考方案1】:-Wl,--no-undefined
链接器选项可以在构建共享库时使用,未定义的符号将显示为链接器错误。
g++ -shared -Wl,-soname,libmylib.so.5 -Wl,--no-undefined \
-o libmylib.so.1.1 mylib.o -lthirdpartylib
【讨论】:
您能提供链接器输出吗? 嗯,我可以发誓我以前做过这个,但没有得到任何输出。再次这样做似乎使这项工作正常(即我收到错误!) 我将 -Wl,-no-undefined 编辑为 -Wl,--no-undefined (正如 ld 手册所说),尽管这两种情况似乎都对我有用。【参考方案2】:经过更多研究,我意识到这些东西的工作原理。有两个链接器选项可以操作共享库的未定义符号:
第一个是--no-undefined
。它在链接阶段报告未立即解析的未解析符号。除非在链接的共享库中找到符号,否则手动(使用-l
开关)或自动(libgcc_s
,C++ 运行时;libc
,C 运行时;ld-linux-**.so
,动态链接器实用程序)选择,@987654326 @ 将其报告为错误。这就是提问者需要的关键。
还有另一个键,--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
【讨论】:
不,无论我使用 --no-allow-shlib-undefined 还是 --no-undefined 都没有错误。 @Fredrik,我想,你忘了添加-Wl,
的东西。它确实显示错误,虽然不是你想要的那个。但这是你能拥有的最多。
似乎 --no-undefined 按预期工作,但 --no-allow-shlib-undefined 没有。 (按你说的做。)
@Fredrik,谢谢。我修正了我完全不正确的帖子,它可能对你有用。以上是关于强制 GCC 通知共享库中未定义的引用的主要内容,如果未能解决你的问题,请参考以下文章