-fPIC仅用于共享库吗?

xml*_*lmx 4 c c++ gcc compilation elf

我知道-fPIC共享库是必需的,并且知道为什么。

但是,我不清楚这个问题:

不应-fPIC在构建可执行文件或静态库时使用它?

Emp*_*ian 5

不应-fPIC在构建可执行文件或静态库时使用它?

从来没有一个强词,上面的陈述是错误的。

使用-fPIC(内部)构建的代码不是最佳选择,那么为什么要将其放入共享库以外的任何内容中?

让我们从一个静态库开始,它有一个简单的答案。

假设你想给你的用户可以链接到一个静态库或者可执行文件,到自己的共享库?

在这种情况下,您必须给他们3个单独的存档库(一个-fPIC用于链接到共享库的内置库,一个-fPIE用于链接到PIE可执行文件的内置库,以及一个“常规”库),或者您可以给他们一个单独的存档库(必须使用-fPIC)构建代码。

现在,可能有人争辩说,您应该给他们一个共享库,但是这迫使您的最终用户分发2个二进制文件,他们可能不愿意这样做。

但是,假设您要构建一个常规(非PIE)可执行文件。将-fPIC代码链接到此类可执行文件的原因可能是什么?

好吧,假设您正处于开发阶段,并且还不太在乎优化代码。进一步假设您想将代码作为共享库以及作为PIE和非PIE可执行文件的一部分进行测试。

在上述条件下,你既可以编译代码3次(有和没有-fPIC,和用-fPIE),或者你可以编译它一次(与-fPIC),并将其链接到共享库,PIE和非PIE可执行文件的所有3。这样做可以节省大量的编译时间,并节省一些构建系统的复杂性。

TL; DR:将-fPIC对象放入可执行文件和静态库具有其位置,并且您应该了解执行此操作的原因(如果最终执行此操作)。

更新:

目标文件中的代码始终可重定位

正确。

它是位置无关的代码吗?

否:并非所有可重定位代码都与位置无关。

与位置无关的代码是可重定位代码的子集。可重定位代码可以具有适用于任何部分的重定位。与位置无关的代码不得针对.text(和.rodata)进行任何重定位。