第二章:开发环境搭建
好,咱们正式开始动手。这一章,说白了就是“把家伙事儿备齐”。
很多朋友一上来就急着写代码、调模型,结果编译报错一堆,最后发现是工具链没装对。我早期做嵌入式项目时,就吃过这个亏——交叉编译出来的程序,在目标板上跑不起来,查了三天,结果是链接库版本不匹配。嗯,从那以后,我养成了一个习惯:先把环境搭得干干净净,再动代码。
2.1 交叉编译工具链安装
什么是交叉编译?简单说,就是在你的PC上(x86架构)编译出能在ARM架构上跑的程序。你想想看,树莓派、Jetson Nano这些目标板,性能有限,直接在它们上面编译大项目(比如GGUF推理引擎)会慢到怀疑人生。所以我们在PC上编译,生成目标板的可执行文件。
我个人习惯用Linaro GCC或者ARM官方工具链。以树莓派4B(ARMv8 64位)为例:
# 下载ARM64交叉编译工具链
wget https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu.tar.xz
# 解压到指定目录
tar -xf gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu.tar.xz -C /opt/
# 配置环境变量(建议写入~/.bashrc)
export PATH=/opt/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin:$PATH
export CC=aarch64-none-linux-gnu-gcc
export CXX=aarch64-none-linux-gnu-g++
小提示: 如果你用的是Jetson Nano(也是ARM64),这套工具链完全通用。我曾在项目中同时维护树莓派和Jetson Nano两个目标,共用一套交叉编译链,省了不少事。
2.2 CMake与依赖库配置
CMake是C++项目的标配。GGUF推理引擎依赖不少底层库,比如ggml、BLAS(加速矩阵运算)、OpenMP(多线程)。
我个人习惯写一个交叉编译工具链文件(toolchain.cmake),这样CMake就知道该用哪个编译器、找哪些库。举个例子:
# toolchain.cmake
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(CMAKE_C_COMPILER aarch64-none-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER aarch64-none-linux-gnu-g++)
set(CMAKE_FIND_ROOT_PATH /opt/arm64-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)
然后编译时这样调用:
mkdir build && cd build
cmake .. -DCMAKE_TOOLCHAIN_FILE=../toolchain.cmake \
-DGGML_BLAS=ON \
-DGGML_BLAS_VENDOR=OpenBLAS
make -j4
注意: 我曾经在配置OpenBLAS时踩过坑——PC上装的OpenBLAS是x86版本,交叉编译时必须用ARM64版本的OpenBLAS。否则链接时会报“找不到库”的错误。解决办法是:在目标板上先编译一份OpenBLAS,然后把头文件和库文件拷贝到PC的sysroot目录下。
2.3 目标板系统准备
目标板(树莓派或Jetson Nano)需要提前装好系统。我个人推荐:
- 树莓派4B: 使用Raspberry Pi OS(64位版),或者Ubuntu Server 22.04 LTS(ARM64)。
- Jetson Nano: 使用NVIDIA官方JetPack SDK,它包含了CUDA、cuDNN、TensorRT等加速库。
系统装好后,有几个关键步骤:
- 开启SSH: 方便远程调试。树莓派在
raspi-config里开启,Jetson Nano默认开启。 - 安装基础依赖:
# 在目标板上执行
sudo apt update
sudo apt install build-essential cmake git libomp-dev libblas-dev
- 确认架构:
uname -m
# 输出应为 aarch64
核心逻辑: 整个开发环境搭建,其实就是“PC端交叉编译 + 目标板端运行验证”的闭环。你想想看,如果PC和目标板的环境不一致(比如库版本不同),那编译出来的程序大概率跑不起来。所以,保持两边环境同步是关键。
2.4 知识体系结构图
下面这张图,帮你理清本章的核心脉络:
2.5 避坑指南
最后,分享几个我亲身踩过的坑:
- 库版本不一致: 我曾经在PC上用OpenBLAS 0.3.20编译,目标板上装的是0.3.18,结果运行时崩溃。后来我养成了习惯:在目标板上编译一份依赖库,然后拷贝到PC的sysroot里。
- 文件传输权限: scp传文件后,别忘了
chmod +x。我有一回忘了加执行权限,在目标板上折腾了半天,以为是编译问题。 - CMake缓存: 如果切换了工具链或库路径,记得删除
build/CMakeCache.txt,否则CMake会沿用旧的配置。
嗯,环境搭建就这些。别嫌麻烦,这一步做好了,后面会顺很多。