undefined reference to `__assert_fail'

本文记录了一次在编译DD-WRT时遇到的链接错误,详细解释了错误产生的原因及解决过程。通过调整编译环境,避免了不同库间的冲突。

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

今天同事问了我一个关于DD-WRT编译的问题,在link里面一个工具的时候出现了下面的错误:

 

[root@localhost dhcpforwarder]# mipsel-linux-uclibc-gcc -o dhcpfwd -ffunction-sections -fdata-sections -Wl,--gc-sections src/parser.o src/main.o src/cfg.o src/recvfromflags.o src/output.o

/home/ipdslam_users/yzeng/dd-wrt/toolchains/4.1.0-uclibc-0.9.28/bin/../lib/gcc/mipsel-linux-uclibc/4.1.0/../../../../mipsel-linux-uclibc/bin/ld: BFD 2.16.1 assertion fail /home/openwrt/trunk/openwrt/toolchain_build_mipsel/binutils-2.16.1/bfd/elfxx-mips.c:2562

src/main.o: In function `execRelay':

main.c:(.text+0x590): undefined reference to `__assert_fail'

main.c:(.text+0x690): undefined reference to `__assert_fail'

src/main.o: In function `determineMaxMTU':

main.c:(.text+0x914): undefined reference to `__assert_fail'

main.c:(.text+0x970): undefined reference to `__assert_fail'

src/main.o: In function `fillFDSet':

main.c:(.text+0xb4c): undefined reference to `__assert_fail'

src/main.o:main.c:(.text+0xbd4): more undefined references to `__assert_fail' follow

collect2: ld returned 1 exit status

 

我在

http://lists.busybox.net/pipermail/uclibc/2002-February/002657.html

上看到了这样一些描述:

 

On Sun Feb 17, 2002 at 10:49:59PM -0600, Alberto Alonso wrote:
> When trying to compile a program that uses the
> microwindows library I get the following error:
>
> nxproto.o(.text+0x13f): undefined reference to `__assert_fail'
> nxproto.o(.text+0x169): undefined reference to `__assert_fail'
>
> After doing some grepping I did see an assert function
> Could I use that one instead?
 
I think you must be mixing code compiled with glibc with code
compiled with uClibc, since glibc defines __assert_fail in
include/assert.h and #defines assert to call that, while uClibc
does not use or define __assert_fail at all...  Check that you
are not mixing libraries compiled with glibc with code compiled
with uClibc....
 
 -Erik

 

尝试清除了src/parser.o src/main.o src/cfg.o src/recvfromflags.o src/output.o这几个目标文件再去编译,发现链接成功了。

最后我们发现,在该主机上装了一个MontaVista 3.1 Pro的环境,而且PATH和CROSS_COMPILE这2个环境,默认都指向了MV,所以开始的时候的确有一部分是用MV的交叉编译器来编译的,后面修改过环境变量。因为MV里用的是Glibc的环境,所以就有了上面的错误。

 

我觉得我们在写一个编译脚本的时候,最好能够清除默认的一些环境变量,将本代码需要的环境导出。这样就不会因为在一台服务器上安装了太多的环境导致混乱。

 

<think>我们正在解决一个编译错误:undefined reference to `__assert_func' 根据用户提供的引用[1],这类错误通常是由于缺少函数实现体或链接时找不到对应的实现文件。 引用[1]中提到,解决方法是检查是否将包含该函数实现的文件加入到了编译(链接)过程中。 具体到错误信息:undefined reference to `__assert_func',这个函数通常与断言(assert)相关。 在C/C++中,断言失败时会调用__assert_func函数。这个函数通常由C库提供。 可能的原因和解决方法: 1. 检查是否在链接时缺少了C库。确保链接了标准C库(例如,gcc中会自动链接libc,但有时可能需要显式指定)。 2. 检查是否在编译时定义了宏(如NDEBUG)导致断言被禁用,从而可能引起链接时缺少该函数?但通常即使禁用断言,也不会出现链接错误,因为标准库会提供该函数。 3. 可能是交叉编译时工具链不完整,缺少对应的库文件。 4. 检查代码中是否自己定义了assert相关的宏,但没有提供__assert_func的实现?如果自定义了断言宏,则需要提供相应的实现。 根据引用[1]的提示,我们可以尝试将包含__assert_func实现的源文件或库加入到链接中。 但是,__assert_func通常是在标准C库中实现的。因此,如果出现这个错误,可能是因为链接时没有链接标准C库,或者链接顺序有问题。 解决方案步骤: 1. 确认编译命令中是否包含了标准C库。例如,在gcc中,通常会自动链接libc。如果使用了-nostdlib选项,则需要显式添加库。 2. 如果使用了-nostdlib,需要添加-lc来链接标准C库。 3. 检查是否在链接时缺少了包含该函数的库文件(如libc.a或libc.so)。 例如,在Android.mk(Android NDK构建文件)中,可能需要添加: LOCAL_LDLIBS := -lc 或者,在Makefile中,确保链接器命令包含了-lc。 另外,引用[2]提到一个生成器函数的例子,但似乎与当前问题无关,我们可以忽略。 因此,针对这个错误的解决方案是:确保链接了标准C库(libc)。 如果问题仍然存在,检查工具链的C库是否完整。 生成相关问题: 1. 如何检查标准C库是否被正确链接? 2. 在交叉编译环境中如何指定C库路径? 3. 如何自定义断言函数以替换标准的__assert_func?</think>### 解决 "undefined reference to `__assert_func'" 错误 这个错误通常发生在编译链接阶段,表示链接器找不到 `__assert_func` 函数的实现。以下是逐步解决方案: #### 1. **检查标准库链接** - 确保编译时链接了标准 C 库(`libc`)。在编译命令末尾显式添加 `-lc````bash gcc your_file.c -o output -lc ``` - 如果使用了 `-nostdlib` 选项(禁止自动链接标准库),需手动添加所需库: ```bash gcc -nostdlib your_file.c -o output -lc -lgcc ``` #### 2. **验证工具链完整性** - 检查交叉编译工具链是否完整,特别是 C 库文件(如 `libc.a``libc.so`)。对于 Android NDK: - 确认 `android.mk` 包含所有必需文件: ```makefile LOCAL_LDLIBS := -lc # 显式链接标准C库 ``` - 检查 NDK 版本兼容性,必要时更新工具链[^1]。 #### 3. **检查自定义断言实现** - 若代码中重定义了 `assert` 宏,需提供 `__assert_func` 的实现。示例: ```c void __assert_func(const char *file, int line, const char *func, const char *expr) { fprintf(stderr, "Assertion failed: %s:%d %s: %s\n", file, line, func, expr); abort(); } ``` #### 4. **排查编译顺序问题** - 确保依赖库的链接顺序正确。将基础库(如 `libc`)放在命令末尾: ```bash gcc your_file.c -lother_lib -lc # 正确顺序 ``` #### 5. **检查系统库路径** - 确认链接器能找到库文件。添加库搜索路径: ```bash gcc your_file.c -o output -L/path/to/libs -lc ``` - 使用 `ldd` 检查可执行文件的依赖关系: ```bash ldd output ``` ### 常见原因总结 | 原因 | 解决方案 | |---------------------|------------------------------| | 未链接标准 C 库 | 编译命令添加 `-lc` | | 工具链不完整 | 更新 NDK 或检查库文件完整性 | | 自定义断言未实现 | 补全 `__assert_func` 函数 | | 链接顺序错误 | 调整库顺序(基础库放最后) | > **提示**:Android NDK 项目需特别注意 `android.mk``LOCAL_LDLIBS` 配置,遗漏标准库会导致此错误[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值