ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

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

树莓派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的包走这条链路。
返回列表