一些老版本的DEMO经常会出现的错误(ld: -pie can only be used when targeting iOS 4.2 or later clang: error: linker c)

本文介绍了因模拟器版本过旧导致的问题及解决方法。通过调整版本设置,使其与模拟器相匹配,从而解决运行中出现的错误。

错误提示:


错误原因:因为版本比较旧,模拟器与版本不匹配

解决方法:如下图,将版本改为与模拟器相匹配就行了

图2



<think> 我们正在处理一个编译链接错误错误信息是: 'relocation R_X86_64_32 against `.rodata' can not be used when making a PIE object; recompile with -fPIE' 以及 '/usr/bin/ld: failed to set dynamic section sizes: bad value' collect2: error: ld returned 1 exit status 根据引用资料,这个错误通常与位置无关代码(PIE)有关。在较新的Ubuntu版本(如18.04)中,编译器的默认设置可能启用了PIE(位置无关可执行文件),而旧版本(如16.04)没有。当链接器尝试将非位置无关的代码(如一些没有使用-fPIE-fPIC编译的静态库或目标文件)链接到PIE可执行文件时,就会出现这种错误。 解决思路: 1. 重新编译所有源代码(包括依赖的库)时加上-fPIE-fPIC选项,以生成位置无关的代码。 2. 如果某些依赖的库无法重新编译(如第三方预编译库),则可能需要禁用PIE。 具体步骤: 方法一:重新编译并添加-fPIE-fPIC选项 - 如果是自己编译的代码,可以在编译命令(CFLAGS/CXXFLAGS)中添加`-fPIE`或`-fPIC`选项。 - 例如:`gcc -fPIE -c file.c` 编译源文件,然后在链接时使用`-fPIE -pie`(或者直接使用`-pie`,但编译时通常需要-fPIE)。 - 对于链接阶段,通常需要在编译所有目标文件时使用`-fPIE`,然后在链接可执行文件时加上`-pie`选项(有时链接器会自动处理,但显式指定更安全)。 - 如果项目使用makefile,可以修改CFLAGS/CXXFLAGS: ``` CFLAGS += -fPIE LDFLAGS += -pie ``` 方法二:禁用PIE(如果重新编译不可行) - 在链接时添加`-no-pie`选项,禁用PIE- 例如:`gcc -no-pie -o program file1.o file2.o ...` - 注意:禁用PIE可能会降低安全性(因为关闭了ASLR对可执行文件的保护),所以优先考虑方法一。 根据引用[5]中的例子,错误信息中提示了&ldquo;recompile with -fPIE”,所以重新编译目标文件(.o文件)时加入`-fPIE`可能是最直接的解决方法。 另外,错误信息中还出现了&ldquo;/usr/bin/ld: failed to set dynamic section sizes: bad value”,这通常是因为链接过程中出现了前面的错误(即重定位错误)而导致的连锁错误。因此,解决重定位问题后,这个错误也会消失。 实例分析引用[4]:在edk2编译BaseTools时,错误指向了静态库libCommon.a中的目标文件需要重新编译。解决方法应该是重新编译生成这个静态库,并在编译库的源代码时加上`-fPIC`(因为静态库会被链接到共享库或PIE可执行文件中,通常使用-fPIC)。 步骤总结: 1. 找到所有需要重新编译的源代码(包括依赖库),确保编译时加入`-fPIE`或`-fPIC`(对于静态库,推荐使用`-fPIC`)。 2. 重新编译这些代码,生成新的目标文件。 3. 在链接可执行文件时,确保使用`-pie`选项(如果使用-fPIE则链接时需要-pie,如果使用-fPIC则不一定需要,但两者都可以)。 如果无法重新编译某些依赖库(比如第三方预编译库),则尝试在链接时使用`-no-pie`来禁用PIE。 对于用户的具体错误,可以尝试: - 如果正在构建自己的项目,修改Makefile(或构建脚本)中的编译标志。 - 如果使用cmake,可以在CMakeLists.txt中添加: ```cmake set(CMAKE_POSITION_INDEPENDENT_CODE ON) ``` 这会在编译时自动添加`-fPIC`(或`-fPIE`,取决于目标类型)。 注意:在Ubuntu 16.04升级到18.04后,默认的gcc行为发生了变化,启用了PIE。因此,在升级系统后编译旧项目可能会遇到此问题。 最后,请确保在修改后重新构建整个项目(先clean再重新编译)。 如果上述方法都不能解决,请检查是否还有其他链接错误,因为多个错误可能同时存在。 </think> ### 解决 `relocation R_X86_64_32 against `.rodata'` 错误的方法 该错误是由于 **位置无关代码(PIE)** 的编译策略冲突导致,常见于 Ubuntu 18.04+ 或较新的 GCC 版本。以下是完整解决方案: #### 🔧 方法一:添加编译选项(推荐) 在编译命令中加入 `-fPIE` 和 `-pie` 标志: ```bash # C语言项目 gcc -fPIE -pie -o your_program *.c # C++项目 g++ -fPIE -pie -o your_program *.cpp # Makefile修改示例 CFLAGS += -fPIE LDFLAGS += -pie ``` **原理**: Ubuntu 17.10+ 默认启用 PIE 增强安全性[^2][^5],`-fPIE` 生成位置无关代码,`-pie` 使可执行文件支持地址随机化(ASLR)。 #### 方法二:强制禁用 PIE(备用) 若方法一无效,临时禁用 PIE 兼容性: ```bash gcc -no-pie -o your_program *.c ``` > ⚠️ 注意:这会降低程序安全性,仅建议临时测试使用[^3][^5]。 #### 📦 方法三:重建依赖库 当错误涉及静态库(如 `.a` 文件)时: ```bash # 1. 清理旧编译 make clean # 2. 重新编译库(关键步骤) cd path/to/library make CFLAGS="-fPIC" CXXFLAGS="-fPIC" # 3. 重新链接主程序 gcc -fPIE -pie -o main main.c -L/path/to/library -lmylib ``` **关键点**: 静态库需用 `-fPIC`(非 `-fPIE`)编译[^4],因其会被多个可执行文件共享。 #### 系统级修复 更新系统工具链: ```bash sudo apt update sudo apt install --reinstall build-essential binutils ``` --- ### 错误原因深度分析 1. **PIE 机制冲突** 新系统默认要求所有代码段支持地址随机化,但旧目标文件(`.o`/`.a`)未按此标准编译[^1][^2][^5]。 2. **重定位类型限制** `R_X86_64_32` 重定位要求绝对地址,与 PIE 的相对地址需求冲突[^3]。 3. **工具链版本差异** Ubuntu 16.04 → 18.04 后 GCC 默认启用 PIE[^2],导致旧项目编译失败。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值