-fPIC在构建共享库时是什么意思?


109

我知道' -fPIC'选项与解析地址和各个模块之间的独立性有关,但是我不确定它的真正含义。你可以解释吗?


1
另外如果你想更详细地知道有这里是一个伟大的文章(akkadia.org/drepper/dsohowto.pdf
MJ

Answers:


61

PIC代表位置独立代码

并引用man gcc

如果目标机器支持,则发出与位置无关的代码,该代码适用于动态链接并避免对全局偏移表的大小进行任何限制。此选项对m68k,PowerPC和SPARC有所不同。与位置无关的代码需要特殊的支持,因此仅在某些机器上有效。

在提到的体系结构上构建共享库(* .so)时使用此功能。


1
f并不代表任何含义,它只是选项名称的一部分。
Zifre

17
fpic和fPIC之间有区别。它们都做相同的事情,但是fpic在可用的情况下使用较短的相对偏移量。因此,使用fpic进行编译可能会产生较小的文件。不幸的是,它并不总是能按预期工作,因此请使用fPIC。另请注意,并非所有处理器都支持较短的偏移量,因此可能不会有所不同。
马丁·约克

2
'f'是gcc处理命令行参数的方式的宿醉(这是几年前的事,他们更改了我最近没看过的那部分代码)。但是当时只允许在不同条件下使用某些字母或组合(定义命令行参数的语言非常复杂),因此使用“ f”可以轻松地将其定义为命令行参数。
马丁·约克

2
如果没有fPIC构建* .so,会发生什么?
Isa

2
@IsaA我今天从源代码编译了一个c-api mysql函数,但是它无法构建,/usr/bin/ld: /tmp/cc7hXILq.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC所以我添加了fPIC并构建了它。
chiliNUT

32

f是选项“控制接口约定在代码生成中使用的”在gcc前缀

PIC代表“位置无关的代码”,它的一个专业化fpic的M68K和SPARC。

编辑:在阅读了0x6adb015引用文档的第11页和coryan的注释之后,我进行了一些更改:

此选项仅对共享库有意义,并且您告诉操作系统您正在使用全局偏移表GOT。这意味着您所有的地址引用都是相对于GOT的,并且代码可以跨多个进程共享。

否则,没有此选项,加载程序将不得不自行修改所有偏移量。

不用说,我们几乎总是使用-fpic / PIC。


1
我以为OS可以自由地在任何虚拟地址中加载库,但是如果没有pic / PIC,则加载器必须修改代码并调整所有绝对跳转+间接指向例程/库的实际位置。使用pic / PIC时,代码不会被修改,因此实际上可以在多个进程之间共享。
coryan

多个过程在很大程度上是偶然的-它们的关键是代码可以在绝对最小的地址修正的情况下在任何虚拟地址处加载。
乔纳森·勒夫勒

16

man gcc 说:

-fpic
  生成适用于共享的位置无关代码(PIC)
  库(如果目标计算机支持)。这样的代码访问所有
  通过全局偏移表(GOT)的常量地址。动态的
  程序启动时,加载程序会解析GOT条目(动态
  加载程序不属于GCC;它是操作系统的一部分)。如果
  链接的可执行文件的GOT大小超过了计算机特定的大小
  最大大小,您会从链接器收到一条错误消息,指示
  -fpic不起作用;在这种情况下,请改用-fPIC重新编译。
  (在SPARC上,这些最大值为8k;在m68k和RS / 6000上,最大值为32k。
  386没有此限制。)

  与位置无关的代码需要特殊的支持,因此
  仅适用于某些机器。对于386,GCC支持PIC
  系统V,但不适用于Sun 386i。为生成的代码
  IBM RS / 6000始终与位置无关。

-fPIC
  如果目标机器支持,则发出与位置无关的代码,
  适用于动态链接并避免大小限制
  全局偏移表。该选项对m68k有所不同
  和SPARC。

  与位置无关的代码需要特殊的支持,因此
  仅适用于某些机器。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.