3. 环境搭建:JetPack SDK安装、交叉编译环境配置、Python/C++混合开发环境搭建

说实话,环境搭建这块,是很多初学者最容易卡住的地方。我见过太多人,代码写得挺溜,结果卡在装环境上,一卡就是好几天。咱们这节课,我就把我在几个量产项目里踩过的坑、总结出来的经验,一次性给你讲透。

咱们的目标很明确:让你的电脑能编译出在 Jetson 上跑的程序,并且 Python 和 C++ 能愉快地一起工作。

核心思路: 在 x86 的 Ubuntu 主机上,通过 JetPack SDK 获取 Jetson 的交叉编译工具链和库,然后配置好 CMake 和 Python 的虚拟环境,实现「一次编译,到处运行」。

3.1 JetPack SDK:你的「万能钥匙」

JetPack SDK 是什么?说白了,它就是 NVIDIA 官方提供的一个「大礼包」。里面包含了 Jetson 的 Linux 内核、驱动、CUDA、cuDNN、TensorRT 等等所有你需要的东西。

安装方式有两种,我推荐第二种:

  1. SDK Manager 图形化安装: 适合新手,点点鼠标就行。但说实话,我很少用,因为网络一不稳定就得重来,很烦。
  2. 命令行安装(我推荐): 可控性高,能看清楚每一步在干什么。出了问题也好排查。

我个人习惯用命令行。下面是我整理的一个标准流程:

# 1. 下载 JetPack SDK Manager
wget https://developer.download.nvidia.com/compute/jetson/jp/sdkmanager/jetson_sdk_manager_2.1.0_amd64.deb

# 2. 安装
sudo apt install ./jetson_sdk_manager_2.1.0_amd64.deb

# 3. 运行(注意:这里要加 --cli 参数进入命令行模式)
sdkmanager --cli

# 4. 登录你的 NVIDIA 开发者账号
login --user your_email@example.com

# 5. 选择目标平台和 JetPack 版本
# 比如:Jetson Orin NX 16GB, JetPack 6.0
# 这一步很关键,选错了后面全白搭
sdkmanager --product Jetson --target_os Linux --version 6.0 --target_jetson Orin_NX_16GB

# 6. 下载并安装(只下载主机端的 Host 组件)
sdkmanager --download --host
注意: 下载过程非常依赖网络。我曾经在客户现场,网络差到只有 200KB/s,硬是下了一整夜。建议你提前下载好离线包,或者找个网络好的时间点操作。

3.2 交叉编译环境:为什么不能直接在 Jetson 上编译?

你可能会问:「我直接在 Jetson 上写代码、编译不行吗?」

行,但很慢。Jetson 的 CPU 性能跟桌面级 CPU 比,差距还是挺大的。一个在 PC 上编译 1 分钟的项目,在 Jetson 上可能要 10 分钟。你想想看,每次改个代码都要等 10 分钟,这谁受得了?

所以,我们采用交叉编译:在强大的 PC 上生成 Jetson 能运行的二进制文件。

配置交叉编译工具链,核心就三步:

  1. 安装交叉编译器: 通常是 aarch64-linux-gnu-g++ 这个工具。
  2. 获取 Jetson 的 sysroot: 也就是 Jetson 根文件系统的拷贝,里面包含了所有库和头文件。
  3. 配置 CMake: 告诉 CMake 使用交叉编译器,并指定 sysroot 路径。

下面是一个标准的 CMake 交叉编译工具链文件:

# toolchain.cmake
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)

# 指定交叉编译器
set(CMAKE_C_COMPILER /usr/bin/aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER /usr/bin/aarch64-linux-gnu-g++)

# 指定 sysroot 路径
set(CMAKE_SYSROOT /home/user/jetson_sysroot)

# 告诉 CMake 不要测试编译器(因为目标平台不在本地)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
我的经验: sysroot 最好直接从 Jetson 上打包过来,别自己手动拼。用 rsync 同步整个根目录,干净又省事。命令大概是:rsync -avz --exclude='/proc' --exclude='/sys' user@jetson_ip:/ ./jetson_sysroot/

3.3 Python/C++ 混合开发:取长补短

在实际项目中,我们经常需要 Python 和 C++ 混合编程。为什么?

  • C++: 负责底层、高性能的计算,比如图像预处理、模型推理。跑得快,是硬道理。
  • Python: 负责上层逻辑、业务调度、快速原型验证。开发快,是王道。

我常用的方案是 pybind11。它能把 C++ 函数直接暴露给 Python 调用,就像调用普通 Python 函数一样简单。

搭建混合开发环境,我建议你这样做:

  1. 创建 Python 虚拟环境: 用 conda 或 venv 都行,隔离项目依赖,避免冲突。
  2. 安装 pybind11: pip install pybind11 或者从源码编译。
  3. 编写 C++ 模块: 用 PYBIND11_MODULE 宏把你的函数包装起来。
  4. 编译: 用 CMake 编译生成 .so 文件。
  5. 在 Python 中调用: import my_module,然后直接用。

来看一个最简单的例子:

// example.cpp
#include <pybind11/pybind11.h>

int add(int i, int j) {
    return i + j;
}

namespace py = pybind11;

PYBIND11_MODULE(example, m) {
    m.doc() = "pybind11 example plugin";
    m.def("add", &add, "A function that adds two numbers");
}
# CMakeLists.txt
cmake_minimum_required(VERSION 3.14)
project(example)

find_package(pybind11 REQUIRED)
pybind11_add_module(example example.cpp)

编译之后,在 Python 里就能这样用了:

import example
result = example.add(3, 4)
print(result)  # 输出 7
避坑指南: 我曾经在交叉编译 pybind11 模块时,忘记把编译好的 .so 文件放到 Jetson 的 Python 路径下,结果一直报 ImportError。记住,.so 文件必须放在 sys.path 能搜索到的目录里。

3.4 整体环境架构图

下面这张图,能帮你把整个环境搭建的逻辑串起来:

边缘端开发环境架构图 边缘端开发环境架构图 主机开发环境 (x86 Ubuntu) JetPack SDK 交叉编译器 Sysroot CMake pybind11 Python 虚拟环境 编译产物 (.so / 可执行文件) 目标设备 (Jetson Orin / Xavier) CUDA / cuDNN TensorRT OpenCV Python 运行时 C++ 运行时 应用层代码 部署运行 流程:主机编译 → 生成 .so → 拷贝到 Jetson → 运行

3.5 验证环境:跑一个「Hello World」

环境搭好了,怎么知道对不对?写个简单的程序验证一下。

C++ 验证:

// hello.cpp
#include <iostream>
int main() {
    std::cout << "Hello from Jetson!" << std::endl;
    return 0;
}

用交叉编译器编译:aarch64-linux-gnu-g++ hello.cpp -o hello。然后把 hello 文件传到 Jetson 上,运行。如果输出 "Hello from Jetson!",说明交叉编译环境没问题。

Python/C++ 混合验证:

就用上面那个 example.add 的例子。编译出 example.so,传到 Jetson 上,在 Python 里 import 并调用。如果返回 7,说明整个混合开发环境就通了。

一个小技巧: 验证环境时,别一上来就搞复杂的模型推理。先跑个最简单的加法函数,能通就说明整个链路是好的。这叫「最小可行性验证」,能帮你快速定位问题。

嗯,环境搭建这块,内容确实不少。但只要你按照我上面说的步骤,一步步来,别跳步,基本上半天就能搞定。搞定了这一步,后面的开发就顺风顺水了。