第2章:环境搭建——交叉编译工具链安装、CMake 配置、Python 与 TFLite 解释器源码获取

好,咱们正式开始动手了。

上一章我们聊了TFLite的整体架构,说白了就是让你心里有个谱。这一章,咱们得把“家伙事儿”都备齐。环境搭建这事儿,我见过太多人卡在这里。不是工具链版本不对,就是CMake找不到编译器。嗯,别急,咱们一步步来。

2.1 交叉编译工具链:选对版本,少走弯路

嵌入式平台嘛,你肯定不是在x86的电脑上直接跑模型。你得在PC上编译,然后把二进制丢到ARM板子上跑。这就叫交叉编译。

我个人习惯用gcc-arm-none-eabi或者aarch64-linux-gnu-gcc,具体看你目标平台是ARM Cortex-M还是Cortex-A。举个例子,如果你用的是树莓派或者瑞芯微的RK3588,那就是aarch64。

注意: 千万别用Ubuntu源里自带的太老版本。我曾经因为用了apt install默认的4.9版本,结果编译出来的TFLite解释器在板子上段错误,查了两天才发现是工具链对浮点ABI的支持有问题。

安装命令很简单,但版本要选对:

# 以aarch64为例,我推荐用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 -xf gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz
sudo mv gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu /opt/
export PATH=$PATH:/opt/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin

验证一下:

aarch64-linux-gnu-gcc --version
# 输出类似:aarch64-linux-gnu-gcc (Linaro GCC 7.5-2019.12) 7.5.0

你想想看,如果这里版本号不对,后面所有编译都会白费力气。所以,装完一定要跑一下这个命令。

2.2 CMake 配置:别让构建系统卡住你

TFLite的构建用的是CMake。说实话,CMake本身不难,难的是写对交叉编译的toolchain文件。

我习惯在项目根目录下建一个toolchain.cmake,内容大致如下:

# 设置目标系统
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)

# 指定编译器
set(CMAKE_C_COMPILER /opt/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER /opt/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-g++)

# 查找根文件系统(如果你有板子的sysroot)
set(CMAKE_FIND_ROOT_PATH /path/to/your/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)
小技巧: 如果你没有完整的sysroot,可以先用CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH,让CMake先在本地找库。但最终部署时,一定要确保板子上有对应的动态库。

然后编译TFLite的时候,这样调用:

mkdir build && cd build
cmake .. \
  -DCMAKE_TOOLCHAIN_FILE=../toolchain.cmake \
  -DTFLITE_ENABLE_XNNPACK=OFF \
  -DTFLITE_ENABLE_GPU=OFF
make -j4

这里我把XNNPACK和GPU都关了。为什么?因为嵌入式平台往往没有GPU加速,或者XNNPACK的优化反而会引入额外的依赖。我踩过这个坑——开了XNNPACK,结果链接时缺了一堆符号,折腾半天。

2.3 获取 Python 与 TFLite 解释器源码

好,工具链和CMake搞定了,接下来就是拿源码。

Python方面,我建议直接用pip安装tflite-runtime,而不是完整的tensorflow包。完整包太大了,嵌入式开发不需要那些训练相关的库。

# 在PC上安装(用于原型验证)
pip install tflite-runtime

# 如果你要在ARM板子上跑Python,记得交叉编译或者用板子自带的Python环境
# 我个人习惯先在PC上用Python跑通模型,再交叉编译C++版本

至于TFLite解释器的C++源码,直接从GitHub拉取:

git clone https://github.com/tensorflow/tensorflow.git
cd tensorflow
# 我建议切到一个稳定版本,比如v2.12.0
git checkout v2.12.0

源码拉下来之后,你关心的核心目录是:

  • tensorflow/lite/ —— 解释器核心代码
  • tensorflow/lite/c/ —— C API,嵌入式移植主要用这个
  • tensorflow/lite/micro/ —— TFLite Micro,如果你跑在MCU上

这里有个细节:如果你只需要解释器,不需要训练功能,可以只保留tensorflow/lite目录,其他删掉。我做过一个项目,把整个tensorflow repo拖下来,结果编译时间长达40分钟。后来只保留lite目录,编译时间缩短到5分钟。

2.4 验证环境:跑一个最小示例

环境搭没搭好,跑个例子就知道了。我习惯写一个最简单的C程序来验证:

#include "tensorflow/lite/c/c_api.h"
#include <stdio.h>

int main() {
  TfLiteModel* model = TfLiteModelCreateFromFile("model.tflite");
  if (model == NULL) {
    printf("Failed to load model\n");
    return -1;
  }
  printf("Model loaded successfully!\n");
  TfLiteModelDelete(model);
  return 0;
}

编译命令:

aarch64-linux-gnu-gcc test.c -I./tensorflow -L./build -ltensorflowlite_c -o test_tflite

如果编译通过,没有报错,恭喜你,环境搭建成功了。

核心要点回顾:
  • 交叉编译工具链版本要匹配目标平台,别用太老的
  • CMake的toolchain文件是灵魂,写错一个路径就全白费
  • 源码只取lite目录,别全量下载
  • 先跑通最小示例,再搞复杂功能

嗯,环境搭建这部分就到这里。下一章我们开始真正动手,把TFLite解释器编译成静态库,然后集成到你的嵌入式项目中。到时候你会发现,今天这一步虽然繁琐,但绝对是值得的。