将共享库与静态库链接:静态库的编译方式必须与应用程序链接它的方式不同吗? [英] Linking a shared library against a static library: must the static library be compiled differently than if an application were linking it?

查看:17
本文介绍了将共享库与静态库链接:静态库的编译方式必须与应用程序链接它的方式不同吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

至少在 Linux 和 Solaris 上,静态库实际上只是一堆已编译的 .o 文件,它们被扔进一个大文件中.编译静态库时,通常会省略 -fpic 标志,因此生成的代码是位置相关的.

At least on Linux and Solaris, static libraries are really just a bunch of compiled .o's tossed into one big file. When compiling a static library, usually the -fpic flag is ommited, so the generated code is position dependent.

现在假设我的静态库是 B.我已经构建了它并得到了生成的 .a 文件,它实际上只是所有位置相关的 .o 文件的一个整体.现在我有一个我想构建的共享库A,我希望它静态链接B.当我构建A时,我自然会使用-fpic标志来使生成的代码位置独立.但是如果我链接到 B,我不是混合了位置相关和位置无关的目标文件吗?

Now say my static library is B. I've built it and have the resulting .a file which is really just a glob of all of the position dependent .o files. Now I have a shared library I'd like to build, A, and I want it to statically link B. When I build A, naturally I'll use the -fpic flag to make the generated code position independent. But if I link against B, aren't I mixing position dependent and position independent object files?

除非我还指定 -mimpure-text,否则我会收到很多文本重定位错误,我认为这可能是原因.看来我编译一个库的时候,真的需要编译3次,一个共享版本,一个静态版本,一个static-that-c​​an-be-used-by-shared-libs版本.我对吗?我可以继续使用 -mimpure-text 但是 g++ 手册页说,如果你这样做,对象实际上并没有最终被共享(不清楚它是全部未共享还是只是静态链接的部分,有人知道吗?).

I'm getting a lot of text relocation errors unless I also specify -mimpure-text, and I think this maybe the cause. It seems when I compile a library, I really need to compile it 3 times, a shared version, a static version, and a static-that-can-be-used-by-shared-libs version. Am I right? I could just keep using -mimpure-text but the g++ man page says that if you do that the object doesn't actually end up being shared (it's unclear if it's all unshared or just the statically linked parts though, does anyone know?).

推荐答案

您不必在共享对象中使用 PIC 代码(正如您所发现的,您可以使用 -mimpure-text 选项来允许这样做).

You do not have to use PIC code in shared objects (as you have discovered you can use the -mimpure-text option to allow that).

也就是说,共享对象中的非 PIC 代码更重量级.使用 PIC 代码,内存中的文本页面只是磁盘上文本页面的直接内存映射.这意味着如果多个进程正在使用共享对象,它们可以共享内存页面.

That said, non-PIC code in shared objects are more heavyweight. With PIC code, the text pages in memory are just direct memory mappings of the text pages on disk. This means that if multiple processes are using the shared object, they can share the memory page.

但如果您没有 PIC 代码,当运行时链接器加载共享对象时,它必须对文本页面应用修正.这意味着使用共享对象的每个进程都将拥有它自己的任何文本页面的唯一版本,该文本页面上有一个修复(即使共享对象加载到与写时复制相同的地址,也只会注意到该页面是修改,而不是以相同的方式修改).

But if you do not have PIC code, when the runtime linker loads the shared object, it will have to apply fixups to the text pages. This means that every processes that uses the shared object will have it's own unique version of any text page that has a fixup on it (even if the shared object is loaded at the same address as copy-on-write only notices that the page was modified and not that it was modified in the same way).

对我来说,重要的问题是您是否会同时运行多个进程,每个进程都加载共享对象.如果你这样做了,绝对值得确保 SO 中的所有代码都是 PIC.

To me, the important issue is whether you will simultaneously have multiple processes running that each load the shared object. If you do, it is definitely worth making sure all the code within the SO is PIC.

但如果不是这种情况,并且只有一个进程加载了共享对象,那么它就没有那么重要了.

But if that is not the case and only a single process has the shared object loaded, it's not nearly as critical.

这篇关于将共享库与静态库链接:静态库的编译方式必须与应用程序链接它的方式不同吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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