1. Jetson nano 编译 librealsense 时 Vulkan 找不到,到底卡在哪
如果你在 Jetson nano 上编译 librealsense,CMake 阶段突然抛出Could NOT find Vulkan (missing: VULKAN_LIBRARY VULKAN_INCLUDE_DIR),紧接着又看到The Xinerama headers were not found,那你不是一个人。这个报错组合在 JetPack 4.5 / L4T 32.5.0 的 Nano 上非常典型,尤其是你明明用同一张镜像刷过另一台机器、那台却编译通过的时候,会让人怀疑人生。
先把结论说清楚:Vulkan 这条Could NOT find在 librealsense 2.40.0 这个版本里,很多时候只是 CMake 的一个探测提示,真正让Configuring incomplete失败的是后面 GLFW 的 Xinerama 头文件缺失。也就是说,Vulkan 报错是“烟雾弹”,Xinerama 才是“真凶”。但两者经常一起出现,所以本文会把 Vulkan 的识别逻辑、依赖补齐、CMake 参数、重新验证的完整链路都走一遍,让你下次遇到同类 CMake 找不到库的问题能自己定位。
这篇适合谁:手上有一台 Jetson nano(JetPack 4.x),想编译 librealsense 做深度相机开发,或者正在被 CMake 的missing: XXX_LIBRARY XXX_INCLUDE_DIR折磨的嵌入式同学。下面所有命令都可以直接复制,我会标出每一步的预期输出,方便你对照。
2. 先确认环境与依赖,再谈 Vulkan 配置
动手之前,先让环境信息可复现。Jetson nano 的 JetPack 版本、CUDA、Vulkan 运行时版本都会影响 CMake 的探测结果。用jetson_release -v看一眼,重点确认三件事:L4T 版本、Vulkan 版本、Python 版本。
jetson_release -v在 JetPack 4.5 上你大概率会看到类似输出:L4T 32.5.0、CUDA 10.2.89、Vulkan 1.2.70、Python 3.6.9。注意这里Vulkan: 1.2.70说明系统里其实是有 Vulkan 运行时的,但 CMake 依然报找不到VULKAN_LIBRARY和VULKAN_INCLUDE_DIR,原因通常是缺开发包(头文件 + 链接库),而不是缺运行时。
补齐依赖分两层。第一层是 Vulkan 开发相关,第二层是 GLFW 窗口创建需要的 X11 扩展头文件。很多人只装了第一层,结果 Vulkan 找到了,却倒在 Xinerama 上。
sudo apt-get update sudo apt-get install -y libvulkan-dev vulkan-utils sudo apt-get install -y libxinerama-dev libxcursor-dev libxi-dev libxrandr-devlibvulkan-dev提供vulkan/vulkan.h和libvulkan.so,正好对应 CMake 要找的VULKAN_INCLUDE_DIR与VULKAN_LIBRARY。libxinerama-dev、libxcursor-dev则是 GLFW 在 X11 下编译的硬依赖。装完之后可以用下面两条命令快速确认文件确实到位:
ls /usr/include/vulkan/vulkan.h ls /usr/lib/aarch64-linux-gnu/libvulkan.so两条都能列出文件,说明 Vulkan 开发环境已经具备被 CMake 识别的条件。如果第一条报 No such file,说明libvulkan-dev没装上,回到上一步重装即可。
注意:Jetson nano 的 apt 源偶尔会慢,如果
apt-get update卡住,先确认网络正常再重试,不要中途 Ctrl+C 留下半装的包。
3. 可复制的 CMake 配置与编译命令
依赖齐了之后,进入 librealsense 源码目录,建一个干净的 build 目录。这里强调“干净”是因为 CMake 会缓存上一次的探测结果,如果之前失败过,缓存里可能还留着VULKAN_LIBRARY-NOTFOUND,直接重跑会继续报错。
cd ~/RealSense/librealsense-2.40.0 rm -rf build mkdir build && cd build然后是核心的 cmake 命令。针对 Jetson nano 的 USB 相机场景,通常要开FORCE_RSUSB_BACKEND,并带上 Python 绑定:
cmake ../ \ -DFORCE_RSUSB_BACKEND=ON \ -DBUILD_PYTHON_BINDINGS:bool=true \ -DPYTHON_EXECUTABLE=/usr/bin/python3 \ -DCMAKE_BUILD_TYPE=Release如果你希望显式告诉 CMake Vulkan 的位置,避免它自己猜,可以再加两个变量。这在多版本 Vulkan 共存或路径非标准时特别有用:
cmake ../ \ -DFORCE_RSUSB_BACKEND=ON \ -DBUILD_PYTHON_BINDINGS:bool=true \ -DPYTHON_EXECUTABLE=/usr/bin/python3 \ -DVULKAN_INCLUDE_DIR=/usr/include \ -DVULKAN_LIBRARY=/usr/lib/aarch64-linux-gnu/libvulkan.so \ -DCMAKE_BUILD_TYPE=Release参数含义对照如下,方便你按需裁剪:
| 参数 | 作用 | 建议值 |
|---|---|---|
| FORCE_RSUSB_BACKEND | 强制走 USB 后端,绕过内核补丁 | ON |
| BUILD_PYTHON_BINDINGS | 生成 pyrealsense2 | true |
| PYTHON_EXECUTABLE | 指定 Python 解释器 | /usr/bin/python3 |
| VULKAN_INCLUDE_DIR | Vulkan 头文件目录 | /usr/include |
| VULKAN_LIBRARY | Vulkan 链接库路径 | /usr/lib/aarch64-linux-gnu/libvulkan.so |
| CMAKE_BUILD_TYPE | 编译优化级别 | Release |
配置成功后,你会看到-- Configuring done和-- Generating done,最后一行是Build files have been written to。这时候 Vulkan 那行可能仍然显示Could NOT find Vulkan,但只要没有CMake Error且配置完成,就可以继续编译。因为 librealsense 对 Vulkan 是可选依赖,找不到时会自动降级,不影响核心功能。
接着编译。Jetson nano 内存只有 4GB,直接make -j4容易 OOM,建议用-j2甚至-j1:
make -j2 sudo make install sudo ldconfig编译过程大概几十分钟到一小时,取决于 SD 卡速度。如果中途出现virtual memory exhausted或进程被 kill,就是内存不够,降到-j1重来。
4. 验证 Vulkan 是否被识别,以及 pyrealsense2 是否可用
配置完成后,先回头确认 Vulkan 到底有没有被 CMake 认到。最直接的办法是翻 CMake 的输出日志,或者用cmake --system-information过滤:
cmake --system-information | grep -i vulkan如果输出里出现VULKAN_LIBRARY:FILEPATH=/usr/lib/aarch64-linux-gnu/libvulkan.so和VULKAN_INCLUDE_DIR:PATH=/usr/include,说明 Vulkan 已经被正确识别。如果还是NOTFOUND,说明前面的libvulkan-dev没装好,或者你用的 cmake 命令没带上显式路径。
再验证 Vulkan 运行时本身是否正常:
vulkaninfo | head -n 20能打印出 GPU 名称、API 版本等信息,就说明 Vulkan 运行时没问题。这一步和 CMake 识别是两回事:运行时在,不代表开发头文件在,反之亦然。
最后验证 librealsense 的 Python 绑定。这是判断编译是否真正成功的硬指标:
python3 -c "import pyrealsense2 as rs; print(rs.__version__); print(len(dir(rs)))"正常会打印版本号(如 2.40.0)和一个较大的数字(可用符号数量)。你也可以进交互式环境看一眼:
python3 >>> import pyrealsense2 as rs >>> dir(rs)[:10]能列出align、config、pipeline这些名字,就说明 pyrealsense2 已经装好,可以接相机跑深度流了。如果 import 报ModuleNotFoundError,多半是make install没执行或ldconfig没跑,补一下即可。
5. 本篇常见报错排查清单
把这次踩到的坑整理成一张排查表,下次遇到同类 CMake 报错可以按顺序过一遍。
| 报错信息 | 根因 | 处理 |
|---|---|---|
| Could NOT find Vulkan (missing: VULKAN_LIBRARY VULKAN_INCLUDE_DIR) | 缺 libvulkan-dev 开发包 | apt 安装 libvulkan-dev |
| The Xinerama headers were not found | 缺 libxinerama-dev | apt 安装 libxinerama-dev libxcursor-dev |
| Configuring incomplete, errors occurred | 上面任一依赖缺失 | 补齐依赖后删 build 重跑 |
| virtual memory exhausted | Nano 内存不足 | make -j1 降并发 |
| ModuleNotFoundError: pyrealsense2 | 未 install 或未 ldconfig | sudo make install && sudo ldconfig |
| 重新 cmake 仍报 NOTFOUND | CMake 缓存了旧结果 | rm -rf build 后重建 |
几个容易忽略的点单独说。第一,CMake 缓存非常顽固,改完依赖一定要删 build 目录,否则它读的还是旧的CMakeCache.txt。第二,FORCE_RSUSB_BACKEND=ON和OFF会影响后端选择,Nano 上建议保持 ON,避免折腾内核补丁。第三,编译时如果 CMake 提示要联网下载第三方库,网络不稳会卡很久,可以提前把依赖装全,减少在线拉取。
提示:如果你在配置阶段看到
Could NOT find apriltag,这属于可选依赖缺失,不影响主流程,可以忽略。
6. 编译通过之后,把调试效率也提上来
librealsense 编译通过只是第一步,后面你大概率要反复跑 Python 脚本调深度流、对齐、点云,还要查 API 用法、对比不同版本的参数。这时候如果每次都在 Nano 本地翻文档、试参数,效率会很低。我自己的做法是把模型对话和接入文档放在手边,遇到rs.config()参数不确定、或者 pipeline 启动报错时,直接查证再改代码,比盲试快很多。
需要查 librealsense 的 API 用法、CMake 参数含义,或者想快速验证一段 pyrealsense2 代码逻辑,可以用模型对话:https://taotoken.net/api?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite 配合接入文档 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite 一起看,前者帮你解释报错和参数,后者给你可复制的接入示例。如果你后面要长期在 Nano 上做视觉编码、写 Agent 脚本,可以考虑 Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite 把常用调试流程固化下来。API Key 在控制台生成:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite 生成后填到你的脚本或工具里即可。
回到编译本身,最后再给一个收尾动作:把这次成功的 cmake 命令写进一个build.sh,下次换机器或重刷系统直接跑,省得再回忆参数。脚本里记得带上rm -rf build,避免缓存问题重演。