我正在使用g ++在linux上开发一个c ++应用程序。我的应用程序链接在共享库中,该库公开了我需要的简单API。该库在内部引用了大量其他共享库。我必须找到每一个并将它们添加到我的Makefile中以将它们链接起来。
我认为我的应用程序必须链接到主lib依赖的任何库。围绕这个链接要求的唯一方法是将主lib编译在其所有依赖项的静态库中吗?这是否适用于通过dlopen / dlsym使用插件模型?
TY
答案 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使用插件模型?
没有。为此,您需要在要加载它的路径中使用共享库。