Ubuntu17下Makefile编译C项目遇R_X86_64_32S重定位错误求助
解决Ubuntu 17下Makefile编译C项目的R_X86_64_32S链接错误
这个问题我之前帮不少开发者排查过,本质是64位系统下编译静态库时缺少**位置无关代码(PIC)**导致的链接冲突。咱们一步步来解决:
1. 先搞懂为啥报错
你看到的R_X86_64_32S是x86_64架构的32位重定位标记,当你把没有编译成位置无关的静态库(libgnl.a)链接到需要位置无关的目标时(比如共享库,或者某些64位可执行文件场景),链接器就会报错——因为64位环境里,共享对象要求代码能在内存任意地址加载,而普通编译出来的代码绑定了固定地址,自然不兼容。
2. 修改Makefile,给编译加-fPIC参数
你需要给生成gnl.o(以及静态库里所有.o文件)的编译规则加上-fPIC参数:
# 假设原来的单文件编译规则是这样 gnl.o: gnl.c gnl.h gcc -c gnl.c -o gnl.o # 修改后加上-fPIC gnl.o: gnl.c gnl.h gcc -c -fPIC gnl.c -o gnl.o
如果你的Makefile里有全局的CFLAGS变量,直接把-fPIC加到里面更省心,不用逐个改规则:
CFLAGS = -Wall -Wextra -fPIC # 把-fPIC追加到现有CFLAGS后面
3. 清理旧文件,重新编译
改完规则后,先把之前生成的.o和静态库清掉,再重新编译:
make clean make
这样新生成的libgnl.a里的所有目标文件都是位置无关的,链接时就不会再出现重定位错误了。
4. 额外检查:链接规则是否正确
如果你的最终目标是生成共享库,记得链接时加上-shared参数;如果是可执行文件,64位Ubuntu默认是支持的,但如果Makefile里有特殊链接选项,确认没有强制使用不兼容的模式。
给你贴个简化的Makefile示例,供参考:
CC = gcc CFLAGS = -Wall -Wextra -fPIC AR = ar ARFLAGS = rcs # 编译静态库libgnl.a lib/my/libgnl.a: gnl.o $(AR) $(ARFLAGS) $@ $^ # 编译最终可执行文件mysh mysh: main.o lib/my/libgnl.a $(CC) $(CFLAGS) $^ -o $@
内容的提问来源于stack exchange,提问作者Arthur Ringler
相关产品推荐
相关产品推荐

