C++ 强制 GCC 通知共享库中未定义的引用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2356168/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Force GCC to notify about undefined references in shared libraries
提问by Fredrik Ullner
I have a shared library that is linked with another (third-party) shared library. My shared library is then loaded using dlopen in my application. All this works fine (assuming files are in the proper path etc).
我有一个与另一个(第三方)共享库链接的共享库。然后在我的应用程序中使用 dlopen 加载我的共享库。所有这些都可以正常工作(假设文件位于正确的路径等)。
Now, the problem is that I don't even need to specify to link against the third-party shared library when I link my library. GCC accept it without reporting errors about undefined references. So, the question; how can I force GCC to notify me about undefined references?
现在,问题是当我链接我的库时,我什至不需要指定链接第三方共享库。GCC 接受它而不报告有关未定义引用的错误。所以,问题; 如何强制 GCC 通知我未定义的引用?
If I change my library to be (temporarily) an executable, I get undefined references (when not supplying the library to the linker). (Works fine if I specify it.)
如果我将我的库更改为(临时)可执行文件,我会得到未定义的引用(当不向链接器提供库时)。(如果我指定它工作正常。)
I.e., the following is done:
即,完成以下操作:
g++ -fPIC -shared -o libb.so b.o
g++ -fPIC -shared -o liba.so a.o
g++ -o a.exe a.cpp
Where the second line does NOT give out an error and the third line complains about an undefined reference.
其中第二行没有给出错误,第三行抱怨未定义的引用。
Sample code:
示例代码:
a.h:
啊:
class a
{
public:
void foobar();
};
a.cpp:
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:
b.cpp:
#include "b.h"
void b::foobar()
{
}
回答by Dmitry Yudakov
-Wl,--no-undefined
linker option can be used when building shared library, undefined symbols will be shown as linker errors.
-Wl,--no-undefined
构建共享库时可以使用链接器选项,未定义的符号将显示为链接器错误。
g++ -shared -Wl,-soname,libmylib.so.5 -Wl,--no-undefined \
-o libmylib.so.1.1 mylib.o -lthirdpartylib
回答by P Shved
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.
第一个是--no-undefined
。它在链接阶段报告未立即解析的未解析符号。除非在链接的共享库中找到该符号,否则手动(使用-l
开关)或自动(libgcc_s
,C++ 运行时; libc
,C 运行时;ld-linux-**.so
,动态链接器实用程序)选择,--no-undefined
将其报告为错误。这就是提问者需要的钥匙。
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 againstare 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.
还有另一个键,--no-allow-shlib-undefined
(其描述也暗示了--no-undefined
)。它检查是否满足您链接共享库的共享库中的定义。此密钥在本主题中显示的情况下用处不大,但很有用。然而,它有其自身的障碍。
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:
事情是,上面说的也是正确的,例如,对于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'
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:
这些是来自加载器的未定义引用,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