1

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

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

4

3 回答 3

4

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

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

在您的情况下,听起来共享库没有链接到它所需的库。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,在这种情况下事情稍后会失败)

于 2012-07-09T19:16:27.583 回答
1

我假设我的应用程序必须链接到主库所依赖的任何库。

听起来好像您的应用程序正在直接使用这些符号(不仅仅是通过 API 共享库间接使用) ,或者共享库没有正确链接,因此它没有链接到它所依赖的库。如果在创建该共享库时,它的依赖项被链接到,-l那么在将您的应用程序链接到 API 库时,它将导致它们被自动链接到。

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

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

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

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

如果插件库没有正确链接,您在尝试使用dlopen它们时会遇到同样的问题。

于 2012-07-09T19:20:41.890 回答
-1

我假设我的应用程序必须链接到主库所依赖的任何库。解决此链接要求的唯一方法是在其所有依赖项的静态库中编译主库吗?

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

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

不,为此,您需要在要从中加载它的路径中拥有共享库。

于 2012-07-09T19:09:48.477 回答