You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用aarch64-none-elf工具链交叉编译TFLite C API时G++报错

解决ARM裸机工具链交叉编译TensorFlow Lite C API的CMake错误

问题根源

你使用的aarch64-none-elf是裸机目标工具链,配套的newlib标准库需要用户手动实现_exit、_write等底层系统调用桩函数,CMake测试C编译器时链接简单程序找不到这些符号,导致测试失败。此外TensorFlow Lite的CMake配置可能默认依赖C环境,即使只编译C API也会触发C++编译器检测。

可行解决方案

1. 强制跳过C++编译器检测

在CMake工具链文件中添加以下配置,让CMake复用C编译器代替C编译器,并强制跳过C编译器有效性测试:

# 复用C编译器作为C++编译器
set(CMAKE_CXX_COMPILER "${CMAKE_C_COMPILER}")
# 强制CMake不测试C++编译器
set(CMAKE_CXX_COMPILER_FORCED ON)
# 禁用C++相关构建目标
set(BUILD_CXX OFF CACHE BOOL "Disable C++ builds")

或者直接在CMake命令行传递参数:

cmake .. \
  -DCMAKE_TOOLCHAIN_FILE=your_toolchain_file.cmake \
  -DCMAKE_CXX_COMPILER=$(which aarch64-none-elf-gcc) \
  -DCMAKE_CXX_COMPILER_FORCED=ON \
  -DBUILD_CXX=OFF

2. 实现裸机系统调用桩

针对aarch64-none-elf工具链,创建一个syscalls.c文件,实现newlib要求的系统调用桩(根据实际需求调整实现):

#include <sys/stat.h>

// 程序退出桩
void _exit(int status) {
    while (1); // 死循环代替退出
}

// 输出桩(可改为串口输出逻辑)
int _write(int fd, char *buf, int len) {
    // 示例:忽略输出,返回写入长度
    return len;
}

// 文件关闭桩
int _close(int fd) {
    return -1;
}

// 文件定位桩
int _lseek(int fd, int ptr, int dir) {
    return 0;
}

// 输入桩
int _read(int fd, char *buf, int len) {
    return 0;
}

// 堆内存扩展桩
void *_sbrk(int incr) {
    extern char _end; // 链接脚本定义的程序结束地址
    static char *heap_end = NULL;
    if (heap_end == NULL) {
        heap_end = &_end;
    }
    char *prev_heap = heap_end;
    heap_end += incr;
    return prev_heap;
}

然后在CMake中把这个文件加入编译,或者在工具链文件中添加链接参数:

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${CMAKE_CURRENT_LIST_DIR}/syscalls.c")

3. 改用Linux目标工具链

如果你的目标平台运行Linux系统,建议替换为aarch64-linux-gnu工具链(对应下载包为arm-gnu-toolchain-13.2.Rel1-x86_64-aarch64-linux-gnu)。该工具链针对Linux环境,配套glibc库自带完整系统调用实现,不会出现此类链接错误。

内容的提问来源于stack exchange,提问作者aurette

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 17:54:51