ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ARM架构与交叉编译实战:从工具链选型到板卡部署全流程

ARM架构与交叉编译实战:从工具链选型到板卡部署全流程 做嵌入式或者搞边缘计算的人几乎都会撞上ARM 架构和交叉编译这两个词。尤其这几天我正好在折腾语音识别模型在 ARM 小盒子上的 CPU 部署又从 Qt 5.12.10 的交叉编译环境一路踩到 RK3576 的板子攒了一肚子的经验和坑。很多朋友一上来就拿着 x86 那套思路去搞 ARM结果在编译环节就被折腾得欲哭无泪。这其实不是能力问题而是没搞明白这两者之间的底层逻辑差异——你是在一个架构的电脑上为另一个架构的设备生产可执行代码这中间隔着的就是交叉编译要解决的那点事。这篇文章我不打算讲那种教科书式的大道理就从一个过来人的角度把这几天梳理的 ARM 架构核心要点、交叉编译工具链选型、完整实操步骤以及我踩过的那些坑掰开揉碎了跟你说清楚。不管你是刚入门想搞明白 ARM 和 x86 到底差在哪还是已经在交叉编译 Qt、部署模型时被各种报错折磨得头大这篇应该都能给你一些实在的参考。1. 内容整体设计与思路拆解1.1 从为什么不能直接编译说起先抛个问题你手上的电脑是 x86 架构的 CPU你的目标是给一块 RK3576 的开发板写程序这块板子的 CPU 是 ARM 架构。你用 GCC 在电脑上直接编译出来的程序能拷到板子上跑吗大概率跑不起来就算能跑起来也是各种花式报错。原因很简单x86 和 ARM 是两套不同的指令集它们认识的机器码根本就不是一回事。x86 用的是 CISC 复杂指令集指令又长又全单个指令能完成的操作很多ARM 不一样它走的是 RISC 精简指令集路线指令短小精悍追求的是低功耗和高效率。这就好比一个美国人写了一封英文信直接递给一个只懂中文的人对方当然看不懂你得先找个翻译把信翻成中文。所以交叉编译的交叉这两个字指的就是你在一种架构平台上编译出运行在另一种架构平台上的程序。而我们平时说的本地编译或者原生编译则是在什么架构上跑就编译什么架构的程序。既然懂了原理整个方案的设计思路就很清晰了先在 x86 主机上准备交叉编译工具链也就是那个翻译官。再配置对应的库和依赖让编译出来的程序能链接到 ARM 板子上需要的库。最后通过 make 或 cmake 之类的工具完成编译把生成的二进制文件拷到 ARM 板子上运行。这套流程听着简单实际做起来工具链选型、路径配置、链接库的顺序和路径这些细节哪一个都能卡住你好几天。1.2 工具链选型不止是下载一个编译器那么简单很多人对交叉编译的理解就是下载一个交叉编译器比如 arm-linux-gnueabihf-gcc然后就直接用了。但这个思路在 2025 年的今天其实已经不够用了甚至是有坑的。选工具链要考虑几个维度CPU 架构的匹配度ARMv7、ARMv8、Cortex-A 系列还是 Cortex-M 系列、32 位还是 64 位、用的 C 库是 glibc 还是 uclibc、交叉编译的目标系统是嵌入式 Linux、实时系统还是裸机。就拿我最近在用的 RK3576 来说它是 ARM Cortex-A72 架构64 位跑的是 Linux那就得选 aarch64-linux-gnu 系列的交叉编译器如果错选了 arm-linux-gnueabihf 这种 32 位工具链编译出来的东西到板子上直接就是 illegal instruction。另外工具链本身也有几个流派有 Linaro 出品的 gcc 工具链、有芯片原厂定制 SDK 里自带的工具链、也有开源社区维护的 Buildroot 和 Yocto。如果是玩评估板我强烈建议优先用板卡厂商 SDK 里自带的工具链因为那套工具链和板子上的内核、根文件系统、库版本是严格匹配的能少踩好多坑。像飞腾那边也提供了配套的交叉编译环境用起来比自己在网上拼凑一套工具链省心太多了。1.3 影响范围不光嵌入式AI 部署同样离不开它说到影响范围交叉编译的边界已经远远超出传统的嵌入式开发了。这两年边缘计算火起来越来越多的 AI 模型要跑到 ARM 架构的设备上做 CPU 推理。比如最近很多人折腾的 SenseVoice-Small 语音识别模型想把它部署到 ARM 小盒子上跑 CPU 推理就会遇到一模一样的问题模型依赖的底层算子库、推理框架ONNX Runtime、ncnn、MNN 这些全部要在 x86 上编译出 ARM 版本才能拷到板子上跑。Qt 开发方向也一样你在 x86 上用 Qt Creator 写的程序要部署到 ARM 板子上就得用 5.12.10 这类特定版本的 Qt 源码去做交叉编译这个过程涉及 qmake 的重新配置、编译链的指定、还有一大堆依赖库的链接问题。可以说只要你的目标设备是 ARM交叉编译就是绕不开的一道工艺门槛。理解了这一点你就能明白为什么这个问题老生常谈却依然值得反复讲。2. 核心细节解析与实操要点2.1 ARM 架构的关键细节别只记一个ARM名字ARM 这个词其实挺笼统的。就像你不能因为轿车和卡车都叫车就觉得它们开法一样不同 ARM 架构之间的差异有时候比 ARM 和 x86 之间的差异还大。现在主流的 ARM 架构大致有这几类ARMv7-A这是老一代的 32 位应用处理器架构Cortex-A7、Cortex-A9、Cortex-A15 这些经典核心都属于这个档次。很多工业控制板、老旧安卓平板用的都是这一类对应的交叉编译前缀是 arm-linux-gnueabihf。ARMv8-A这是目前主流应用的 64 位架构Cortex-A53、A72、A76、A78 都是它的子孙。大部分现代开发板树莓派 4/5、RK3568/RK3576、飞腾派都是这个架构的。它的交叉编译前缀通常是 aarch64-linux-gnu 这一档。Cortex-M 系列比如 STM32 用的 Cortex-M3/M4/M7这种是单片机一般跑 RTOS 或者裸机交叉编译方式又是另外一套往往用 arm-none-eabi- 这种不带 Linux 的裸机工具链。ARM 还有一个比较特殊的存在就是大小核架构比如 big.LITTLE一个大核一个效率核配合工作。这个特性对编译优化是有影响的你在编译时如果不针对具体 CPU 做 -mcpu 或 -mtune 优化性能可能就差那么一截。讲这些可能有点枯燥但对后续交叉编译非常关键因为工具链选择错后面全是白干。2.2 交叉编译工具链的组成不只是编译器本身很多教程喜欢把交叉编译工具链简称为交叉编译器好像只需要一个 gcc 程序就够了。实际上一套完整的交叉编译工具链至少包含四大件组件作用典型文件编译器源码编译成汇编/目标文件aarch64-linux-gnu-gcc汇编器汇编代码编程目标文件aarch64-linux-gnu-as链接器目标文件链接成可执行文件aarch64-linux-gnu-ldC 运行库提供 malloc、printf 等基础函数libc.so.6、crt1.o除了这四大件还有头文件、调试工具、binutils 辅助工具比如 objdump、readelf、strip这些。这些工具的最终目的都是为了让 x86 上的 GCC 能生成 ARM 架构的汇编再用 ARM 架构的汇编器去处理最后链接到 ARM 版本的 C 库上产出一个能在 ARM Linux 上跑起来的 ELF 文件。一个很容易出错的地方是链接动态库的时候如果用到了系统库比如 pthread、dl、m交叉编译器会自动去找它对应的 ARM 版本的库文件这个时候如果你不小心把 x86 的库路径写进了链接参数那链接器就会报一堆skipping incompatible的警告甚至直接失败。这种问题最容易发生在你为了省事手动指定 -I 和 -L 路径的时候。2.3 实操要点目录结构规划非常关键玩交叉编译最忌讳的就是项目的临时文件、目标文件、中间产物乱成一锅粥。我个人的习惯是建立一个标准的 cross-build 目录结构cross-build/ ├── tools/ # 存放交叉编译工具链 ├── sysroot/ # 目标板的根文件系统副本包含库和头文件 ├── build/ # 编译过程中生成的临时文件 ├── output/ # 最终生成的 ARM 可执行文件 └── src/ # 项目源码sysroot 是一个关键概念它就是目标板根文件系统的迷你镜像。我们编译时需要从头文件里知道库函数的声明从库文件里提取链接信息这些在 x86 电脑上默认都是 x86 的版本不能在交叉编译里用。所以需要从板子上把 /usr/include、/usr/lib、/lib 这些目录原样拷贝一份到主机上作为 sysroot交叉编译器通过 --sysroot 参数指向它才能找到正确的 ARM 版本头文件和库。这个细节很多人第一次接触时完全想不到结果是编译时各种找不到头文件或者链接时用了 x86 的 .so一运行就崩。3. 实操过程与核心环节实现3.1 环境准备用 Ubuntu 20.04 搭一套交叉编译环境我用的是 Ubuntu 20.04 系统主要是看上它稳定跟各种嵌入式 SDK 的兼容性都还不错。前面提到的几个热搜词里也有 Ubuntu 20.04 装 PetaLinux 和 Zynq7000 交叉工具链的需求这套环境是完全通用的。首先安装基础依赖。这一步千万别跳过后面缺了任何一个都会以奇怪的方式暴雷sudo apt update sudo apt install -y build-essential git wget file tree \ libncurses5-dev libncursesw5-dev zlib1g-dev gawk \ diffstat texinfo g-multilib python3 python3-pip \ chrpath socat cpio python3-distutils libyaml-dev然后找个地方放工具链。不同的工具链存放位置会影响后续的 PATH 配置建议统一放到 /opt 下面sudo mkdir -p /opt/cross sudo chown $USER:$USER /opt/cross cd /opt/cross假设我们现在用的是标准 ARMv8 工具链可以直接从 Linaro 开源镜像获取最新版本。如果你用的是 RK 系列的 SDK官方会直接给你一套 buildroot 目录里面自带工具链路径一般在 buildroot/output/host/bin/ 下面这种采用官方自带工具链的方式最省事。如果是手动下载 Linaro 工具链大概是这样的wget https://releases.linaro.org/components/toolchain/binaries/latest-7/aarch64-linux-gnu/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz tar -xvf gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz解压完之后把工具链的 bin 目录加入 PATHexport PATH/opt/cross/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin:$PATH然后验证一下是否安装成功aarch64-linux-gnu-gcc --version aarch64-linux-gnu-gcc (Linaro GCC 7.5-2019.12) 7.5.0看到这个输出说明交叉编译器已经就位了。不过这样只对当前的 shell 会话生效要永久生效可以把它写进 ~/.bashrc。3.2 一个最小的交叉编译实验从 hello 到 file 命令验证光有工具链还不够得实际跑一个程序验证流程。先写一个简单的 hello.c#include stdio.h int main(void) { printf(Hello ARM, from cross compile!\n); return 0; }然后使用交叉编译器编译aarch64-linux-gnu-gcc -o hello_cross hello.c这里默认不加什么选项交叉编译器会自行选择目标架构。编译完后用 file 命令看下产物file hello_cross hello_cross: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 3.7.0...看到 ELF 64-bit LSB executable, ARM aarch64 这一行说明程序确实是 ARM 架构的这就是交叉编译初步成功的迹象。如果你看不出区别可以对比看下在电脑上本地编译出的文件它是 x86-64 格式两者本质不同。这一步虽然简单但非常关键因为它能确认工具链和三方库的头文件、库文件是否齐全。如果这一步都跑不通后面再复杂的工程也不用看了。3.3 具体工程用 CMake 完成一个带依赖的交叉编译实际项目里很少直接拿 gcc 命令去编译整个工程基本都是用 CMake 来做构建管理。接下来我以一个小型 C 项目为例演示 CMake 交叉编译的完整配置。首先在工程根目录准备一个 toolchain.cmake 文件这个文件是 CMake 交叉编译的身份证set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR aarch64) set(TOOLCHAIN_PREFIX aarch64-linux-gnu-) set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc) set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g) set(CMAKE_FIND_ROOT_PATH /opt/cross/sysroot_aarch64) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)这份配置文件里有几个关键点需要你注意CMAKE_SYSTEM_NAME 和 CMAKE_SYSTEM_PROCESSOR告诉 CMake 现在是交叉编译目标是 aarch64 架构的 Linux。CMAKE_C_COMPILER / CMAKE_CXX_COMPILER指定交叉编译器。CMAKE_FIND_ROOT_PATH非常重要的一个字段它相当于 sysroot 的根路径让 CMake 在找头文件和库时只在这个路径下面找而不要去找宿主机的 /usr/include。三个 MODE 选项PROGRAM 设为 NEVER意思是查找程序时不受 sysroot 限制因为我们需要用的 cmake、gcc 这些工具是本机的LIBRARY 和 INCLUDE 设为 ONLY意思是查找库和头文件时只能在 sysroot 里面找绝对别跑偏。然后写一个 CMakeLists.txtcmake_minimum_required(VERSION 3.10) project(cross_demo) set(CMAKE_CXX_STANDARD 11) add_executable(cross_demo main.cpp)main.cpp 就简单点打印一行信息然后返回 0 即可。接下来进入 build 目录执行mkdir -p build cd build cmake .. -DCMAKE_TOOLCHAIN_FILE../toolchain.cmake make -j$(nproc)编译完成后用 file 再看一下 cross_demo如果显示 ARM aarch64 动态链接 ELF就说明整个 CMake 交叉编译链路是通的。后续你的工程里有什么第三方的静态库、动态库按相同办法放进 sysroot并配上 find_library 就能轻松搞定。3.4 从源码交叉编译 Qt 5.12.10一个典型的C 库地狱实例如果说前面的验证还比较轻松那么交叉编译 Qt 绝对是地狱模式的典型。我这次帮朋友折腾 RK3576 板子上的 Qt 5.12.10整整花了一天时间踩遍各种少库、缺头文件的问题。可以把核心过程拆解给你看。首先你需要准备一份 Qt 5.12.10 的源码不是那种在线安装包而是源码包。下载解压后需要写一个脚本指定交叉编译参数。重点在于 -xplatform 参数它告诉 Qt 我们是在做交叉编译并且使用的平台配置文件是哪个./configure -prefix /opt/qt5.12.10-aarch64 \ -xplatform linux-aarch64-gnu-g \ -release \ -opensource -confirm-license \ -nomake examples -nomake tests \ -no-opengl \ -no-xcb \ -skip qt3d \ -skip qtcanvas3d \ -skip qtvirtualkeyboard \ -skip qtwebengine \ -I/opt/cross/sysroot_aarch64/usr/include \ -L/opt/cross/sysroot_aarch64/usr/lib这里好几个参数都是血泪教训-skip qtwebengine这是 Qt6 之前的杀手级组件依赖大量的系统库如 ICU、libpng、libjpeg在交叉编译环境里几乎必然是地狱。如果不跳过去配置阶段可能通过但编译阶段大概率会挂掉。-no-opengl -no-xcb如果你的板子上没有 GPU 硬件或没有 X11 的依赖库这两个选项能避免你被一堆 OpenGL 头文件缺失的报错折磨。-I和-L指向 sysroot这一步太关键了Qt 配置阶段会去检测系统里有哪些库如果找不到它就会自动禁用对应的模块。你过去可能遇到过Qt 编译完了但很多模块缺失的情况八成就是系统库的路径没指对。配置通过之后就是漫长的 makemake -j$(nproc) make install编译时间看机器性能通常半小时到两小时不等。编译完成后在 /opt/qt5.12.10-aarch64 下就能看到一堆 ARM 架构的 Qt 库把这些库连同整个目录拷到板子上然后用板子上的 Qt 交叉编译套件去编译你的 Qt 工程就可以了。3.5 语音场景实战SenseVoice-Small 在 ARM CPU 上的部署思路说完了 Qt再讲讲这几天另一个热搜点SenseVoice-Small 模型在 ARM 架构 CPU 上的部署。语音识别模型上 ARM 盒子跑 CPU 推理是边缘计算里一个很典型的场景包括本地的语音指令控制、智能门禁、会议记录终端等。一般思路是这样先用 ONNX 把 SenseVoice-Small 导出成 onnx 模型再用 ONNX Runtime 的 ARM 版本进行推理。关键是 ONNX Runtime 本身是开源的官方预编译包也提供了 ARM Linux 版本可以直接从 GitHub 上下载。但如果你想对模型做量化或者做自定义算子优化就得走源码编译路线./build.sh --config Release \ --arm64 \ --build_shared_lib \ --parallel 8编译 ARM 版 ONNX Runtime 需要指定 --arm64 参数再配合前面说的交叉编译工具链和 sysroot。编译完成后会得到 libonnxruntime.so 和一堆头文件把这些文件和模型文件一起部署到板上再写一个 C 或者 Python 的调用程序就可以跑语音识别了。实际部署时内存占用和首次推理延迟是两个大头。ARM 盒子的内存往往不大模型加载时如果峰值内存过高就容易被杀进程首次推理如果延迟大往往是因为模型初始化和算子注册的耗时。可以先跑一个 warm-up 推理来预热然后看 steady-state 的延迟表现。SenseVoice-Small 本身参数量不大在 ARM CPU 上用 int8 量化后基本能做到几百毫秒内的识别延迟在一般语音交互场景里足够用了。4. 常见问题与排查技巧实录4.1 No such file or directory 但文件明明存在这个问题在交叉编译里太经典了尤其是在 Ubuntu 20.04 的 64 位系统上装 32 位工具链时。你明明把工具链解压好了文件也都存在但执行 aarch64-linux-gnu-gcc 却提示 No such file or directory。这大概率不是文件不存在而是动态链接器的问题——工具链本身是 32 位程序跑在纯 64 位系统上缺少 32 位运行库。解决办法是把 32 位库补上sudo dpkg --add-architecture i386 sudo apt update sudo apt install -y libc6:i386 libncurses5:i386 libstdc6:i386如果你使用的是 arm-linux-gnueabihf 这类 32 位工具链这个问题几乎是必现的所以很多人第一次在 x86_64 机器上跑都一脸懵。4.2 skipping incompatible 链接器警告链接时如果看到类似这样的警告skipping incompatible /usr/lib/x86_64-linux-gnu/libssl.so when searching for -lssl恭喜你交叉编译器跑到宿主机的库路径里去找库了找到的自然是 x86 版本跟 ARM 目标不兼容。根本原因是 -L 参数没有严格指向 sysroot。解决方法是使用 --sysroot 或者在 CMake 里把 CMAKE_FIND_ROOT_PATH 指到正确的 sysroot 上同时检查一下 toolchain.cmake 的路径配置是否正确。另外还有一种办法直接给工程指定-DCMAKE_EXE_LINKER_FLAGS--sysroot/opt/cross/sysroot_aarch64强制链接器进 sysroot 找库。不过这不是长久的做法建议还是从工程层面解决。4.3 fatal error: X11/Xlib.h: No such file or directory这个在交叉编译带 GUI 的项目时也是高频问题。大家的本能反应是明明板子上面有 X11 库啊为什么找不到因为板子上有库但宿主机 sysroot 里没有头文件和库文件的副本。交叉编译不是直接在板子上编译它需要在你宿主的 sysroot 里存放一切的依赖。你需要去目标板上执行下面的命令把相关目录完整拷回来mkdir -p /opt/cross/sysroot_aarch64 rsync -avz rootboard_ip:/usr/include /opt/cross/sysroot_aarch64/usr/ rsync -avz rootboard_ip:/lib /opt/cross/sysroot_aarch64/ rsync -avz rootboard_ip:/usr/lib /opt/cross/sysroot_aarch64/usr/拷完之后再重新配置工程缺头文件和缺 .so 的问题基本上少一半。另外有的库是软链接指向特定版本的rsync 默认会保留软链接但如果你用过普通的 cp -r就可能把 .so 复制成目标文件而不是完整的软链接链导致链接时版本识别出错这种问题很隐蔽好多人排查半天才发现是复制方式的问题。4.4 编译出来还是 x86 架构qmake 和 CMake 缓存导致的串味有时候你明明用了 aarch64 的交叉编译器最后 file 检查却发现产物是 x86 的 ELF。这种串味大多数发生在已有构建缓存的工程里。CMake 会把前一次构建的编译器信息保存在 CMakeCache.txt 中如果你直接在一个旧的 build 目录里重新执行 cmake ..它可能根本不理会你新传入的 CMAKE_TOOLCHAIN_FILE。我遇到过一次最隐蔽的情况Qt 的 qmake 已经按交叉编译生成但在 make 时却弹出 x86 的 g这是因为 qmake 的 qmake.conf 里编译器路径没改彻底Makefile 里硬编码了 cc 或 g。解决方法就是彻底清掉缓存目录重新解压一份干净源码或者用make distclean清理之后再配置。千万不要图省事在旧缓存上反复试越试越乱。4.5 常见问题速查表现象可能原因快速解法执行工具链报 No such file or directory缺 32 位运行库安装 libc6:i386 等 32 位库链接时 skipping incompatible库路径指到了宿主机设置 --sysroot 生效头文件找不到sysroot 里缺头文件rsync 从板子同步 /usr/include编译产物还是 x86CMake/qmake 缓存未清删掉 build 目录重新配置交叉编译 Qt 配置时少模块sysroot 里库不全把板子的 /lib 和 /usr/lib 完整拷贝板子上跑提示 illegal instruction工具链架构与板子 CPU 不匹配换正确架构的交叉工具链5. 实操心得与扩展思路5.1 先把板子当成服务器交叉编译没那么魔幻很多刚接触交叉编译的朋友最大的心理障碍是觉得它很玄。其实换个角度理解就通了你的 x86 电脑就是一台编译服务器板子只是一个运行目标。你在服务器上准备好所有依赖然后就能一直为板子生产可执行文件。这也意味着你在 x86 上能做的静态分析、内存调试、单元测试只要依赖允许大部分也能在交叉编译出来后拿到板子上做差别只是你得频繁把编译产物传到板子上。解决传文件麻烦的思路是配置 NFS 或者 SSH直接把编译输出目录挂载到板子上。一开始用 scp 拷没事但一旦项目工程变大频繁拷贝效率太低而且还容易搞混版本。我在实际项目里通常把 output 目录直接做成 NFS 共享板子上挂载后每次编译完直接运行这样迭代效率高非常多。5.2 交叉编译里的三个版本一致性踩的坑多了我总结出交叉编译的三个版本一致性只要有一条没对上后面就会一路埋雷架构一致性32 位 ARM 板子要用 arm-linux-gnueabihf64 位 ARM 板子要用 aarch64-linux-gnu。混用必炸。C 库一致性板子上的 glibc 版本要和交叉工具链配套的 glibc 版本一致或更低。如果工具链的 glibc 太新编译出的程序拷到旧库的板子上会报 GLIBC_2.XX not found。内核头文件一致性工具链使用的内核头文件版本最好不低于板子内核版本否则一些系统调用的定义会缺失。尤其第二条最容易坑人。很多人辛苦编译完 Qt、应用往板子上一放报 version GLIBC_2.33 not found那真叫一个欲哭无泪。这种问题不像编译错误那么直观网上搜半天也找不到标准答案。我建议你在准备 sysroot 的时候顺手看一眼板子的/lib/aarch64-linux-gnu/libc.so.6版本并把工具链的 sysroot 里对应的 glibc 新版本压缩站内的库文件保持一致或者干脆用板子原厂 SDK 自带的工具链基本能规避这个问题。5.3 后续可以怎么扩展如果这篇文章的内容你已经完全消化下一步建议往这几个方向试试看自己用 Buildroot 编译一套完整的交叉编译工具链和根文件系统彻底理解工具链内部是怎么生成、怎么匹配的。试试在 ARM 板子上跑容器配合交叉编译出来的镜像让部署更标准化。研究一下 NEON 指令优化ARM 的 NEON 是 SIMD 指令集很多 AI 算子、音视频处理性能瓶颈都可以靠它提升配合交叉编译时添加 -mfpuneon 相关的编译选项能明显提高运行效率。我个人这几天的体会是交叉编译这个主题看起来是工具链的配置问题实际上是对体系结构、操作系统、C 库、链接原理的综合考验。把这条链路打通一次之后再迁移到任何新的 ARM 板子都会从容很多。最后再分享一个小技巧不管你是用 Qt、ONNX Runtime 还是其他什么大型项目做交叉编译最好都建立一个标准的搭建日志文档把每一个版本的源码下载路径、依赖版本、sysroot 来源、configure 参数都清清楚楚记下来。别问我为什么知道要记——我那天随手把 Qt 配置脚本忘在临时目录里第二天才知道后悔。
返回列表