删除链接器依赖项

时间:2012-07-09 18:14:55

标签: c++ c linux linker g++

我正在使用g ++在linux上开发一个c ++应用程序。我的应用程序链接在共享库中,该库公开了我需要的简单API。该库在内部引用了大量其他共享库。我必须找到每一个并将它们添加到我的Makefile中以将它们链接起来。

我认为我的应用程序必须链接到主lib依赖的任何库。围绕这个链接要求的唯一方法是将主lib编译在其所有依赖项的静态库中吗?这是否适用于通过dlopen / dlsym使用插件模型?

TY

3 个答案:

答案 0 :(得分:4)

  

是唯一可以解决此链接要求的方法,主要的lib是否在其所有依赖项的静态库中编译?

没有。共享库本身可以链接到它所依赖的共享库。大多数链接器也会选择这些库,并将您的可执行文件链接到这些库,而无需在链接器阶段提及它们。

在您的情况下,听起来共享库没有链接到它所需的库。 ldd工具在这方面很有用。

例如,假设您生成此共享库:

gcc -shared foo.o -o libfoo.so -lm

现在libfoo.so链接到数学库(libm)。任何链接到libfoo.so的应用程序 也会链接到libm,即你只需要做

gcc -o prog main.o -lfoo

另一方面,如果共享库未链接到lib,但仅使用

生成
 gcc -shared foo.o  -o libfoo.so

链接应用程序时必须明确链接到libm:

gcc -o prog main.o -lfoo -lm

当您执行dlopen()共享库时,运行时链接程序将加载共享库也链接的所有库 - 除非它们已经加载。所以 - 如果你dlopen()的库没有链接到它依赖的库,并且你的可执行文件也没有链接到那些库,dlopen()将失败(除非你指定RTLD_LAZY,在这种情况下,事情会在以后失败)

答案 1 :(得分:1)

  

我认为我的应用程序必须链接到主lib依赖的任何库。

听起来好像你的应用程序直接使用这些符号(不只是间接地通过API共享库)共享库没有正确链接,所以它没有链接到它依赖的库。如果在创建共享库时,其依赖项与-l链接,那么在将应用程序链接到API库时,它会自动链接到它们。

  

是唯一可以解决此链接要求的方法,主要的lib是否在其所有依赖项的静态库中编译?

这是一种方式,但不是唯一的方式。

  

这是否适用于通过dlopen / dlsym使用插件模型?

只要插件正确链接到它们所依赖的库... 不,在这种情况下,链接器可能无法知道运行时{lib}将使用哪些库dlopen ,所以无法知道它们的依赖关系,所以你不需要在链接时命名它们。如果事先不知道可能加载的所有插件,就不可能。

如果插件库没有正确链接,那么在尝试dlopen时会出现同样的问题。

答案 2 :(得分:-1)

  

我认为我的应用程序必须链接到主lib依赖的任何库。围绕这个链接要求是唯一的方法,让主lib在其所有依赖项的静态库中编译吗?

当然。没有办法:在库运行时搜索路径中进行静态链接或拥有库(正确版本,如果不兼容ABI)。

  

这是否适用于通过dlopen / dlsym使用插件模型?

没有。为此,您需要在要加载它的路径中使用共享库。