为什么在x86_64上编译静态库时gcc不会隐式提供-fPIC标志

Has*_*yed 59 gcc compilation dynamic-linking gnu-toolchain static-linking

编译静态链接静态库的共享对象时遇到了很多问题.此问题仅出现在x84_64平台上.在x86_32上进行相同的编译工作时,我没有任何问题.

也许这是一个特定于操作系统的GCC配置,但我的研究表明它是如何在x86_64平台上运行GCC的.无论如何,我在Ubuntu 10.04 x86_64上使用gcc 4.4.3.

问题是如何解决的?...确保使用-fPIC编译所有静态库依赖项.

问题1: -fpic和-fPIC之间有什么区别(显然-fPIC会在x86上生成更多指令)?为什么后一种类型在x86_64上下文中更相关?

问题2:我的假设是,当您链接静态代码时,您在链接时将函数硬连接到二进制文件中,为什么它需要"位置无关代码"机制提供的间接级别?

问题3:现在如果x86不需要-fpic/-fPIC来链接共享对象与静态存档,为什么在x86_64中需要它?

问题4:即使需要,为什么不隐式提供?我认为突破性变化应该是一个很大的禁忌

F'x*_*F'x 48

  1. 见问题3544035.也在这里那里讨论.
  2. 这取决于您对静态库的用途.如果你只想将它链接到程序中,它就不需要PIC代码(libtool称之为便利库,因为你几乎可以没有它,它只是帮助你的编译过程达到合理的大小,例如).否则,如果您打算将共享库链接到它,则需要在静态库中使用PIC代码.
  3. 请参阅问题3146744以及此处
  4. 它使您的代码膨胀,因此它不是默认代码.有一点需要注意的是,当您编译单个目标文件时,GCC不知道您是否要创建一个共享库.在我的大多数小项目中,我只是将几个目标文件链接在一起,例如,不需要PIC代码.

另外,我的建议是:如果你需要担心,你做错了(或者你喜欢学习艰难的方式,这很好,因为你会从经验中获得更多).编译系统(libtool,cmake,无论你使用什么)都应该为你做.

  • 当您将静态库链接到共享库时,它不再涉及目标代码,因此首先需要以正确的方式(使用 PIC)对其进行编译。 (2认同)