Платформенная справка: CN/EN V1.1.1, RK Linux SDK/Buildroot, примеры RK356x/RK3562. Совместимость версий и Python указана ниже; 32-битная rootfs не проверена/не поддержана источником. Для ArmSoM проверьте SDK, инструментарий и rootfs; аппаратных испытаний нет. Время сборки и вывод — примеры производителя. Технических рисунков в PDF нет; таблицы и код редактируемые.
Сомнения источника сохранены: обе команды docker container cp копируют ros2-sources.tar.gz, хотя далее требуется ros2-build-scripts.tar.gz. Имена build_ros2.sh/build-ros2.sh, pybind11_verdor и cross_compile.mimix/mimix против cross-compile.mixin расходятся. Это не проверенные сценарии. Удаление _FORTIFY_SOURCE — предложение источника, способное ослабить защиту; нужна оценка. Прошивка и swap меняют систему, команды не выполнялись. Авторство кода сохранено.
Пояснение китайских комментариев кода: Dockerfile создаёт образ; два архива образов уже подготовлены; linux-sdk-patches содержит возможные недостающие патчи SDK; MD5SUM проверяет архивы; scripts содержит сценарии/патчи, sources — исходники зависимостей. Добавьте недостающий LTTNG_TOOLS для iron; newgrp входит в группу Docker; сначала получите ID контейнера; не пропускайте ./ (текущий каталог); успешная сборка выводит пример сообщения; результаты TRY_RUN с платы вносятся в Docker; rootfs переупаковывает образ; strace показывает ошибочный поиск в sysroot/$CMAKE_PREFIX_PATH инструментария.
ArmSoM Docs · ROS2 Documentation
1. Версии ROS2
Rockchip Linux SDK основан на Buildroot; инструментарий и пакеты постоянно обновляются. Поэтому сборка ROS2 с новым SDK может давать небольшие ошибки. В предлагаемом методе версии по возможности фиксируются: исходники ROS2 скачиваются с GitHub, версии каждого пакета задаются явно. Выпуски ROS2 приведены ниже.
| Выпуск ROS2 | Версия | Ссылка |
|---|---|---|
| foxy | ros2-release-foxy-20230620 | https://github.com/ros2/ros2/releases/tag/release-foxy-20230620 |
| galactic | ros2-release-galactic-20221209 | https://github.com/ros2/ros2/releases/tag/release-galactic-20221209 |
| humble | ros2-release-humble-20230724 | https://github.com/ros2/ros2/releases/tag/release-humble-20230724 |
| iron | ros2-release-iron-20230912 | https://github.com/ros2/ros2/releases/tag/release-iron-20230912 |
Версии RK Linux SDK, для которых источник сообщает об успешной сборке:
| Linux SDKBuildroot Version | Версия Python | Подходящий образ Docker | Примечание |
|---|---|---|---|
| linux-5.10-stan-rkr1 | Python 3.10.5 | jammy-ros2-build | Добавить патч ros2_dep.config |
| linux-4.19-gen-rkr3 | Python 3.8.6 | focal-ros2-build | Обновить и включить патчи lttng: lttng-tools(2.12.3), lttng-libust(2.12.3), liburcu(0.13.0) |
Примечание: версии Python на Docker-хосте и в целевой rootfs должны совпадать. 32-битная система не проверена.
2. Файлы и пояснения для сборки в Docker
Патчи, образы Docker и исходники этого раздела можно скачать по следующей ссылке:
https://console.zbox.filez.com/l/iJBMWZ
tree
.
├── docker-focal-python38
│ └── rosdep.Dockerfile # 制作Docker Image的Dockerfile
├── docker-jammy-python310
│ └── rosdep.Dockerfile # 制作Docker Image的Dockerfile
├── focal-ros2-build.tar.gz # 根据Dockerfile制作好的Docker Image
├── jammy-ros2-build.tar.gz # 根据Dockerfile制作好的Docker Image
├── linux-sdk-patches
│ └── buildroot # RK Linux SDK不同发布版本有可能会缺少的补丁
│ ├── 0001-package-add-libasio.patch
│ └── 0002-configs-rockchip-add-ros2-build-dependencies.patch
├── MD5SUM.txt # 各压缩包的MD5SUM检验码
├── ros2-build-scripts.tar.gz # 编译脚本及补丁
└── ros2-sources.tar.gz # ROS2及其部分依赖库的源码包
Проверьте наличие ros2_dep.config в каталоге Buildroot RK Linux SDK.
ls buildroot/configs/rockchip/ros2_dep.config
buildroot/configs/rockchip/ros2_dep.config
# 如该ros2_dep.config中缺少:LTTNG_TOOLS,⼿动加上(ROS2 iron有依赖)
tail -f buildroot/configs/rockchip/ros2_dep.config
# Required by ros2-iron tracetools; With LTTNG foxy/galactic/humble will build tracetools too.
BR2_PACKAGE_LTTNG_TOOLS=y
BR2_PACKAGE_LTTNG_LIBUST=y
Если файла нет, примените следующие два патча в каталоге Buildroot.
0001-package-add-libasio.patch
0002-configs-rockchip-add-ros2-build-dependencies.patch
Проверьте требуемые версии lttng-tools (2.12.3), lttng-libust (2.12.3) и liburcu (0.13.0).
3. Сборка зависимостей ROS2
В проекте Buildroot RK Linux SDK файл ros2_dep.config задаёт зависимости сборки и выполнения ROS2; их нужно включить в rootfs и собрать. Например, добавьте ros2_dep.config в rockchip_rk356x_robot_defconfig:
git diff
--- a/configs/rockchip_rk356x_robot_defconfig
+++ b/configs/rockchip_rk356x_robot_defconfig
@@ -10,6 +10,7 @@
#include "wifi.config"
#include "debug.config"
#include "bt.config"
+#include "ros2_dep.config"
BR2_TARGET_GENERIC_HOSTNAME="rk356x_robot"
BR2_TARGET_GENERIC_ISSUE="Welcome to RK356X Buildroot For Robot"
BR2_ROOTFS_OVERLAY:="board/rockchip/common/robot/base board/rockchip/common/wifi"
После полной сборки rootfs переходите к следующему шагу.
4. Подготовка среды сборки на Linux (Ubuntu) PC
Установите Docker на Ubuntu PC:
sudo apt install docker.io
sudo usermod -aG docker $USER
newgrp docker # 登录到docker⽤⼾组
4.1 Импорт образа Docker
Сначала проверьте версию Python, собранную RK Linux SDK, например:
./buildroot/output/rockchip_rk3562_robot/host/bin/python --version
Python 3.10.5
Выберите соответствующий образ Docker по версии Python:
| Версия Python | Подходящий образ Docker |
|---|---|
| Python 3.10.5 | jammy-ros2-build |
| Python 3.8.6 | focal-ros2-build |
Выберите jammy-ros2-build, импортируйте образ и войдите в контейнер:
gunzip jammy-ros2-build.tar.gz
docker image load -i jammy-ros2-build.tar
docker run -it --mount type=bind,source=/home/zsq/29/linux-sdk/buildroot/output/rockchip_rk3562_robot/,target=/buildroot jammy-ros2-build
Замените source= абсолютным путём к каталогу output собранного Linux SDK. После входа в контейнер пользователь по умолчанию — builder, пароль по умолчанию — rockchip.
4.2 Копирование сценария сборки и архива исходников
Скопируйте необходимые файлы командой docker container cp:
# ⾸先查找已登录的container ID
docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS
PORTS NAMES
c519d9d668f9 jammy-ros2-build "/bin/bash" 15 minutes ago Up 15 minutes
pedantic_feynman
docker container cp ros2-sources.tar.gz c519d9d668f9:/tmp/
docker container cp ros2-sources.tar.gz c519d9d668f9:/tmp/
Распакуйте их в контейнере:
builder@c519d9d668f9:/opt/ros$ ls /tmp/
ros2-build-scripts.tar.gz ros2-sources.tar.gz
builder@c519d9d668f9:/opt/ros$ tar zxf /tmp/ros2-build-scripts.tar.gz -C /
builder@c519d9d668f9:/opt/ros$ tar zxf /tmp/ros2-sources.tar.gz -C /
builder@c519d9d668f9:/opt/ros$ ls
cross-compile foxy galactic humble iron
4.3 Изменение версии Python в сценариях
Проверьте /opt/ros/cross-compile/cross-compile.mixin и build_ros2.sh. Замените версию Python версией RK Linux SDK: например, 310 на 38; 310 означает Python 3.10 и далее аналогично.
Замените 3.10 на 3.8.
4.4 (Необязательно) Сборка ROS2 с Docker
Для создания образа Docker с нуля используйте предоставленный RK файл rosdep.Dockerfile:
docker build -t jammy-ros2-build -f rosdep.Dockerfile ./ # "./"不要少拷⻉了,表⽰当前⽬录
4.5 (Необязательно) Загрузка исходников
Чтобы скачать исходники других версий, после входа в Docker используйте vcs-import:
cd /opt/ros/foxy
mkdir src
vcs-import -w 10 --retry 10 --skip-existing --recursive src < ros2-release-foxy-20230620/ros2.repos
5. Сборка ROS2
Ещё раз убедитесь, что в RK Linux SDK включён ros2_dep.config и rootfs полностью собрана. Версия Python выбранного образа Docker должна соответствовать версии из RK Linux SDK. Выберите выпуск ROS2 и последовательно выполните следующие команды:
ls /opt/ros
cross-compile foxy galactic humble iron
cd /opt/ros/iron
./prepare-source.sh
./build-ros2.sh
# 编译成功后,应有类似提⽰:
...
Summary: 317 packages finished [15min 37s]
...
build ros quit & cleanup
Результаты сборки находятся в /buildroot/target/opt/ros, промежуточные файлы — в /buildroot/build/ros. Если build_ros2.sh не сообщает ошибок, сборка успешна. Некоторые пакеты в Buildroot SDK не собираются или не выполняются: rviz требует X11/рабочий стол; для этой функции используйте образ Ubuntu arm вместо Buildroot. turtlesim требует графический интерфейс. Чтобы исключить пакет, создайте COLCON_IGNORE в соответствующем каталоге src, например: touch src/ros/ros_tutorials/turtlesim/COLCON_IGNORE.
5.1 TRY_RUN: выполнить вручную и записать результат
Сообщение TRY_RUN для fastrtps:
--- stderr: fastrtps
CMake Error: TRY_RUN() invoked in cross-compiling mode, please set the following
cache variables appropriately:
SM_RUN_RESULT (advanced)
SM_RUN_RESULT__TRYRUN_OUTPUT (advanced)
For details see /buildroot/build/ros/fastrtps/TryRunResults.cmake
Согласно инструкции перенесите приложение на плату, выполните его и внесите результат. Например:
root@rk3562-buildroot:/# /tmp/cmTC_4f573-SM_RUN_RESULT
PTHREAD_RWLOCK_PREFER_READER_NP
# 根据上述执⾏结果,在docker中填⼊结果:
cat /buildroot/build/ros/fastrtps/TryRunResults.cmake
....
set( SM_RUN_RESULT
"0"
CACHE STRING "PTHREAD_RWLOCK_PREFER_READER_NP" FORCE)
set( SM_RUN_RESULT__TRYRUN_OUTPUT
"0"
CACHE STRING "PTHREAD_RWLOCK_PREFER_READER_NP" FORCE)
Сообщение TRY_RUN для rosbag2_cpp:
--- stderr: rosbag2_cpp
CMake Error: TRY_RUN() invoked in cross-compiling mode, please set the following
cache variables appropriately:
HAVE_SANITIZERS_EXITCODE (advanced)
HAVE_SANITIZERS_EXITCODE__TRYRUN_OUTPUT (advanced)
For details see /buildroot/build/ros/rosbag2_cpp/TryRunResults.cmake
Как выше: запустите приложение на плате по инструкции и внесите результаты. Например:
set( HAVE_SANITIZERS_EXITCODE
"127"
CACHE STRING "error while loading shared libraries: liblsan.so.0: cannot open shared object file: No such file or directory" FORCE)
set( HAVE_SANITIZERS_EXITCODE__TRYRUN_OUTPUT
"127"
CACHE STRING "error while loading shared libraries: liblsan.so.0: cannot open shared object file: No such file or directory" FORCE)
5.2 Отдельная сборка пакета ROS2 и приложения
Параметр colcon build –packages-select
6. Упаковка rootfs и запуск ROS2
После полной сборки ROS2 вернитесь в Buildroot SDK и заново упакуйте rootfs. ROS2 установлена в /opt/ros.
cd /data/linux-sdk/rk3562
./build.sh rootfs # 重新打包rootfs.img
После прошивки rootfs.img на плате rk3562 выполните Hello World Demo:
# cd /opt/ros/
# export COLCON_CURRENT_PREFIX=/opt/ros
# export ROS_HOME=/userdata/
# source ./local_setup.sh
# ros2 pkg list
# ros2 pkg executables
# ros2 run demo_nodes_cpp listener &
# ros2 run demo_nodes_cpp talker
[INFO] [1501839280.834017748] [talker]: Publishing: 'Hello World: 1'
[INFO] [1501839280.839280957] [listener]: I heard: [Hello World: 1]
[INFO] [1501839281.831636015] [talker]: Publishing: 'Hello World: 2'
[INFO] [1501839281.835092640] [listener]: I heard: [Hello World: 2]
[INFO] [1501839282.831618532] [talker]: Publishing: 'Hello World: 3'
[INFO] [1501839282.835336782] [listener]: I heard: [Hello World: 3]
# ros2 run demo_nodes_py listener &
# ros2 run demo_nodes_py talker
7. Решённые типичные ошибки сборки
7.1 Недостаточно памяти на машине сборки
Можно включить swap, например zram:
sudo -i su
# modprobe zram
# echo 12G > /sys/block/zram0/disksize
# echo 6G > /sys/block/zram0/mem_limit
# mkswap /dev/zram0
# swapon /dev/zram0
# free -h
total used free shared buff/cache available
Mem: 14Gi 3.9Gi 5.5Gi 27Mi 5.4Gi 10Gi
Swap: 11Gi 2.7Gi 9.3Gi
7.2 Ошибка на плате: `GLIBCXX_3.4.30’ not found
root@rk3562-buildroot:/opt/ros-foxy# ros2 run demo_nodes_cpp talker
/opt/ros-foxy/lib/demo_nodes_cpp/talker: /lib/libstdc++.so.6: version
`GLIBCXX_3.4.30' not found (required by /opt/ros-foxy/lib/librclcpp.so)
/opt/ros-foxy/lib/demo_nodes_cpp/talker: /lib/libstdc++.so.6: version
`GLIBCXX_3.4.30' not found (required by /opt/ros-foxy/lib/libspdlog.so.1)
Существует много версий RK Linux SDK с обновляемым инструментарем. Для ROS2 необходимо использовать тот же кросс-компилятор Linux SDK, которым собрана rootfs.
7.3 В результате сборки появляются библиотеки x86_64
ls /opt/ros/lib/python3.10/site-packages/rclpy/_rclpy_pybind11.cpython-310-x86_64-linux-gnu.so
У pybind11 есть известные проблемы при кросс-компиляции: найденный Python является исполняемым файлом HOST, поэтому параметры также формируются для HOST, например:
PYTHON_MODULE_EXTENSION:INTERNAL=.cpython-310-x86_64-linux-gnu.so
В новых версиях pybind11/tools/FindPythonLibsNew.cmake рекомендуется при кросс-компиляции задавать параметры Python вручную извне. На этой основе:
-
Обновите pybind11 в src/ros2/pybind11_vendor до v2.10.2.
-
Задайте следующие два параметра в pybind11_verdor/CMakeLists.txt, явно указав PYTHON_MODULE_EXTENSION:
list(APPEND extra_cmake_args "-DPYBIND11_PYTHONLIBS_OVERWRITE=OFF")
list(APPEND extra_cmake_args "-DPYTHON_MODULE_EXTENSION=.cpython-310-aarch64-linux-gnu.so")
- Также объявите в cross-compile.mixin:
- "-DPYBIND11_PYTHONLIBS_OVERWRITE=OFF"
- "-DPYTHON_MODULE_EXTENSION=.cpython-310-aarch64-linux-gnu.so"
После этих изменений PYTHON_MODULE_EXTENSION в CMakeCache.txt сборки rclpy всё ещё указывает на x86_64, но при второй сборке меняется на ожидаемый aarch64. Причины:
- В pybind11/tools/pybind11NewTools.cmake переменная PYTHON_MODULE_EXTENSION очищается, если PYBIND11_PYTHON_EXECUTABLE_LAST ещё не задана либо её значение изменилось.
76 if(NOT ${_Python}_EXECUTABLE STREQUAL PYBIND11_PYTHON_EXECUTABLE_LAST)
77 # Detect changes to the Python version/binary in subsequent CMake runs, and refresh config if needed
78 unset(PYTHON_IS_DEBUG CACHE)
79 unset(PYTHON_MODULE_EXTENSION CACHE)
80 set(PYBIND11_PYTHON_EXECUTABLE_LAST
81 "${${_Python}_EXECUTABLE}"
82 CACHE INTERNAL "Python executable during the last CMake run")
83 endif()
-
Аналогичное явление описано в pybind11 issue #236.
-
Решение: измените pybind11 так, чтобы при PYBIND11_PYTHONLIBS_OVERWRITE = “OFF” эти параметры не переустанавливались:
commit f7f1f2a927dd785d109833e411325de4c248719f (HEAD -> v2.10.2-fix)
Author: cross-build for rk-linux-sdk <cross-build@rk-linux-sdk.com>
Date: Fri Sep 22 08:24:58 2023 +0000
Do not override the PYTHON_MODULE_EXTENSION if cross building
As suggested in tools/FindPythonLibsNew.cmake,
PYBIND11_PYTHONLIBS_OVERWRITE is a flag to indicate that we set python variables
manually when cross building.
In this case, do not override variables if PYBIND11_PYTHON_EXECUTABLE_LAST
changed or is empty.
diff --git a/tools/pybind11NewTools.cmake b/tools/pybind11NewTools.cmake
index 7d7424a7..91980dad 100644
--- a/tools/pybind11NewTools.cmake
+++ b/tools/pybind11NewTools.cmake
@@ -73,7 +73,7 @@ if(NOT DEFINED ${_Python}_EXECUTABLE)
endif()
-if(NOT ${_Python}_EXECUTABLE STREQUAL PYBIND11_PYTHON_EXECUTABLE_LAST)
+if(NOT ${_Python}_EXECUTABLE STREQUAL PYBIND11_PYTHON_EXECUTABLE_LAST AND NOT PYBIND11_PYTHONLIBS_OVERWRITE STREQUAL "OFF")
# Detect changes to the Python version/binary in subsequent CMake runs, and refresh config if needed
unset(PYTHON_IS_DEBUG CACHE)
unset(PYTHON_MODULE_EXTENSION CACHE)
7.4 В google_benchmark отсутствует заголовок limits
При сборке foxy возникает следующая ошибка:
In file included from /buildroot/build/ros/google_benchmark_vendor/benchmark-1.5.2-prefix/src/benchmark-1.5.2/src/benchmark_register.cc:15:
/buildroot/build/ros/google_benchmark_vendor/benchmark-1.5.2-prefix/src/benchmark-1.5.2/src/benchmark_register.h: In function ‘typename
std::vector<T>::iterator benchmark::internal::AddPowers(std::vector<T>*, T, T,
int)’:
/buildroot/build/ros/google_benchmark_vendor/benchmark-1.5.2-prefix/src/benchmark-1.5.2/src/benchmark_register.h:22:30: error:
‘numeric_limits’ is not a member of ‘std’
22 | static const T kmax = std::numeric_limits<T>::max();
| ^~~~~~~~~~~~~~
Причина — отсутствующий заголовок:
/buildroot/build/ros/google_benchmark_vendor/benchmark-1.5.2-prefix/src/benchmark-1.5.2/src/benchmark_register.h
#include <limits>
Исправлено в новых версиях ROS2; изменение включено и в комплект патчей.
7.5 _FORTIFY_SOURCE определён в инструментарии Linux SDK
--- stderr: mimick_vendor
Cloning into 'mimick-f171450b5ebaa3d2538c762a059dfc6ab7a01039'...
fatal: unable to access 'https://github.com/ros2/Mimick.git/': gnutls_handshake()
failed: Error in the pull function.
Cloning into 'mimick-f171450b5ebaa3d2538c762a059dfc6ab7a01039'...
HEAD is now at f171450 Add armv7l as a 32-bit ARM architecture. (#16)
In file included from /opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/errno.h:25,
from /buildroot/build/ros/mimick_vendor/mimick-f171450b5ebaa3d2538c762a059dfc6ab7a01039-prefix/src/mimick-f171450b5ebaa3d2538c762a059dfc6ab7a01039/include/mimick/mock.h:27,
from /buildroot/build/ros/mimick_vendor/mimick-f171450b5ebaa3d2538c762a059dfc6ab7a01039-prefix/src/mimick-f171450b5ebaa3d2538c762a059dfc6ab7a01039/include/mimick/mimick.h:401,
from /buildroot/build/ros/mimick_vendor/mimick-f171450b5ebaa3d2538c762a059dfc6ab7a01039-prefix/src/mimick-f171450b5ebaa3d2538c762a059dfc6ab7a01039/sample/strdup/test.c:1:
/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/features.h:412:4: error: #warning _FORTIFY_SOURCE
requires compiling with optimization (-O) [-Werror=cpp]
412 | # warning _FORTIFY_SOURCE requires compiling with optimization (-O)
| ^~~~~~~
cc1: all warnings being treated as errors
make[5]: *** [sample/strdup/CMakeFiles/strdup_test.dir/build.make:63:
sample/strdup/CMakeFiles/strdup_test.dir/test.c.o] Error 1
make[4]: *** [CMakeFiles/Makefile2:302:
sample/strdup/CMakeFiles/strdup_test.dir/all] Error 2
make[4]: *** Waiting for unfinished jobs....
In file included from /opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/errno.h:25,
from /buildroot/build/ros/mimick_vendor/mimick-f171450b5ebaa3d2538c762a059dfc6ab7a01039-prefix/src/mimick-f171450b5ebaa3d2538c762a059dfc6ab7a01039/include/mimick/mock.h:27,
from /buildroot/build/ros/mimick_vendor/mimick-f171450b5ebaa3d2538c762a059dfc6ab7a01039-prefix/src/mimick-f171450b5ebaa3d2538c762a059dfc6ab7a01039/include/mimick/mimick.h:401,
from /buildroot/build/ros/mimick_vendor/mimick-f171450b5ebaa3d2538c762a059dfc6ab7a01039-prefix/src/mimick-f171450b5ebaa3d2538c762a059dfc6ab7a01039/test/test.c:1:
/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/usr/include/features.h:412:4: error: #warning _FORTIFY_SOURCE
requires compiling with optimization (-O) [-Werror=cpp]
412 | # warning _FORTIFY_SOURCE requires compiling with optimization (-O)
| ^~~~~~~
cc1: all warnings being treated as errors
Ошибка возникает только при заданном -DCMAKE_TOOLCHAIN_FILE=”/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/share/buildroot/toolchainfile.cmake”, если этот CMake-файл определяет _FORTIFY_SOURCE. Можно не задавать CMAKE_TOOLCHAIN_FILE либо удалить _FORTIFY_SOURCE.
7.6 CMake не находит exlibConfig.cmake
Сборка ament_cmake_vendor_package сообщает, что exlib не найдена, хотя библиотека задана правильно.
root@db4be0cd3eca:/buildroot/build/ros/ament_cmake_vendor_package/test# make
[ 33%] Built target exlib_bad
[ 66%] Built target exlib_good
[ 71%] Performing configure step for 'depender'
loading initial cache file
/buildroot/build/ros/ament_cmake_vendor_package/test/depender-config.cmake
CMake Error at CMakeLists.txt:4 (find_package):
By not providing "Findexlib.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "exlib", but
CMake did not find one.
Could not find a package configuration file provided by "exlib" with any of
the following names:
exlibConfig.cmake
exlib-config.cmake
Add the installation prefix of "exlib" to CMAKE_PREFIX_PATH or set
"exlib_DIR" to a directory containing one of the above files. If "exlib"
provides a separate development package or SDK, be sure it has been
installed.
# strace make 可以看到:
[pid 458018] newfstatat(AT_FDCWD, "/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/buildroot/build/ros/ament_cmake_vendor_package/test/exlib_bad-prefix/install", 0x7ffca495cf50, 0) = -1 ENOENT (No such file or directory)
# :
# grep CMAKE_PREFIX_PATH depender-config.cmake
set(CMAKE_PREFIX_PATH [=[/buildroot/build/ros/ament_cmake_vendor_package/test/exlib_bad-prefix/install;/buildroot/build/ros/ament_cmake_vendor_package/test/exlib_good-prefix/install;/buildroot/build/ros/ament_cmake_vendor_package/test/depender-prefix/install]=] CACHE INTERNAL "")
它去找了Toolchain⽬录下的sysroot/$CMAKE_PREFIX_PATH,所以找不到。
CMAKE_PREFIX_PATH правильно содержит путь exlib. strace make показывает неверный фактический путь поиска с лишним префиксом /opt/aarch64-buildroot-linux-gnu_sdk-buildroot/aarch64-buildroot-linux-gnu/sysroot/. Причина: colcon получает –cmake-args -DCMAKE_TOOLCHAIN_FILE=”/opt/aarch64-buildroot-linux-gnu_sdk-buildroot/share/buildroot/toolchainfile.cmake”, что отличается от toolchain, заданной экспортированными переменными окружения и mimix.
7.7 pkg-config не найден
Starting >>> tracetools
--- stderr: tracetools
CMake Error at /usr/share/cmake-3.22/Modules/FindPackageHandleStandardArgs.cmake:230(message):
Could NOT find PkgConfig (missing: PKG_CONFIG_EXECUTABLE)
Reason given by package: The command
"/usr/bin/pkg-config" --version
failed with output:
stderr:
/usr/bin/pkg-config: symbol lookup error: /usr/bin/pkg-config: undefined
symbol: pkgconf_cross_personality_deinit
result:
127
Call Stack (most recent call first):
/usr/share/cmake-3.22/Modules/FindPackageHandleStandardArgs.cmake:594
(_FPHSA_FAILURE_MESSAGE)
/usr/share/cmake-3.22/Modules/FindPkgConfig.cmake:99
(find_package_handle_standard_args)
CMakeLists.txt:35 (find_package)
В Docker должен быть установлен pkgconf, не pkg-config: он нужен cmake pkg_check_modules(). Если Linux SDK также собирает pkgconf, создаётся host-pkgconf. Из-за отличия версий при поиске pkgconf.so находится библиотека host-pkgconf из Buildroot вместо Docker, и выполнение завершается ошибкой.
7.8 Нужно задать PKG_CONFIG_PATH
При сборке src/ros2/ros2_tracing/tracetools/ в CMakeLists.txt задано:
pkg_check_modules(LTTNG REQUIRED lttng-ust)
Ошибка сборки:
Starting >>> tracetools
--- stderr: tracetools
CMake Error at /usr/share/cmake-3.22/Modules/FindPkgConfig.cmake:611 (message):
A required package was not found
Call Stack (most recent call first):
/usr/share/cmake-3.22/Modules/FindPkgConfig.cmake:833
(_pkg_check_modules_internal)
CMakeLists.txt:36 (pkg_check_modules)
strace -f показывает, что поиск не выполняется в sysroot Linux SDK. Задайте export PKG_CONFIG_PATH=/buildroot/host/aarch64-buildroot-linux-gnu/sysroot/usr/lib/pkgconfig. Другой случай: pkg-config находит lttng из Docker вместо целевой версии и выдаёт:
Starting >>> tracetools
--- stderr: tracetools
/usr/lib/gcc-cross/aarch64-linux-gnu/11/../../../../aarch64-linux-gnu/bin/ld:
cannot find -llttng-ust-common: No such file or directory
collect2: error: ld returned 1 exit status
gmake[2]: *** [CMakeFiles/tracetools.dir/build.make:129: libtracetools.so] Error
1
gmake[1]: *** [CMakeFiles/Makefile2:161: CMakeFiles/tracetools.dir/all] Error 2
gmake[1]: *** Waiting for unfinished jobs....
gmake: *** [Makefile:146: all] Error 2
---
Failed <<< tracetools [4.72s, exited with code 2]
Найдена версия lttng из Docker, отличная от Buildroot. Её lttng-ust.pc требует lttng-ust-common, но в Buildroot этой библиотеки нет. Также задайте export PKG_CONFIG_PATH=/buildroot/host/aarch64-buildroot-linux-gnu/sysroot/usr/lib/pkgconfig. Параметр уже задан в сценарии сборки. Пакет lttng можно не устанавливать в Docker.
7.9 Нужно задать CMAKE_INCLUDE_PATH
Starting >>> orocos_kdl_vendor
--- stderr: orocos_kdl_vendor
Cloning into 'orocos_kdl-507de66'...
done.
HEAD is now at 507de66 Fix CMake warning on Windows (#392)
Submodule 'python_orocos_kdl/pybind11' (https://github.com/pybind/pybind11.git)
registered for path 'python_orocos_kdl/pybind11'
Cloning into '/buildroot/build/ros/orocos_kdl_vendor/orocos_kdl-507de66-prefix/src/orocos_kdl-507de66/python_orocos_kdl/pybind11'...
CMake Error: The following variables are used in this project, but they are set
to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake
files:
EIGEN3_INCLUDE_DIR (ADVANCED)
Путь заголовков, созданных сборкой Linux SDK, нужно задать отдельно, иначе CMake их не найдёт:
export CMAKE_INCLUDE_PATH='/buildroot/host/aarch64-buildroot-linux-gnu/sysroot/usr/include/'
Этот параметр уже задан в сценарии сборки.
7.10 unsafe header/library used in cross-compilation
--- stderr: action_msgs
aarch64-buildroot-linux-gnu-gcc: WARNING: unsafe header/library path used in
cross-compilation: '-isystem' '/usr/local/lib/python3.10/dist-packages/numpy/core/include'
При кросс-компиляции используется /usr/bin/python хоста. Когда numpy/numpyconfig.h не найден, следующий способ получения include dir не даёт правильный путь целевой платы:
# Check if numpy is in the include path
find_file(_numpy_h numpy/numpyconfig.h
PATHS ${PythonExtra_INCLUDE_DIRS}
)
if(APPLE OR WIN32 OR NOT _numpy_h)
# add include directory for numpy headers
set(_python_code
"import numpy"
"print(numpy.get_include())"
)
После выяснения, что путь задаётся PythonExtra_INCLUDE_DIRS, найдите его определение в pybind11: оно происходит из PYTHON_INCLUDE_DIR. При кросс-компиляции значение можно заранее задать в cross_compile.mimix. Параметр уже предусмотрен сценарием сборки; допускается несколько каталогов.
8. Что ещё предстоит улучшить
8.1 Удаление ненужных установленных файлов
Например CMake-файлы, заголовки и статические библиотеки: их можно устанавливать в sysroot.
8.2 ROS2 ещё не поддерживает сборку для arm32 rootfs Linux SDK
9. Ссылки
-
https://docs.ros.org/en/foxy/Guides/Cross-compilation.html
-
https://github.com/ros-tooling/cross_compile.git
-
https://docs.ros.org/en/foxy/Releases.html
