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

parr · 2020-03-20 23:34:18 · 热度: 210

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

猜你喜欢:
共收到 3 条回复
sid #1 · 2020-03-20 23:34:18

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

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

tariku #2 · 2020-03-20 23:34:20

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

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

还有另一个键ld-linux.so(其描述也建议/lib64/ld-linux-x86-64.so)。 它检查您链接共享库所针对的共享库中的定义是否满足。 在本主题中所示的情况下,此键几乎没有用,但可能很有用。 但是,它有自己的障碍。

该手册页提供了一些有关为什么它不是默认值的理由:

   --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
timothy #3 · 2020-03-20 23:34:21

您不能使ld(这是gcc正在运行的)注意链接中不存在的库。 您可以关闭RTLD_LAZY以获得积极的报告,还可以添加一个在链接后立即运行的单元测试,以消除这些问题。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册