交叉编译中出现的 'Undefined reference to __aeabi_read_tp' 错误

本文探讨了使用老版本GCC编译ALSA声音库时遇到的编译警告和错误问题,详细分析了错误原因,并提供了具体的解决方案,包括手动修改配置文件以支持线程本地存储。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一些开源软件的configure程序不会为用户提供编译器相关的细粒度控制,就像我用gcc-3.4.3这种老掉牙来编译alsa-sound库,给了一段莫名其妙的错误:

../src/.libs/libasound.a(pcm_dmix.o): In function `snd_pcm_dmix_sync_ptr':
pcm_dmix.c:(.text+0x2550): warning: Warning: snd_pcm_hwsync() is deprecated, consider to use snd_pcm_avail()
../src/.libs/libasound.a(error.o): In function `snd_lib_error_set_local':
error.c:(.text+0xb4): undefined reference to `__aeabi_read_tp'
error.c:(.text+0xc4): undefined reference to `__aeabi_read_tp'
../src/.libs/libasound.a(error.o): In function `snd_lib_error_default':
error.c:(.text+0x110): undefined reference to `__aeabi_read_tp'
error.c:(.text+0x124): undefined reference to `__aeabi_read_tp'
collect2: ld returned 1 exit status

查看代码:

snd_local_error_handler_t snd_lib_error_set_local(snd_local_error_handler_t func)
{
	snd_local_error_handler_t old = local_error;
	local_error = func;
	return old;
}

看似没有那些asm之类的代码。google一通,看到有个拽人搞了个__aeabi_read_tp空函数解决了 *_*

只好回去仔细查看函数中的那三行代码,终于找到了蛛丝马迹,对于local_error有如下定义:

#ifndef DOC_HIDDEN
#ifdef HAVE___THREAD
#define TLS_PFX		__thread
#else
#define TLS_PFX		/* NOP */
#endif
#endif

看来是使用的编译器不支持线程本地存储关键字,而软件包带来的configure竟然也没有这个控制选项。只好手动修改configure产生的config.h文件。

(简单的去掉__thread是能通过编译,但还是要手动实现相关数据的tls才能保证程序的行为不变)


<think>根据用户的问题,他遇到了链接错误:“undefined reference to __aeabi_unwind_cpp_pr1”。我将结合提供的引用信息,分析原因并提供解决方案。 ### 问题分析: 1. **错误信息含义**:该错误表示链接器在链接过程中找不到`__aeabi_unwind_cpp_pr1`符号的定义。这个符号通常与C++异常处理(Exception Handling)和栈展开(Stack Unwinding)相关,属于ARM架构的ABI(Application Binary Interface)的一部分。 2. **可能的原因**: - **使用了C++异常处理**:当代码中使用了`try/catch`或抛出异常,需要链接相应的异常处理库(如`libunwind`或`libgcc`)。 - **编译器选项配置问题**:如使用了`-nostdlib`或`-nostartfiles`选项,这些选项会禁止链接标准库(包括异常处理库)。 - **工具链不完整**:交叉编译工具链可能缺少必要的库文件(如`libgcc.a`或`libgcc_eh.a`)。 - **链接顺序问题**:链接库的顺序不正确,导致异常处理库没有被正确链接。 ### 解决方案: 1. **添加异常处理库**:显式链接`libgcc`或`libunwind`库。例如,在链接命令中加入`-lgcc`或`-lunwind`。 - 示例:`arm-linux-gcc -o myapp myapp.o -lgcc` 2. **检查编译器选项**:避免使用`-nostdlib`选项(除非明确知道不需要标准库)。如果必须使用`-nostdlib`,则需要手动添加必要的库(如`libgcc`)。 - 例如,将`-nostdlib`替换为`-nostartfiles`(只忽略启动文件,但保留标准库)或完全移除该选项。 3. **指定库路径**:如果工具链的库路径未正确设置,使用`-L`选项指定库目录。 - 示例:`arm-linux-gcc -o myapp myapp.o -L/path/to/lib -lgcc` 4. **检查工具链完整性**:确认交叉编译工具链是否包含`libgcc.a`等库文件。可搜索工具链安装目录下的`lib`子目录。 5. **使用完整工具链命令**:确保使用正确的编译器前缀。如引用[3]所述,使用`arm-none-linux-gnueabi-gcc`而不是通过符号链接的`arm-linux-gcc`,以避免潜在问题。 6. **代码中禁用异常**:如果不需要C++异常处理,可以在编译添加`-fno-exceptions`选项禁用异常(但需确保代码中没有使用异常)。 ### 示例解决方案: 假设使用`arm-linux-gcc`编译,错误信息为`undefined reference to __aeabi_unwind_cpp_pr1`,可尝试以下步骤: ```bash # 步骤1:添加-lgcc显式链接 arm-linux-gcc -o myapp main.o -lgcc # 步骤2:如果步骤1无效,指定libgcc的完整路径 arm-linux-gcc -o myapp main.o /path/to/toolchain/lib/libgcc.a # 步骤3:检查是否误用-nostdlib,若有则移除或替换 # 原命令(错误): # arm-linux-gcc -nostdlib -o myapp main.o # 修改为: arm-linux-gcc -o myapp main.o ``` ### 注意事项: - 该错误常见于**C++代码**的链接阶段,纯C项目通常不会触发(除非混合C++代码)。 - 如果项目使用C++,确保链接器包含C++标准库(如`-lstdc++`)。 §§相关问题§§ 1. 如何检查交叉编译工具链的完整性? 2. 链接器选项`-nostdlib`和`-nostartfiles`有什么区别? 3. ARM架构中栈展开(Stack Unwinding)的实现原理是什么?</think>### `undefined reference to __aeabi_unwind_cpp_pr1` 解决方案 #### **问题原因分析** 该错误通常由以下原因导致: 1. **缺少C++异常处理库** `__aeabi_unwind_cpp_pr1` 是ARM架构中C++异常处理(栈展开)的核心函数。当代码包含`try/catch`等异常处理机制,需链接`libgcc`或`libunwind`库[^2]。 2. **编译器选项冲突** 使用 `-nostdlib`(禁用标准库)或 `-ffreestanding`(独立环境),编译器会跳过异常处理库的自动链接[^2]。 3. **工具链配置问题** 交叉编译工具链的库路径未正确配置,或符号链接(如 `arm-linux-gcc` 指向 `arm-none-linux-gnueabi-gcc`)导致库路径解析失败[^3]。 --- #### **解决方案** ##### 方法1:显式链接异常处理库 在链接命令中添加 `-lgcc` 或 `-lunwind`: ```bash arm-linux-gcc main.o -o output -lgcc # 链接libgcc ``` 或指定完整路径: ```bash arm-linux-gcc main.o -o output /path/to/toolchain/lib/libgcc.a ``` ##### 方法2:检查编译器选项 - **移除 `-nostdlib`** 若需保留自定义库,改为 `-nostartfiles`(仅跳过启动文件,保留标准库): ```bash arm-linux-gcc -nostartfiles main.o -o output # 允许链接libgcc ``` - **添加异常支持** 对纯C项目,添加 `-fexceptions` 启用异常处理: ```bash arm-linux-gcc -fexceptions -c main.c ``` ##### 方法3:修复工具链配置 1. 检查工具链完整性: ```bash find /path/to/toolchain -name "libgcc.a" # 确认库文件存在 ``` 2. 修正符号链接指向: ```bash # 确保符号链接指向真实工具链 ln -sf /real/path/arm-none-linux-gnueabi-gcc /usr/bin/arm-linux-gcc ``` 3. 设置库搜索路径: ```bash export LIBRARY_PATH=/path/to/toolchain/lib:$LIBRARY_PATH ``` ##### 方法4:禁用异常(应急方案) 若无需异常处理,编译禁用: ```bash arm-linux-gcc -fno-exceptions -c main.cpp # 彻底移除异常支持 ``` --- #### **验证步骤** 1. 检查目标文件是否包含异常符号: ```bash arm-linux-nm main.o | grep __aeabi_unwind ``` 2. 查看链接器是否找到库: ```bash arm-linux-ld --verbose | grep SEARCH_DIR # 检查库搜索路径 ``` > **关键提示**:此错误常见于 **C++代码交叉编译到ARM平台** 的场景,本质是链接器未找到ARM ABI的异常处理函数实现[^2][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值