强制GCC通知共享库中未定义的引用

问题描述 投票:56回答:2

我有一个与另一个(第三方)共享库链接的共享库。然后在我的应用程序中使用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 

第二行不显示错误,第三行抱怨未定义引用。

示例代码:

a.h:

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()
{
}
c++ shared-libraries dynamic-linking
2个回答
57
投票

[-Wl,--no-undefined链接器选项可以在构建共享库时使用,未定义的符号将显示为链接器错误。

g++ -shared -Wl,-soname,libmylib.so.5 -Wl,--no-undefined \
    -o libmylib.so.1.1 mylib.o -lthirdpartylib

21
投票

经过更多研究,我意识到了这些东西的工作方式。有两个链接器选项可操作共享库的未定义符号:

第一个是--no-undefined。它报告在链接阶段尚未立即解析的未解析符号。除非在手动(使用-l开关)或自动(libgcc_s,C ++运行时; libc,C运行时; ld-linux-**.so,动态链接器实用程序)链接的共享库中找到该符号,否则将其选为[C0 ]将其报告为错误。这是发问者需要的钥匙。

[还有另一个键--no-undefined(其描述也建议--no-allow-shlib-undefined)。它检查共享库链接共享库所依据的中的定义是否满足。在本主题中所示的情况下,此键几乎没有用,但可能很有用。但是,它有自己的障碍。

该联机帮助页提供了有关为什么不是默认值的一些理由:

--no-undefined

事实就是这样,例如,对于Linux系统,其中共享库的一些内部例程在动态加载程序 --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. 中实现(它既是可执行程序又是共享库)。除非您以某种方式链接它,否则您将获得如下内容:

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
© www.soinside.com 2019 - 2024. All rights reserved.