Linux 在编译时链接共享对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4976288/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 02:49:25  来源:igfitidea点击:

Linking against shared objects at compile time

linuxgcclinkershared-librariescompile-time

提问by Joey

In Windows, many .dlls come with a static .lib counterpart. My understanding is that the .lib counterpart basically contains LoadProcAddress calls so that the programmer doesn't have to do it him/herself. Essentially, a time saver. When I switched to Linux, I was assuming the situation was the same, replacing .dll with .so and .lib with .a, but I have come to a situation that is showing me this is wrong and I can't figure out what is going on:

在 Windows 中,许多 .dll 都带有静态的 .lib 对应文件。我的理解是 .lib 对应物基本上包含 LoadProcAddress 调用,因此程序员不必自己做。本质上,节省时间。当我切换到 Linux 时,我假设情况是一样的,将 .dll 替换为 .so,将 .lib 替换为 .a,但我遇到的情况表明这是错误的,我无法弄清楚是什么正在进行:

I am using a library that comes as a .a/.so pair. I was linking against the .a, but when I executed ldd on the binary that was produced, it contained no reference to the corresponding .so file. So then, I tried linking against the .so file and to my surprise, this worked. In addition, the .so file showed up when I executed ldd against the resulting binary.

我正在使用一个 .a/.so 对的库。我正在链接 .a,但是当我在生成的二进制文件上执行 ldd 时,它不包含对相应 .so 文件的引用。然后,我尝试链接 .so 文件,令我惊讶的是,这奏效了。此外,当我对生成的二进制文件执行 ldd 时,会出现 .so 文件。

So, I am really confused as to what is going on. In Windows, I would never think to link against a .dll file. Also, in Windows, if a .dll file was accompanied with a .lib and I linked against the .lib at compile-time, then I would expect to have a dependency on the corresponding .dll at runtime. Both these things are not true in this case.

所以,我真的很困惑发生了什么。在 Windows 中,我永远不会想到链接 .dll 文件。此外,在 Windows 中,如果 .dll 文件附带 .lib 并且我在编译时链接到 .lib,那么我希望在运行时依赖于相应的 .dll。在这种情况下,这两件事都不是真的。

Yes, I have read the basic tutorials about shared objects in Linux, but everything I read seems to indicate that my initial assumption was correct. By the way, I should mention that I am using Code::Blocks as an IDE, which I know complicates things, but I am 99% sure that when I tell it to link against the .so file, it is not simply swapping out the .a file because the resulting binary is smaller. (Plus the whole business about ldd...)

是的,我已经阅读了有关 Linux 中共享对象的基本教程,但是我阅读的所有内容似乎都表明我最初的假设是正确的。顺便说一下,我应该提到我正在使用 Code::Blocks 作为 IDE,我知道这会使事情复杂化,但是我 99% 确定当我告诉它链接 .so 文件时,它不是简单地换出.a 文件,因为生成的二进制文件较小。(加上关于 ldd 的整个业务......)

Anyway, thanks in advance.

无论如何,提前致谢。

回答by rlibby

I was linking against the .a, but when I executed ldd on the binary that was produced, it contained no reference to the corresponding .so file.

我正在链接 .a,但是当我在生成的二进制文件上执行 ldd 时,它不包含对相应 .so 文件的引用。

This is expected. When you link statically, the static library's code is integrated into the resulting binary. There are no more references to or dependencies on the static library.

这是预期的。静态链接时,静态库的代码会集成到生成的二进制文件中。不再有对静态库的引用或依赖。

So then, I tried linking against the .so file and to my surprise, this worked.

然后,我尝试链接 .so 文件,令我惊讶的是,这奏效了。

What do you mean, that the static linking did not work? There's no reason that it shouldn't...

你是什​​么意思,静态链接不起作用?没有理由不应该...

回答by tharibo

.lib are used in Windows to dynamically link. You don't have them in Linux, you link with .so directly. The .a file is the statically built library, you use it to link statically.

.lib 在 Windows 中用于动态链接。Linux 中没有它们,直接与 .so 链接。.a 文件是静态构建的库,您可以使用它进行静态链接。

回答by yugr

To add to already correct answer by tharibo - in some situations (e.g. delayed shared library load) it might be desirable to do it the Windows way i.e. by linking against a static stub instead of .so. Such stubs can be written by hand, generated by project-specific scripts or by generic Implib.so tool.

要添加 tharibo 已经正确的答案 - 在某些情况下(例如延迟共享库加载),可能需要以 Windows 方式执行此操作,即通过链接静态存根而不是.so. 这样的存根可以手工编写,由项目特定的脚本或通用Implib.so 工具生成