1. 先说结论:这个板子编译 FastDeploy,到底难在哪
RK3588 在国产 ARM 开发板里边算是资源很能打的一类:8 核 A76+A55 架构,带 Mali GPU 和独立 NPU,跑 AI 推理部署确实够看。但有个避不开的现实问题——你翻遍各大发行版仓库,都找不到别人帮你编译好的 FastDeploy 安装包。要么用编译好的通用 Linux x86_64 包,要么自己在板子上从头编。前者显然用不了,后者就得走一遍完整的源码编译流程。
这个坑我先帮大家踩了一遍,结论是:能编,但前提是你要接受它的脾气。编译过程不涉及多少代码修改,主要是依赖下载、内存控制、CMake 选项组合这些环节容易出问题。你要是直接用默认配置在板子上跑,大概率会被 Gcc 进程内存不够、第三方库下载超时、Python 绑定装不上这三件事气得怀疑人生。
这篇文章就是围绕这三件事展开的。整个过程适用于 RK3588 平台,也适用于其他 aarch64 的 ARM 开发板。如果你只是想在板子上快速验证 FastDeploy 能不能跑模型,不想被编译过程劝退,那这篇文章基本可以帮你少走一大半弯路。
提示:我自己是在一块 8GB 内存的 RK3588 板子上完成的编译,系统是 Ubuntu 22.04,Python 版本为系统默认的 3.10。不同的内存容量、系统版本会导致具体参数上的差异,但排雷思路是通用的。
1.1 RK3588 这个平台,编译 AI 推理库的特殊性
先说硬件背景。RK3588 的 CPU 是 4 个 A76 大核加 4 个 A55 小核,大核频率能跑到 2.2GHz 以上,这个性能编小型开源库没压力,但像 FastDeploy 这种依赖较多、还动不动就要拉一堆第三方库的大型项目,压力就全在内存带宽和可用 RAM上。
FastDeploy 编译时本质上是在做三件事:编译本体源码、编译或拉取多个推理后端(ONNX Runtime、OpenVINO、TensorRT 等)、编译周边视觉库和 OpenCV。本来这些依赖在 x86_64 环境都是官方预编译文件直接下载,但到 aarch64 平台上,很多预编译包没有对应版本,CMake 会退回到源码编译模式。源码编译多线程并行时,cc1plus 进程峰值内存占用可以轻松到 2GB 以上,开 8 线程就是 16GB 的量级。8GB 内存的板子,不开 swap 基本编不过去。
再一个特殊点是可选后端的问题。FastDeploy 官方对 NVIDIA Jetson 系列支持非常完善,有专门的一键编译脚本,但 RK3588 不在官方主推列表里。实际编译时你需要把它当成一个"裸 aarch64 Linux 环境"来处理,不碰 Jetson 专用选项,关闭不需要的 GPU/TensorRT 后端,把精力集中在 CPU 后端和原生 NPU 插件上。
1.2 FastDeploy 在 ARM 设备上的编译路线,选哪一种
FastDeploy 在 ARM 平台上有三条路,分别适合不同需求:
- 交叉编译(x86 主机编出 aarch64 产物):速度快,不占板子资源,但你要配交叉编译工具链、sysroot,如果涉及 Python 绑定还要额外处理 host Python 和 target Python 的差异。第一次踩坑率极高。
- 板载直接编译(源码在板子上本地编):不需要跨平台环境,CMake 自己检测系统,OpenCV、Python 头文件都走系统路径。缺点是耗时长、内存紧张,但成功率最高,绝大多数坑都是可预见的。
- Docker 容器内编译:适合讲究环境隔离的人,但 RK3588 上跑 Docker 再挂载编译目录,IO 开销会拖慢速度,且容器内的依赖还是要重新装,没有省掉核心步骤。
我最终选择的是板载直接编译。原因很简单:FastDeploy 的 CMake 脚本里大量使用find_package和系统环境探测逻辑,板载编译时这些探测结果天然正确,不用手动告诉 CMake"目标系统是 aarch64、Python 在哪个路径"这类信息。对新手来说,省掉交叉编译的配置成本,就是省掉最大的不确定因素。
但是,板载编译也有一个必然代价:你得在 RK3588 上消耗大量时间去编 C++ 模板和算子注册代码,这个过程没有任何捷径。以我实测试下来的数据,全量编译大概需要 40-60 分钟,具体取决于开的线程数和磁盘速度。
2. 准备阶段:硬件配置、环境依赖和几个前置检查
很多编译教程上来就让你敲 cmake..,结果编到一半直接 OOM,然后你说"RK3588 编不了 FastDeploy"。不是编不了,是准备工作没做够。这个阶段做得越好,后面越顺。
2.1 内存与 swap 配置:编译失败的第一大杀手
我先说最阴间的现象:**FastDeploy 编译时 Gcc 进程不是一下占满内存,而是随着编译单元逐个推进,内存占用曲线慢慢爬升。**你可能前 20 分钟风平浪静,第 21 分钟突然冒出c++: internal compiler error: Killed (program cc1plus),日志里没有其他任何错误。这种情况 99% 是物理内存耗尽被内核 OOM Killer 杀了。
解决办法是提前配置 swap。我给的参考配置是:内存 8GB 的板子,swap 至少给 8GB,最好给到 12GB。这样 Gcc 多线程并行时的峰值内存需求(约 10-14GB)就有地方缓冲。
配置 swap 的操作分两步。第一步是创建 swap 文件并格式化:
sudo fallocate -l 8G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile第二步是写入/etc/fstab,保证重启后自动挂载:
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab这里有几个坑要说清楚。第一,fallocate在部分文件系统上会创建带空洞的 swap 文件,swapon可能报 "swapon failed: Invalid argument",遇到这种情况不要硬试,直接改用dd if=/dev/zero of=/swapfile bs=1M count=8192的方式生成文件,一步到位。第二,swap 放在普通 MicroSD 卡上会很慢,编译时频繁换页,速度会明显下降。建议把 swap 文件放在 NVMe 固态盘或高速 eMMC 分区上,实测编译速度差异能到 30% 以上。第三,编译完成后 swap 文件不要急着删,后续跑模型、加载大模型权重时它照样能救急。
检查 swap 是否生效,用free -h,看到 Swap 一栏出现你配置的大小就对了。
2.2 系统依赖与工具链安装
FastDeploy 的编译依赖不算多,但每条都要装到位。我在 Ubuntu 22.04 上实测,下面这组依赖是完整的:
sudo apt update sudo apt install -y build-essential cmake git python3-dev \ libopencv-dev libssl-dev libgl1-mesa-dev libgtk2.0-dev \ pkg-config wget unzip tar逐一说下为什么需要它们:
cmake:FastDeploy 最低要求 3.14 以上。Ubuntu 22.04 自带的 cmake 是 3.22,够用。但要注意,如果你之前装过其他版本,编译时出现 CMake 缓存混乱,建议cmake --version确认后,把 build 目录清空重来。python3-dev:这是最容易漏装的。FastDeploy 编译 Python 绑定库时,需要通过 Python.h 头文件定位 Python 版本。如果不装,CMake 配置阶段不会立刻报错,但编译到pybind相关源文件时会直接fatal error: Python.h: No such file or directory。这类错误很容易误判成源码问题,实际就是缺一个 dev 包。libopencv-dev:系统自带 OpenCV 版本可能和 FastDeploy 期望的不一致,但 FastDeploy 的 CMake 逻辑是:找得到系统 OpenCV 就优先用系统的,找不到就自己编一个 OpenCV。自己编 OpenCV 在 ARM 板上要多花 15-20 分钟,所以建议提前装好系统版。libssl-dev:FastDeploy 在模型下载、第三方依赖获取环节会用到 HTTPS 链接,缺 OpenSSL 会导致部分下载源握手失败,而且报错信息藏在日志深处,排查起来特别费劲。
装完工具链后,确认版本一致性:
cmake --version gcc --version python3 --version还有一个很多人忽略的检查点:磁盘空间。FastDeploy 编译过程会产生大量中间文件和第三方源码目录,总量在 6-10GB 之间。如果你的根分区剩余空间低于 15GB,大概率编到一半磁盘满了,各种诡异报错都会冒出来。建议先df -h看一眼。
2.3 第三方库目录预检:哪些会被下载,哪些需要手动准备
FastDeploy 依赖的第三方库,一部分通过 CMake 脚本自动下载,一部分在编译时才检查。我列一个清单,你在编译前心里有数:
| 依赖库 | 获取方式 | 平台差异说明 |
|---|---|---|
| ONNX Runtime | 自动下载预编译包或源码编译 | aarch64 有 Linux 预编译包,但版本若和 FastDeploy 期望不匹配会退化为源码编译 |
| OpenCV | 优先系统库,若无则下载源码编译 | 系统库版本够用就没必要源码编 |
| prebuilt(各后端) | 自动下载 | x86_64 直接下载,aarch64 有时需要手动处理 |
| imgui 等视觉相关库 | 自动下载源码 | 体积小,不易踩坑 |
| 模型资源文件 | 运行时下载 | 编译期一般不涉及 |
我实际遇到的情况是:预览版prebuilt目录下的某些库只提供了 x86_64 版本,CMake 检测到架构不匹配后,会打印一行类似[FastDeploy] Prebuilt library not found for current arch, build from source的提示,然后开始源码编译。这是正常流程,不是出错。只要你网络能连上 GitHub,耐心等就行。
如果你编译时网络不稳定,最稳妥的方法是提前手动把这些依赖下载好放进缓存目录。具体目录路径一般在FastDeploy/build/third_libs,不同版本可能会变,建议编译前先find一下确认。这个方法我后文排雷部分会再详细说。
2.4 Python 绑定编译的前置确认
如果你最终目的是在 RK3588 上用 Python 调用 FastDeploy,这一节很重要。FastDeploy 的 Python 包有两个来源:一个是 pip 直接从官方源装,但官方没有针对 RK3588 的 aarch64 wheel 包,这个源可以直接划掉;另一个是源码编译生成。
源码编译 Python 绑定,核心机制是 CMake 的BUILD_FASTDEPLOY_PYTHON选项,底层通过 pybind11 把 C++ 接口封装成 Python 模块。这个过程中有个非常容易忽略的地方——FastDeploy 会检测 Python 的sysconfig信息来决定安装路径和 ABI 标志,如果系统里有多个 Python 版本(比如系统自带 3.10,你又装了 3.11),CMake 可能选错 Python 版本。
我的建议是:在开始编译前,确认好你到底用哪个 Python 环境。最好用系统默认的python3,不要用 conda 环境,因为 conda 的 Python 路径、库文件布局和 system Python 不同,FastDeploy 的 CMake 脚本对 conda 环境的兼容性没有那么好。实际工作中我见过有人非要用 conda 环境来编,结果造出libpython3.11.so链接错误,排查了大半天。如果你确定要用特殊 Python 环境,可以手动传入PYTHON_EXECUTABLE和PYTHON_INCLUDE_DIR强制指定,但不推荐新手这么干。
3. 编译实操:从源码到第一个库文件
准备工作做完,接下来就是真正的编译环节。这部分我按完整流程来写,每一步都带笔记,你照着走就行。
3.1 获取源码与常见编译选项解读
源码从官方仓库直接克隆。如果你那边访问 GitHub 较慢,可以走镜像源,这里不做推荐,按你自己网络实际情况选择效率最高的方式就好。
git clone https://github.com/PaddlePaddle/FastDeploy.git cd FastDeploy拿到源码后,先看目录结构。核心的 CMake 文件是根目录下的CMakeLists.txt,里面定义了所有编译选项。不要急着改源码,先把常用选项过一遍:
BUILD_EXAMPLES:编译官方示例程序。建议打开,因为编译成功后可以直接运行示例验证环境,省去自己写测试代码的时间。BUILD_TEXT:文字识别相关能力,如果只部署分类、检测模型,可以关掉以缩短编译时间。BUILD_VISION:视觉处理能力,涉及 OpenCV 相关代码。默认开启,不要关。BUILD_ON_JETSON:这个选项务必设为 OFF,我们用在 RK3588 上,不需要 Jetson 平台的优化和组件。WITH_TIMESTAMP:打开后日志里会显示时间戳,方便观察程序运行耗时,建议 ON。ENABLE_ORT_BACKEND:ONNX Runtime 后端,CPU 推理的核心,必须 ON。ENABLE_RKNPU2_BACKEND:瑞芯微 NPU 后端。如果只想先跑通 CPU 推理,可以先 OFF。想上 NPU 加速再单独配置,这部分我在后面单独讲。WITH_GPU:默认 OFF 即可,RK3588 用的是 Mali GPU,FastDeploy 不支持这个 GPU 的加速路径。
CMake 选项里还有几个类似ENABLE_PADDLE_BACKEND、ENABLE_OPENVINO_BACKEND之类的选项,在 aarch64 非 x86 平台上要么不支持、要么会自动跳过,不用管它们,保持默认即可。
3.2 一条完整的编译命令与执行节奏
我推荐的编译方式是在源码根目录下创建build目录,把编译产物隔离在源码之外,这样以后重新配置不需要清理仓库。
mkdir build && cd build cmake .. \ -DCMAKE_BUILD_TYPE=Release \ -DBUILD_ON_JETSON=OFF \ -DBUILD_EXAMPLES=ON \ -DBUILD_VISION=ON \ -DBUILD_TEXT=OFF \ -DWITH_TIMESTAMP=ON \ -DENABLE_ORT_BACKEND=ON \ -DENABLE_RKNPU2_BACKEND=OFF \ -DCUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda最后一行CUDA_TOOLKIT_ROOT_DIR是我故意留的空值,用来展示一个很常见的错误写法。**FastDeploy 的 CMake 脚本里有一些通用的后端检测逻辑,如果你不显式传入这个路径而系统里恰好有一个残留的 CUDA 目录,CMake 可能会去检测 CUDA 环境,然后在 aarch64 上找到一个不存在的文件导致配置报错。**正确做法是不要传这个参数,让它自动跳过。如果你之前配置过别的带 CUDA 的项目,环境变量CUDA_HOME或LD_LIBRARY_PATH可能会干扰检测,建议在编译前先unset CUDA_HOME。
cmake ..配置成功后,日志末尾会看到生成略信息,比如Build files have been written to: /home/user/FastDeploy/build。
接下来是真正耗时的编译步骤:
make -j$(nproc)nproc在 RK3588 上一般输出 8,也就是 8 线程并行。但我要泼一盆冷水:**8 线程并行编译 FastDeploy,8GB 内存的板子基本不够用。**我实测下来,4 线程编译耗时和 8 线程相差不大,但稳定性天差地别。原因是 FastDeploy 有几个编译单元特别吃内存,8 线程时峰值内存瞬间飙到 12GB 以上,即使有 swap 也会拖慢整体速度。建议保守一点,用 4 线程:
make -j4编译开始后,你会看到大量的.cpp文件在编译。前 10 分钟主要是各类第三方依赖,之后进入 FastDeploy 本体代码。如果你配置了BUILD_EXAMPLES=ON,最后会看到示例程序的二进制文件开始链接。
这时系统负载会很高,属正常现象。你可以用htop单独开一个窗口查看编译进程状态,如果某个 cc1plus 进程内存涨到 3GB 以上,而系统已经开始吞 swap,说明线程开多了,后续编译会慢,但一般不会失败。
整个全量编译大概 40-60 分钟,具体时长取决于你的存储介质速度和内存大小。编译完成后,build目录下会生成大量.so文件和可执行文件,核心产物是libfastdeploy.so,位于build/Release/目录下。
3.3 Python绑定安装:fastdeploy 这个 Python 包是怎么来的
C++ 库编译完成后,如果你没开 Python 绑定选项,Python 侧并不会有fastdeploy包。此时有两种选择:一种是重新回到 CMake 配置页面,加上-DBUILD_FASTDEPLOY_PYTHON=ON,再次编译 Python 模块;另一种是使用官方提供的脚本。我建议直接在 CMake 重新配置,这样一气呵成:
cmake .. -DBUILD_FASTDEPLOY_PYTHON=ON make -j4这次编译量比第一次小很多,耗时大约 10-15 分钟。编译完成后,在build目录下你会找到fastdeploy的 Python 模块文件,路径通常形如build/python/dist/下有fastdeploy-*.whl,或者直接在python目录下生成了可导入的模块。
安装方式很简单:
cd build/python pip install dist/fastdeploy-*.whl装完后进入 Python 验证是否可用:
import fastdeploy print(fastdeploy.__version__)如果这行代码能正常输出版本号,说明核心链接和 Python 绑定都成功了。如果报No module named fastdeploy,大概率是.whl安装到了另一个 Python 环境中。用which python和which pip确认当前环境就是编译时指定的那个 Python。
还有一点需要注意,FastDeploy 的 Python 包在启动时会加载libfastdeploy.so,如果你后续把build目录删了或者移动了位置,Python 包会因为找不到这个.so而报 ImportError。所以编译产物别急着清理,或者你把它安装到系统库目录后,再清理也不迟。
4. 排雷记录:我撞上的几个坑和解决方法
这一部分把我实际踩过的坑按"症状—原因—解法"的结构写出来,每一条都是血泪教训,强烈建议收藏。
4.1 坑一:cc1plus 被 OOM Killer 强杀
现象:编译到一半,屏幕上出现c++: internal compiler error: Killed (program cc1plus),前后都是正常的编译日志,看起来像是编译器自身崩溃。
原因:物理内存耗尽。FastDeploy 编译时模板展开强度很高,单个编译单元的最大内存占用能超过 1.5GB。8 线程并行时,如果有 6 个编译单元同时到达峰值,8GB 内存瞬间被打满。内核的 OOM Killer 会挑选内存占用最高的进程杀掉,cc1plus 首当其冲。报错信息里不会出现 OOM 字样,所以非常迷惑人。
解决方法就是我第 2 部分说的:配足 swap,并且限制线程数。我实测最稳的组合是-j4 + 8GB swap + 8GB RAM。如果条件允许,内存 16GB 以上的板子可以直接-j8,速度快很多。
还有一个辅助技巧:在make命令前临时降低内存压力,比如关闭一些桌面程序、释放缓存:
echo 3 | sudo tee /proc/sys/vm/drop_caches这个操作会把文件缓存释放掉一部分,给编译进程腾出内存。但注意,释放 cache 后后续编译文件的读取速度会暂时变慢,属于权衡之选。
4.2 坑二:第三方依赖下载失败或卡住不动
现象:CMake 配置阶段提示 Fetching 或 Downloading,然后长时间卡在 0%,或者直接报unable to access、Timeout was reached之类的网络错误。
原因:FastDeploy 的 CMake 脚本会从多个外网源拉取预编译库和源码,国内直连某些源速度极不稳定。ARM 平台因为预编译包少,源码编译频率更高,下载链路更长,出问题的概率也更大。
解决方法有两个,按优先级排序:
方法一,手动下载并置入缓存目录。先用浏览器或其他工具把依赖包下载下来,放到 CMake 能找到的位置。具体做法是,在编译时注意观察日志中的下载链接和保存路径,一旦发现卡住的库,记下链接,用wget或curl手动下载后放在目标目录。
方法二,检查网络环境后重试。如果是临时抖动,单纯重跑cmake ..有时候就能续上。但 CMake 的FetchContent模块有时在下载失败后会在 build 目录留下残留文件,重跑时反而跳过下载直接使用不完整的文件,导致后续编译报错。遇到这种情况,直接清空build目录重来更省心。
我个人的习惯是:编译前先准备一个"离线依赖包"目录,把third_libs下最核心的几个库全部手动下载好,再让 CMake 走本地路径。虽然前期多花半小时,但整个过程心里有底。
4.3 坑三:Python.h: No such file or directory
现象:编译 Python 绑定时报错,错误指向 pybind 相关源码,提示找不到 Python.h。
原因:只装了python3,没装python3-dev。编译期需要 Python 的开发头文件和链接库,这些在 dev 包中,而非运行时的默认安装包中。
解决方法:
sudo apt install python3-dev装好后重新配置 CMake,让它重新检测 Python 路径:
rm -rf build mkdir build && cd build cmake .. -DBUILD_FASTDEPLOY_PYTHON=ON这里值得一提的是,有些 ARM 系统里的 Python 版本较新(比如 3.11),但 FastDeploy 的 pybind11 版本可能不兼容。如果出现PYBIND11_INTERNALS_VERSION相关的报错,说明 pybind11 版本偏旧,要更新 FastDeploy 源码里的第三方 pybind11。不过我实测 Ubuntu 22.04 + Python 3.10 的组合没有这个问题。
4.4 坑四:编译成功但 import 时报 undefined symbol
现象:编译全部完成,pip install也成功,但import fastdeploy时抛出类似undefined symbol: _ZN...的错误。
原因:动态链接库版本不一致,最常见的是 OpenCV 版本冲突。系统里同时存在多个 OpenCV 版本(比如自己源码编了一个 4.x,系统 apt 装了一个 4.5),FastDeploy 编译时链接了版本 A,Python 导入时运行时加载了版本 B,符号表对不上就崩。
解决方法是统一 OpenCV 版本。最省事的做法是:卸载所有源码安装的 OpenCV,只保留系统 apt 版本。检查方式:
ldconfig -p | grep opencv如果看到多个路径的 libopencv_*.so,就要小心了。建议在编译 FastDeploy 前先确认pkg-config --modversion opencv4,确保只存在一个版本。
另一个导致 undefined symbol 的常见原因是libfastdeploy.so的 rpath 设置。FastDeploy 编译时默认把第三方库的相对路径写进了 rpath,如果你移动了build目录,这些相对路径就失效了。解决办法是设置环境变量显式指明库路径:
export LD_LIBRARY_PATH=/path/to/FastDeploy/build/Release:$LD_LIBRARY_PATH4.5 坑五:RKNN NPU 后端的配置困惑
现象:部分教程提到在 RK3588 上使用 FastDeploy 的 RKNN 后端时,需要单独编译 RKNPU2 相关组件,并且要设置板子上 NPU 驱动。如果直接在网络上下载一个librknnmrt.so放进系统,运行时会报版本不匹配。
原因:RK3588 的 NPU 驱动和运行时库分属多个版本,FastDeploy 官方对 RKNN 后的支持不如 ONNX Runtime 后端成熟。而且 RKNPU2 的后端编译需要额外的第三方库路径,不能直接靠一个 CMake 开关搞定。
如果你只是先把流程跑通,我建议第一次编译时把ENABLE_RKNPU2_BACKEND设为 OFF,先走 CPU 推理。等 FastDeploy 在板子上运行验证成功,再回来研究 NPU 加速。这样把"编译问题"和"NPU 适配问题"分开排查,效率高得多。
如果你确实想要尝试 RKNN 后端,我的经验是:先确认板子的 NPU 驱动版本,再去找和驱动版本匹配的librknnrt.so,并把RKNN_TOOLCHAIN_DIR或类似选项指定到正确路径下进行编译。不同版本之间如果出现奇怪的算子错误,优先怀疑运行时库和编译器版本不匹配,而不是 FastDeploy 源码本身有 bug。
5. 常见问题与快速排查手册
下面这张表是我把编译过程中可能遇到的问题汇总成的速查表,建议保存下来备用。
| 问题现象 | 根本原因 | 首要排查动作 |
|---|---|---|
Killed (program cc1plus) | 内存不足触发 OOM | 检查 free -h,补 swap,降线程数 |
| CMake 下载第三方库卡住 | 网络问题 | 手动下载依赖置入缓存目录 |
Python.h找不到 | 缺 python3-dev | apt 安装 python3-dev |
| import 报 undefined symbol | OpenCV 版本冲突或 rpath 失效 | 统一 OpenCV 版本,设置 LD_LIBRARY_PATH |
| CMake 配置时报 CUDA 错误 | 环境中 CUDA 残留干扰 | unset CUDA_HOME,不传 CUDA 参数 |
| 编译成功但示例程序找不到模型 | 示例代码默认从远端下载模型 | 手动下载模型放到对应目录 |
| make 时端口被杀进程复现 | 并发过高 | 改用 make -j2 或 -j4 重试 |
| Python 包安装后无法导入 | 编译时的 Python 与安装时不一致 | 用which python检查,统一环境 |
| disk 空间不足导致编译报错 | 日志文件与中间文件占满磁盘 | 清理磁盘或迁移 build 目录到更大分区 |
这个表没有覆盖到所有场景,但如果你能把表里对应问题的排查动作走一遍,编译过程的大部分坑就能绕开。
还有一些通用技巧。比如,编译 FastDeploy 时尽量用一个tmux或screen会话,因为编译耗时长,如果网络中断导致 SSH 断开,编译进程会收到 SIGHUP 被杀掉。我之前有一次编到 50 分钟,因为终端窗口关闭导致前功尽弃,重新编了第二遍。用tmux可以规避这类问题:
tmux new -s build # 在会话中执行编译 # 如果断开,重新 tmux attach -t build 恢复再比如,保存编译日志以便排查。执行 make 时把完整日志输出到文件:
make -j4 2>&1 | tee build.log错误信息往往在日志中间位置,如果直接看终端很容易刷屏漏掉,日志文件可以随时搜索关键字,比如error、fatal、undefined reference。
6. 关于交叉编译的补充说明
很多人会问:为什么不直接在一台 x86 服务器上交叉编译,省得在板子上干等几十分钟?这个问题我研究过,也实际试过,结论是:可以,但性价比不一定高。
交叉编译 FastDeploy 的关键难点在于,项目依赖的第三方库太多,而且很多库在交叉编译工具链下也得重新编译,你等于要先给依赖库做一遍 aarch64 版本的完整编译。这还没算上 sysroot 配置、工具链版本匹配、Python 绑定目标路径等额外工作。全部折腾下来,前期准备时间很可能超过板载编译的几十分钟。
那什么情况下建议交叉编译?一种是你有多台 RK3588 板子要批量部署,希望在主机上一次性编好镜像下发;另一种是板子存储空间确实紧张,装不下 10GB 的中间文件。这两种场景适合投入交叉编译的准备工作,否则就老老实实板载编译。
如果交叉编译,CMake 需要通过工具链文件指定架构。我提供一个最小工具链配置作为参考:
set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR aarch64) set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc) set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++) set(CMAKE_FIND_ROOT_PATH /path/to/sysroot) 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_FIND_ROOT_PATH_MODE那三行,它决定了 CMake 从哪里找库和头文件。如果配错,交叉编译会抓取到主机上的 x86 库导致链接失败,错误信息很隐蔽,难以排查。
但再次强调,如果你只是想正常使用 FastDeploy,板载编译完全够用。
7. 一点个人体会
RK3588 上编译 FastDeploy 这件事,说难不难,说简单也绝对不简单。它和编译一个普通 C++ 项目的最大区别在于:FastDeploy 的构建系统自动处理了很多依赖,但这套自动化在 aarch64 平台上的容错性不如 x86_64。说白了,这是一个需要"陪跑"的编译任务——你没法全程撒手不管,但也不需要深入源码改逻辑。
如果让我重新做一遍,我的顺序会是:先配好 swap 和依赖,看一遍 CMake 选项确认后端选型,用-j4慢慢编译,编完先跑官方示例,再考虑 Python 绑定和 NPU 加速。每一步都不要跳过验证环节,因为 FastDeploy 的编译链比较长,一个环节的隐性错误往往到很后面才爆炸。
最后分享一个小技巧。FastDeploy 编译完成后,建议不要直接删掉build目录,至少保留到你把所有 demo 和 Python 绑定都验证完毕。因为编译产物里的.so文件可能被 Python 包依赖,而且后续想重新加一个后端(比如从 CPU-only 切到 RKNPU),在已有 build 目录上加cmake配置再make,只编译新模块,比全量重编快得多。等你确认所有功能都正常了,再考虑清理。我在实际中因为这个保留 build 目录的习惯,省掉过两次全量重编的时间,这个经验值得你参考。