背景
在Unix环境下,将原先静态链接目标(.a),重新编译链接生成动态链接库(.so)时,项目使用GNU make,产生如下报错:”/usr/bin/ld: ex.o: relocation R_X86_64_32 against `.rodata’ can not be used when making a shared object; recompile with -fPIC”
分析
经过反复查验,发现makefile编写无误,确实使用了-fPIC的编译选项。
问题关键在于,由于笔者没有显示地(explicitly)将中间目标.o文件删除、进行重新编译。由于编译链接成动态链接库需要将源代码.c文件生成位置无关代码(PIC),即Position Independent Code,gcc使用的即是fPIC编译链接选项。然而,先前使用的是静态链接,生成的.o文件并非PIC。
关于PIC及静态库、动态库的相关知识可参见《Computer System:A Programmer’s Perspective》一书第七章。而GNU make对于未更新的.o文件不做重新编译,因此报错。
解决
因此,解决方法就是将中间目标全部删除,重新执行make。可见,编写make时,养成编写clean选项是一个必要的好习惯。而将项目从静态链接库转变成动态链接库时,也需要手动显示地make clean。
If you like this blog or find it useful for you, you are welcome to comment on it. You are also welcome to share this blog, so that more people can participate in it. If the images used in the blog infringe your copyright, please contact the author to delete them. Thank you !