GCC问题:relocation R_X86_64_32 against `.rodata‘ can not be used when making a shared object;

1,225 阅读1分钟

问题现象

,
在这里插入图片描述
CentOS7, gcc 4.8.5 编译自己的动态库,调用pjlib库的时候,报错。

问题原因

下载官方pjlib源码,按照官方得编译步骤编译完成库是静态库,在连接静态库编译为动态库的过程中报错。

解决办法

需要编译自己的动态库的时候则增加 -fPIC参数。
增加之后完美解决。

为什么呢

-fPIC 作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code),
则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。

PIC就是position independent code.
PIC使.so文件的代码段变为真正意义上的共享.
如果不加-fPIC,则加载.so文件的代码段时,代码段引用的数据对象需要重定位, 重定位会修改代码段的内容,这就造成每个使用这个.so文件代码段的进程在内核里都会生成这个.so文件代码段的copy.每个copy都不一样,取决于 这个.so文件代码段和数据段内存映射的位置.

参考

[1] blog.sina.com.cn/s/blog_54f8…