与具有依赖关系的动态库链接 [英] Linking with dynamic library with dependencies

查看:23
本文介绍了与具有依赖关系的动态库链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下场景:

  • 共享库 libA.so ,没有依赖关系.
  • 共享库 libB.so,以 libA.so 作为其依赖项.

我想编译一个与 libB 链接的二进制文件.我应该将二进制文件仅与 libB 链接还是与 libA 链接?

I want to compile a binary file that links with the libB. Should I link the binary with libB only or with libA either?

有没有办法只链接直接依赖,让运行时从依赖中解析未解析的符号?

Is there any way to link only with the direct dependencies, letting the resolution of unresolved symbols from the dependencies for runtime?

我担心库 libB 的实现可能会在未来发生变化,引入其他依赖项(例如 libC、libD、libE).我会有问题吗?

I'm worried about the fact that the library libB implementation may change in the future, introducing other dependencies (libC, libD, libE for instance). Am I going to have problems with that?

换句话说:

  • libA 文件:a.cpp a.h
  • libB 文件:b.cpp b.h
  • 主程序文件:main.cpp

当然,b.cpp 包含 a.h,main.cpp 包含 b.h.

Of course, b.cpp includes a.h and main.cpp includes b.h.

编译命令:

g++ -fPIC a.cpp -c
g++ -shared -o libA.so a.o

g++ -fPIC b.cpp -c -I.
g++ -shared -o libB.so b.o -L. -lA

我应该使用以下哪个选项?

Which of the bellow options should I use?

g++ main.cpp -o main -I. -L. -lB

g++ main.cpp -o main -I. -L. -lB -lA

我无法使用第一个选项.链接器抱怨库 libA 中未解析的符号.但这对我来说听起来有点奇怪.

I couldn't use the first option. The linker complains about the unresolved symbols from the library libA. But it sound a little strange to me.

非常感谢.

-- 更新评论:

当我链接二进制文件时,链接器将尝试解析来自 main 和 libB 的所有符号.但是,libB 具有来自 libA 的未定义符号.这就是链接器抱怨的原因.

When I link the binary, the linker will try to resolve all symbols from the main and the libB. However, libB has undefined symbols from the libA. That's why the linker complains about that.

这就是为什么我也需要与 libA 链接.但是我找到了一种方法来忽略共享库中未解析的符号.看起来我应该使用以下命令行来做到这一点:

That's why I need to link with the libA too. However I found a way to ignore unresolved symbols from shared libraries. Looks like I should use the following command line to do that:

g++ main.cpp -o main -I. -L. -lB -Wl,-unresolved-symbols=ignore-in-shared-libs

看起来仍然可以使用 -rpath 选项.但是我需要更好地理解它.

Looks like it is still possible to use the -rpath option. However I need to understand it a little better.

有谁知道使用 -Wl,-unresolved-symbols=ignore-in-shared-libs 选项时可能存在的任何陷阱?

Does anyone knows any possible pitfalls when using the -Wl,-unresolved-symbols=ignore-in-shared-libs option?

-- 更新评论 2:

-rpath 不应用于此目的.强制在给定目录中找到库很有用.-unresolved-symbol 方法看起来好多了.

-rpath should not be used for this purpose. It is useful to force a library to be found in a given directory. The -unresolved-symbol approach looks much better.

再次感谢.

推荐答案

看起来您已经完成了大部分任务.你的调查做得很好.让我们看看我是否可以帮助弄清楚它背后的原因".

It looks like you are most of the way there already. Well done with your investigation. Let's see if I can help clear up the 'why' behind it.

这是链接器正在做的事情.当你链接你的可执行文件(上面的'main')时,它有一些未解析的符号(函数和其他东西).它将查看后面的库列表,尝试解析未解析的符号.一路上,它发现一些符号是由 libB.so 提供的,所以它注意到它们现在由这个库解析.

Here's what the linker is doing. When you link your executable ('main' above) it has some symbols (functions and other things) that are unresolved. It will look down the list of libraries that follow, trying to resolve unresolved symbols. Along the way, it finds that some of the symbols are provided by libB.so, so it notes that they are now resolved by this library.

但是,它还发现其中一些符号使用了您的可执行文件中尚未解析的其他符号,因此它现在也需要解析这些符号.如果不链接 libA.so,您的应用程序将是不完整的.一旦它与 libA.so 链接,所有符号都被解析并且链接完成.

However, it also discovers that some of those symbols use other symbols that are not yet resolved in your executable, so it now needs to resolve those as well. Without linking against libA.so, your application would be incomplete. Once it links against libA.so, all symbols are resolved and linking is complete.

如您所见,使用 -unresolved-symbols-in-shared-libs 并不能解决问题.它只是推迟它,以便在运行时解析这些符号.这就是 -rpath 的用途:指定要在运行时搜索的库.如果这些符号无法解析,您的应用将无法启动.

As you saw, the use of -unresolved-symbols-in-shared-libs, doesn't fix the problem. It just defers it so that those symbols are resolved at run time. That's what -rpath is for: to specify the libraries to be searched at run time. If those symbols can't be resolved then, your app will fail to start.

找出库依赖关系不是一件容易的事,因为一个符号可以由多个库提供,并通过链接其中任何一个来满足.

It's not an easy thing to figure out library dependencies because a symbol could be provided by more than one library and be satisfied by linking against any one of them.

这里对这个过程还有另一种描述:为什么链接库的顺序有时会导致GCC出错?

There is another description of this process here: Why does the order in which libraries are linked sometimes cause errors in GCC?

这篇关于与具有依赖关系的动态库链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆