环境: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
必须仅应用于那些公开外部函数的源文件?
在大图中,我有一堆可能没有用-fPIC
标志编译的归档(.a)文件。我需要创建一个与这些存档文件链接的自定义共享库。如果我的假设有效,我认为可以链接这些存档文件。欣赏你的想法。问候。
答案 0 :(得分:1)
我们可以得出结论,-fPIC必须只应用于那些源文件 暴露外部功能?
不,我们不能。 -fPIC
的唯一目的是确保生成的机器代码可以链接到与位置无关的二进制文件。尽管如此,即使没有-fPIC
编译源代码,某些代码似乎也可能是PIC就绪的。它可能是没有外部依赖性的短自包含函数,无论生成的目标文件中是否需要辅助数据结构,如PLT和GOT条目。
如果您的目标文件无法链接到与位置无关的二进制文件,那么无论如何链接器都将失败并显示全面的错误消息。你需要用这个神奇的选项重新编译它。
因此,您应始终将-fPIC
放到共享库的CFLAGS
,以节省您自己的时间并避免浪费的重新编译。
答案 1 :(得分:1)
如果可执行文件中存在一个没有-fPIC标志的目标文件,则会有一些程序文本页面具有位置相关的内存引用。这些页面无法在运行时重新定位到合适的虚拟内存地址(这主要是共享对象的目的)。当您在其他计算机上构建代码或将.so链接到其他代码时,这些位置相关的内存引用将来自您。
-fPIC需要为:
生成与位置无关的代码此外,在Linux / x86-32上编译/链接没有-fPIC的目标文件时,您可能会在没有任何警告或错误的情况下离开;但是在一些架构上不可能这样做。