环境: Ubuntu 16.04
在我的实验中,我运行了以下命令:
gcc -c 1.c
gcc -c -fPIC 2.c
gcc -shared 1.o 2.o -o libmyxxx.so我需要公开的函数都是通过extern "C"声明在2.c中定义的。这些函数内部调用1.c中定义的其他函数。
请注意,我没有将-fPIC应用于1.c。尽管如此,没有任何警告,一切似乎都很好地编译/链接。
我们能否得出结论,-fPIC必须仅应用于那些公开外部函数的源文件?
在更大的图中,我有一堆存档(.a)文件,这些文件可能不是用-fPIC标志编译的。我需要创建一个自定义共享库来链接到这些归档文件。如果我的假设是正确的,我认为可以链接到这些档案文件。感谢你的想法。致以问候。
发布于 2017-06-06 17:13:20
我们能否得出结论,-fPIC必须仅应用于那些公开外部函数的源文件?
不,我们不能。-fPIC的唯一目的是确保生成的机器代码可以链接到与位置无关的二进制文件中。尽管如此,即使源代码是在没有-fPIC的情况下编译的,也有可能有些代码看起来已经准备好了。它可能是短的、不需要外部依赖的自包含函数,这将不需要生成的对象文件中的辅助数据结构,比如PLT和GOT条目。
无论如何,如果您的目标文件不能链接到独立于位置的二进制文件,链接器将失败。你需要用这个神奇的选项重新编译它。
因此,您应该始终将-fPIC放到共享库的CFLAGS中,以节省您自己的时间,避免浪费的重新编译。
发布于 2017-06-06 20:30:00
如果可执行文件中有一个没有-fPIC标志而编译的对象文件,则会有具有位置相关内存引用的程序文本页。这些页面将无法在运行时被重新定位到合适的虚拟内存地址(这主要是共享对象的目的)。当您在其他计算机上构建代码或将.so链接到其他代码时,这些位置相关的内存引用将出现并对您进行字节化。
-fPIC需要生成与位置无关的代码,用于:
此外,在Linux/x86-32上编译/链接一个没有-fPIC的对象文件时,您可能没有任何警告或错误;但是在某些体系结构上不可能做到这一点。
https://stackoverflow.com/questions/44395448
复制相似问题