树莓派4B-ROS2-Humble交叉编译sysroot

发布时间:2026/10/4 6:39:43

树莓派4B-ROS2-Humble交叉编译sysroot 树莓派 4B ROS 2 Humble 交叉编译sysroot 方案打通笔记编译机Ubuntu 22.04 x86_64 Humble目标板Raspberry Pi 4B 2GBUbuntu Server 22.04.5 ARM64 ros-humble-ros-base方法从板子同步 sysroot电脑上用aarch64-linux-gnu-gcc交叉编译产物 rsync 回板子运行验证包pi_hello_cpp板子上成功打印hello from cross-compiled ARM64 node本文不使用 Docker。Docker Hub 在国内常连不上且 qemu 模拟 ARM 较慢。一、在做什么电脑是 x86_64树莓派是 aarch64。电脑上直接colcon build出来的程序拷到板子会无法执行。交叉编译的含义编译器跑在电脑上aarch64-linux-gnu-gcc生成 ARM Linux 用户态代码头文件和.so来自板子同步到电脑的~/pi_sysrootcolcon / ament仍用电脑上已装的 x86 Humble只当构建工具运行仍用板子 apt 安装的/opt/ros/humble电脑 x86 树莓派 ARM64 ┌─────────────────┐ ┌──────────────────┐ │ aarch64-gcc │ 链接 │ Ubuntu 22.04 │ │ colcon (x86) │ ────── │ /usr /lib │ │ ~/pi_sysroot │ rsync │ /opt/ros/humble │ │ ws/install ARM │ ────── │ ~/pi_cross_install│ └─────────────────┘ └──────────────────┘必须使用aarch64-linux-gnu不要用aarch64-none-linux-gnu那是给无 glibc 的嵌入式目标用的。二、一次性准备电脑sudoaptupdatesudoaptinstall-ygcc-aarch64-linux-gnu g-aarch64-linux-gnursyncaarch64-linux-gnu-gcc-dumpmachine应输出aarch64-linux-gnu。确认能 SSH 上板子IP 按实际情况改sshyao192.168.31.12uname -m应输出aarch64。以下命令全部在电脑上执行不要在树莓派上建~/pi_sysroot。三、从板子同步 sysrootmkdir-p~/pi_sysroot ~/pi_sysroot/opt/ros/humblePIyao192.168.31.12rsync-aH--infoprogress2\--exclude/usr/share/doc\--exclude/usr/share/man\--exclude/usr/src\$PI:/lib/~/pi_sysroot/lib/rsync-aH--infoprogress2\--exclude/usr/share/doc\--exclude/usr/share/man\--exclude/usr/src\$PI:/usr/~/pi_sysroot/usr/rsync-aH--infoprogress2\$PI:/opt/ros/humble/~/pi_sysroot/opt/ros/humble/注意必须先mkdir -p ~/pi_sysroot/opt/ros/humble否则第三条会报mkdir ... failed: No such file or directory不要同步/dev、/proc、/sys、/boot/usr最大可能要数分钟同步完后把 sysroot 里指向/...的绝对符号链接改成相对路径否则在电脑上会指到电脑自己的根目录python3 -PY import os root os.path.expanduser(~/pi_sysroot) n 0 for dirpath, _, filenames in os.walk(root): for name in filenames: p os.path.join(dirpath, name) if not os.path.islink(p): continue t os.readlink(p) if not t.startswith(/): continue rel os.path.relpath(root t, os.path.dirname(p)) os.remove(p) os.symlink(rel, p) n 1 print(fixed, n, symlinks) PYdu-sh~/pi_sysrootls~/pi_sysroot/opt/ros/humble正常示例约 5.4G目录里有setup.bash、lib、include、share。四、CMake toolchainmkdir-p~/pi_crosscat~/pi_cross/aarch64_pi_toolchain.cmakeEOF 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(SYSROOT $ENV{HOME}/pi_sysroot) set(CMAKE_SYSROOT ${SYSROOT}) set(CMAKE_FIND_ROOT_PATH ${SYSROOT}) set(CMAKE_C_FLAGS --sysroot${SYSROOT} CACHE STRING FORCE) set(CMAKE_CXX_FLAGS --sysroot${SYSROOT} CACHE STRING FORCE) set(CMAKE_EXE_LINKER_FLAGS --sysroot${SYSROOT} CACHE STRING FORCE) set(CMAKE_SHARED_LINKER_FLAGS --sysroot${SYSROOT} CACHE STRING FORCE) 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 BOTH) set(Python3_ROOT_DIR ${SYSROOT}/usr) set(Python3_INCLUDE_DIR ${SYSROOT}/usr/include/python3.10) set(Python3_LIBRARY ${SYSROOT}/usr/lib/aarch64-linux-gnu/libpython3.10.so) set(PYTHON_SOABI cpython-310-aarch64-linux-gnu) EOFPACKAGE BOTH电脑上的ament_cmake能找到库仍从 sysroot 链接。五、让 make 找得到 ARM 的 libpythonCMake 会生成对/usr/lib/aarch64-linux-gnu/libpython3.10.so的依赖。这个路径在电脑上不在~/pi_sysroot里。交叉编译器gcc-aarch64-linux-gnu已经占用了/usr/lib/aarch64-linux-gnu里面有ldscripts、bfd-plugins。不要rm -rf这个目录也不要把它整目录替换成指向 sysroot 的链接否则编译器自己的脚本会丢。正确做法保留该目录把 sysroot 里缺的库以符号链接补进去sudorm-f/usr/lib/aarch64-linux-gnu/aarch64-linux-gnuforfin/home/yao/pi_sysroot/usr/lib/aarch64-linux-gnu/*;dob$(basename$f)if[!-e/usr/lib/aarch64-linux-gnu/$b];thensudoln-s$f/usr/lib/aarch64-linux-gnu/$bfidonels-l/usr/lib/aarch64-linux-gnu/libpython3.10.so应能看到libpython3.10.so - libpython3.10.so.1。若 sysroot 里只有libpython3.10.so.1.0、没有.so再补cd~/pi_sysroot/usr/lib/aarch64-linux-gnuln-sfnlibpython3.10.so.1.0 libpython3.10.so六、最小 C 测试包package.xml里邮箱必须合法yaotodo会直接失败。mkdir-p~/pi_cross/ws/src/pi_hello_cpp/srcpackage.xml?xml version1.0?packageformat3namepi_hello_cpp/nameversion0.0.1/versiondescriptionMinimal cross-compile test/descriptionmaintaineremailyaoexample.comyao/maintainerlicenseApache-2.0/licensebuildtool_dependament_cmake/buildtool_dependdependrclcpp/dependexportbuild_typeament_cmake/build_type/export/packageCMakeLists.txtcmake_minimum_required(VERSION 3.8) project(pi_hello_cpp) find_package(ament_cmake REQUIRED) find_package(rclcpp REQUIRED) add_executable(hello src/hello.cpp) ament_target_dependencies(hello rclcpp) install(TARGETS hello DESTINATION lib/${PROJECT_NAME}) ament_package()src/hello.cpp#includerclcpp/rclcpp.hppintmain(intargc,char**argv){rclcpp::init(argc,argv);autonodestd::make_sharedrclcpp::Node(pi_hello_cpp);RCLCPP_INFO(node-get_logger(),hello from cross-compiled ARM64 node);rclcpp::shutdown();return0;}七、交叉编译给板子部署时不要 symlink-install改过 toolchain 或链接库之后先清缓存source/opt/ros/humble/setup.bashcd~/pi_cross/wsrm-rfbuildinstalllog colcon build --parallel-workers4\--cmake-args\-DCMAKE_TOOLCHAIN_FILE$HOME/pi_cross/aarch64_pi_toolchain.cmake\-DCMAKE_PREFIX_PATH$HOME/pi_sysroot/opt/ros/humble\-DCMAKE_BUILD_TYPERelease\-DBUILD_TESTINGOFFfileinstall/pi_hello_cpp/lib/pi_hello_cpp/hellofile必须包含ARM aarch64不能是x86-64。不要对要拷到板子的产物使用--symlink-install。否则install/里是指向电脑build/的链接板子上会报not found: .../share/pi_hello_cpp/local_setup.bash Package pi_hello_cpp not found电脑上开发迭代可以用 symlinkrsync 到板子前必须非 symlink 编一次或rsync -a --copy-links。八、部署到树莓派电脑rsync-a--copy-links ~/pi_cross/ws/install/ yao192.168.31.12:~/pi_cross_install/板子source/opt/ros/humble/setup.bashsource~/pi_cross_install/setup.bash ros2 run pi_hello_cpp hello成功输出[INFO] [...] [pi_hello_cpp]: hello from cross-compiled ARM64 node板子上的 Humble 继续用 apt 那份不要覆盖/opt/ros/humble。日常流程包放在电脑~/pi_cross/ws/src/colcon build带 toolchain不要 symlink-installrsyncinstall/到板子板子source两份 setup 再ros2 run九、板子更新了 ROS 包或系统库电脑怎么同步交叉编译链接的是sysroot 里那一份快照。板子上apt install了新的ros-humble-xxx、升级了libc/libssl等之后电脑上的~/pi_sysroot会过期轻则链接警告重则板子上跑起来缺符号、直接崩溃。1什么时候要同步板子执行过sudo apt update sudo apt upgrade新装了ros-humble-*或-dev包板子上编译/安装过额外的系统库OpenCV、Eigen 等交叉编某个包时提示找不到.so/.pc而板子上明明有小改自己的功能包、没动系统不必重新同步。2增量同步推荐可重复执行还是在电脑上对已有目录做 rsync只传变化的文件PIyao192.168.31.12rsync-aH--delete--infoprogress2\--exclude/usr/share/doc\--exclude/usr/share/man\--exclude/usr/src\$PI:/lib/~/pi_sysroot/lib/rsync-aH--delete--infoprogress2\--exclude/usr/share/doc\--exclude/usr/share/man\--exclude/usr/src\$PI:/usr/~/pi_sysroot/usr/mkdir-p~/pi_sysroot/opt/ros/humblersync-aH--delete--infoprogress2\$PI:/opt/ros/humble/~/pi_sysroot/opt/ros/humble/--delete会删掉板子上已经卸载、但电脑 sysroot 里还留着的文件避免链到旧库。然后再跑一遍符号链接修复脚本第三节那个 Python以及第五节的for f in ... ln -s循环把新出现的.so补到/usr/lib/aarch64-linux-gnu/。最后清 colcon 缓存再编否则会继续用旧的库路径cd~/pi_cross/wsrm-rfbuildinstalllog colcon build --parallel-workers4\--cmake-args\-DCMAKE_TOOLCHAIN_FILE$HOME/pi_cross/aarch64_pi_toolchain.cmake\-DCMAKE_PREFIX_PATH$HOME/pi_sysroot/opt/ros/humble\-DCMAKE_BUILD_TYPERelease\-DBUILD_TESTINGOFF3只更新了某一个 ROS 包时若板子只装了例如ros-humble-cv-bridge可以只同步 Humble 前缀更快rsync-aH--delete--infoprogress2\yao192.168.31.12:/opt/ros/humble/ ~/pi_sysroot/opt/ros/humble/若该包还依赖新的系统库如 OpenCV仍要把/usr再同步一次。4写成电脑上的脚本可选保存为~/pi_cross/sync_sysroot.sh#!/bin/bashset-ePI${PI:-yao192.168.31.12}ROOT$HOME/pi_sysrootmkdir-p$ROOT/opt/ros/humblersync-aH--delete--infoprogress2\--exclude/usr/share/doc--exclude/usr/share/man--exclude/usr/src\$PI:/lib/$ROOT/lib/rsync-aH--delete--infoprogress2\--exclude/usr/share/doc--exclude/usr/share/man--exclude/usr/src\$PI:/usr/$ROOT/usr/rsync-aH--delete--infoprogress2\$PI:/opt/ros/humble/$ROOT/opt/ros/humble/python3 -PY import os root os.path.expanduser(~/pi_sysroot) n 0 for dirpath, _, filenames in os.walk(root): for name in filenames: p os.path.join(dirpath, name) if not os.path.islink(p): continue t os.readlink(p) if not t.startswith(/): continue rel os.path.relpath(root t, os.path.dirname(p)) os.remove(p) os.symlink(rel, p) n 1 print(fixed, n, symlinks) PYforfin$ROOT/usr/lib/aarch64-linux-gnu/*;do[-e$f]||continueb$(basename$f)if[!-e/usr/lib/aarch64-linux-gnu/$b];thensudoln-s$f/usr/lib/aarch64-linux-gnu/$bfidoneechosysroot sync done:$(du-sh$ROOT|cut-f1)chmodx ~/pi_cross/sync_sysroot.sh# 板子 apt 更新之后~/pi_cross/sync_sysroot.sh十、踩坑汇总现象原因处理rsync mkdir humble failed电脑上没有opt/ros中间目录mkdir -p ~/pi_sysroot/opt/ros/humbleInvalid emailyaotodocatkin_pkg 校验邮箱改成yaoexample.comNo rule to make target libpython3.10.somake 找电脑路径/usr/lib/aarch64-linux-gnu/把 sysroot 里的库 ln 进该目录不要整目录替换ln 之后仍找不到 python该路径已是交叉编译器的真实目录删掉目录内部误建的嵌套链接按文件补链0.07s 立刻失败没删build/rm -rf build install log再编板子 Package not found / local_setup.bash--symlink-install链接指向电脑去掉 symlink或rsync --copy-linksfile显示 symbolic linkinstall 指向 build看build/.../hello或不用 symlink板子能编、电脑缺.sosysroot 过期按第九节增量 rsync十一、小结编译器在电脑库来自板子 sysroot运行用板子 apt 的 Humble。给板子的产物不要--symlink-install。板子一升级 ROS/系统库电脑执行sync_sysroot.sh或第九节三条 rsync再清build重编。Python 包多数不用交叉拷源码到板子即可C / 带.so的包走这条链路。
延伸阅读

更多相关文章

2026/9/30 0:16:38

从RAG到搜索智能体:Toast 1如何实现思考型信息检索

最近,AI 圈子里关于“智能体”的讨论热度不减,但很多开发者发现,真正能稳定、高效地完成复杂任务,尤其是需要精准信息检索的智能体,其实并不多。要么是调用成本太高,要么是逻辑推理能力不足,要么…

2026/10/4 11:36:35

MR25H40CDF工业级MRAM存储实战:抗干扰、字节写、高可靠设计

1. MR25H40CDF 不是“普通Flash”,它是一颗能扛住工业现场脉冲干扰的磁阻存储器你手头那块刚焊好的 STM32F429NI 开发板,如果还在用 W25Q32 或 GD25Q16 这类 SPI Flash 做关键参数存储——我劝你立刻停下。不是它们不行,而是当你的设备被部署…

2026/10/4 11:36:35

C# UDP多播实现局域网屏幕广播:从抓屏到接收的完整原型

简介:这份资源面向局域网屏幕共享与多播通信的开发者与学习者,提供一套可运行的屏幕图像实时广播程序源码,帮助理解多播传输、屏幕采集与同步显示的实现思路。压缩包共64个文件,约701KB,以C#源码(cs&#x…

2026/10/4 11:36:35

SolidWorks有限元分析标准流程详解

1. 这不是“点几下就能出结果”的功能,而是工程师的数字验算台SolidWorks Simulation 不是渲染器,也不是自动出图工具——它是一套嵌入在三维建模环境里的工程验证系统。我带过十几届机械专业实习生,几乎所有人第一次打开Simulation模块时&am…

2026/10/4 11:36:35

OpenShell:为Windows 11开始菜单找回效率与自定义自由

一说Windows 11那套居中的开始菜单,不少人是又爱又恨。爱的是它确实比Windows 10时代更符合触屏逻辑,恨的是在鼠标和键盘操作下,它把效率踩在脚底下反复摩擦。打开全屏应用列表要滚好几屏,固定磁贴又没法塞下大量常用工具&#xf…

2026/10/4 11:31:35

MRAM替代EEPROM/电池SRAM:工业存储的SPI驱动与掉电保护实践

最近在给一台小批量生产的工业记录仪做存储模块改造,原来的方案是EEPROM加电池备份SRAM,折腾了两个月,最后全部换成了MRAM。挑来挑去选中了两颗料:Everspin的MR25H40CDF,以及TI的TM4C129XNCZAD,前者做非易失…

2026/10/4 0:01:02

Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化

1. 从“Jev”说起:为什么我要把Agent接进浏览器“Jev”这个词最近在圈子里出现的频率越来越高,很多人第一次听到会以为是某个新模型的名字,其实它更像是一种思路——把Jev模型的能力当作底座,通过Agent的方式去接管浏览器&#xf…

2026/10/4 0:01:02

多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系

1. 从"单兵作战"到"集群协同":多智能体编排到底在解决什么问题如果你最近在折腾 Agent 相关的东西,大概率会有一种感觉:单个 Agent 能做的事情,其实很快就摸到天花板了。你给它一个提示词,挂几个工…

2026/10/4 1:01:05

无源低通滤波器设计实战:从RC到LC,手把手教你避开那些坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 0:01:02

Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化

1. 从“Jev”说起:为什么我要把Agent接进浏览器“Jev”这个词最近在圈子里出现的频率越来越高,很多人第一次听到会以为是某个新模型的名字,其实它更像是一种思路——把Jev模型的能力当作底座,通过Agent的方式去接管浏览器&#xf…

2026/10/4 0:01:02

多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系

1. 从"单兵作战"到"集群协同":多智能体编排到底在解决什么问题如果你最近在折腾 Agent 相关的东西,大概率会有一种感觉:单个 Agent 能做的事情,其实很快就摸到天花板了。你给它一个提示词,挂几个工…

2026/10/4 1:01:05

无源低通滤波器设计实战:从RC到LC,手把手教你避开那些坑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑