至少在Linux和Solaris,静态库其实只是一堆编译的.o年代扔成一个大文件。 当编译一个静态库,通常-fpic标志中省略,所以所生成的代码是依赖于位置。
现在说我的静态库是B.我已经建立,并已得到的某文件是真的只是一个所有相关.o文件位置的水珠。 现在我有一个共享库,我想建立,A,我希望当我建立一个它静态链接B.,我自然会使用-fpic标志作出独立生成的代码位置。 但是,如果我对B链接,不是我的混合位置相关和位置无关的目标文件?
我得到了很多文本重定位错误的,除非我也指定-mimpure文字,我想这也许是原因。 看来当我编译库,我真的需要编译它的3倍,共享版,静态版本,和静态-这可任意地使用的逐共享库的版本。 我对吗? 我可以继续使用-mimpure文本,但G ++手册页说,如果你这样做的目的实际上并没有最终被共享(目前还不清楚,如果这一切都非共享或只是静态链接部分虽然,没有人知道?) 。
你不必在共享对象使用PIC代码(如你发现你可以使用-mimpure文本选项以支持)。
在共享对象这就是说,非PIC代码是更重量级的。 随着PIC代码,在内存中的文本页面在磁盘上的文本页面只是直接存储器映射。 这意味着,如果多个进程正在使用的共享对象,它们可以共享存储器页面。
但是,如果你没有PIC代码,当运行时链接程序的共享对象,它必须调整信息适用于文本页面。 这意味着使用共享对象的每个过程都会有那就是上有一个修正(即使共享对象在同一地址加载副本上只写通知,该页面的任何文本页面的自己独特的版本修改,不在于它以同样的方式被修改)。
对我来说,重要的问题是,你是否会同时具有运行每个负载的共享对象的多个进程。 如果你这样做,这绝对是一个值得确保所有的代码中的SO是PIC。
但如果情况并非如此,只有一个单一的进程已加载的共享对象,它不是几乎一样重要。
我在一个静态库的共享对象库版本的链接阶段如下:G ++ -shared -o libshared.so轮候册, - 全归档-fPIC -lstatic轮候册, - 没有整个归档。 由于--whole-存档链接(列表)中的每个对象与-fPIC静态库(形式libstatic.a)我相信(名单)之前是所有OP需要做的。
作为一个替代方法,船舶两个库:共享一个和静态您链接对并肩作战。 他们应该正确链接到最终的可执行文件。
文章来源: Linking a shared library against a static library: must the static library be compiled differently than if an application were linking it?