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

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

问题描述

考虑以下场景:

  • 共享库 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天全站免登陆