警告

您正在阅读的 ROS 2 文档版本已达到 EOL(生命周期结束),不再受官方支持。如果您想了解最新信息,请访问 Jazzy.

交叉编译

概述

开放机器人技术公司为多个平台提供了预构建的 ROS 2 软件包,但许多开发人员仍依赖于 交叉编译 原因各不相同,例如
  • 开发机器与目标系统不匹配。

  • 针对特定内核架构调整构建(例如,为 Raspberry Pi3 构建时设置 -mcpu=cortex-a53 -mfpu=neon-fp-armv8)。

  • 除 Open Robotics 发布的预置镜像支持的文件系统外,还可使用其他文件系统。

本文档详细介绍了如何交叉编译 ROS 2 软件栈,并提供了交叉编译到基于 Arm 内核的系统的示例。

它是如何工作的?

交叉编译简单软件(如不依赖外部库)相对简单,只需使用交叉编译工具链代替本地工具链即可。

有许多因素使这一过程变得更加复杂:
  • 构建的软件必须支持目标架构。在构建过程中,必须根据目标架构正确隔离和启用特定架构代码。例如汇编代码。

  • 所有依赖项(如库)都必须存在,要么是预编译包,要么是交叉编译包,然后再对使用这些依赖项的目标软件进行交叉编译。

  • 在使用构建工具(如 colcon)构建软件堆栈(而非独立软件)时,构建工具应提供一种机制,允许开发人员在堆栈中每个软件所使用的底层构建系统上进行交叉编译。

交叉编译 ROS 2

ROS 2 交叉编译工具由 Open Robotics 和 ROS 工具工作组共同拥有。

这是一个 Python 脚本,可使用 docker 容器中的模拟器为支持的目标架构编译 ROS 2 源文件。该工具的详细设计见 ROS 2 设计.该工具的使用说明载于 交叉编译软件包.

如果您使用的是旧版本,请按照 遗留工具说明.

遗留工具说明

备注

只有在使用旧版本(版本号 0.0.1)的交叉编译工具。对于所有其他用途,请按照 交叉编译 软件包文档。

尽管 ROS 2 是一个包含大量依赖项的丰富软件栈,但它主要使用两种不同类型的软件包:
  • 基于 Python 的软件,无需交叉编译。

  • 基于 CMake 的软件,提供了交叉编译的机制。

此外,ROS 2 软件栈还采用了 科尔康 提供了一种机制,可将参数转发给 CMake 实例,用于单独构建 ROS 2 发行版中的每个软件包/库。

在以本地方式构建 ROS 2 时,开发人员需要在编译 ROS 2 发行版中的软件包之前下载所有依赖项(如 Python 和其他库)。交叉编译时也需要采用同样的方法。开发人员必须首先在目标系统的文件系统中安装好所有依赖项。

本文件接下来的章节将详细介绍如何使用 cmake-toolchainsCMAKE_SYSROOT 功能来交叉编译 ROS 2。

CMake 工具链文件

CMake 工具链文件是一个定义变量的文件,用于配置 CMake 以进行交叉编译。基本条目有

  • cmake_system_name:目标平台,例如 linux

  • cmake_system_processor:目标架构,例如 aarch64武装

  • CMAKE_SYSROOT:目标文件系统的路径

  • cmake_c_compiler:C 交叉编译器,例如 aarch64-linux-gnu-gcc

  • cmake_cxx_compiler:C++ 交叉编译器,例如 aarch64-linux-gnu-g++

  • cmake_find_root_path:...... 查找* 命令来查找文件系统

交叉编译 ROS 2 时,需要设置以下选项:

  • cmake_find_root_path:该程序使用的替代路径 查找* 命令,用它指定 ROS 2 的路径 /install 小册子

  • cmake_find_root_path_mode_*搜索策略:通常使用程序、软件包、库和包含的搜索策略: 绝不 (在主机上查找)、 只有 (系统根),以及 两者 (在 sysroot 和 host-fs 上查找)

  • PYTHON_SOABI:ROS 2 生成的 python 库的索引名称,例如 cpython-36m-aarch64-linux-gnu

  • 线程参数 "0"; CACHE 字符串 结果 TRY_RUN"; 力量:强制执行 TRY_RUN cmd 为 0(成功),因为二进制文件无法在主机系统上运行。

工具链文件与 -DCMAKE_TOOLCHAIN_FILE=path/to/file 参数。这也将设置 cmake_crosscompiling 变量为 可被正在构建的软件使用。

"(《世界人权宣言》) CMAKE_SYSROOT 对于 ROS 2 尤为重要,因为软件包需要许多依赖项(例如 python、openssl、opencv、poco、eigen3......)。设置 CMAKE_SYSROOT 的目标文件系统上安装所有依赖项,这样 CMake 就能在交叉编译时找到它们。

备注

您可以在 CMake 文献资料 page.

下载 ROS 2 源代码时,可在资源库中找到通用工具链文件 ros-tooling/cross_compile/cmake-toolchains 可单独下载。更多使用示例可在 交叉编译 Arm 示例 节。

目标文件系统

如前所述,ROS 2 需要不同的库,需要提供这些库才能交叉编译。

获取文件系统的方法有很多:
  • 下载预置映像

  • 在目标机上安装依赖项并导出文件系统(例如使用 sshfs)

  • 使用 qemu + docker(或 chroot)在主机上生成文件系统。

备注

有关如何使用 Docker + qemu 的信息,请参阅下一章节。 交叉编译 Arm 示例 节。

建设过程

编译过程与本地编译类似。唯一的区别是 科尔康 来指定 工具链文件:

胶管 构建 --合并安装 \
    --cmake-force-configure \
    --cmake-args \
        -dcmake_toolchain_file(工具链文件="<path_to_toolchain/toolchainfile.cmake>";

"(《世界人权宣言》) 工具链文件 的信息提供给 CMake 交叉编译器目标 文件系统. 科尔康 将在 ROS 2 的每个软件包上使用给定的工具链文件调用 CMake。

交叉编译 Arm 示例

之后 下载 ROS 2 源代码在工作区中添加交叉编译资产。 笨蛋 复制 https://github.com/ros-tooling/cross_compile.git -b 0.0.1 src/ros2/cross_compile.这些是如何为 Arm 内核进行交叉编译的工作示例。

支持以下目标
  • Ubuntu-arm64:适用于任何基于 ARMv8-A 的系统。

  • Ubuntu-armhf:适用于任何基于 ARMv7-A 的现代系统。

这些是主要步骤:
  • 安装开发工具

  • 下载 ROS 2 源代码

  • 下载 ROS 2 交叉编译资产

  • 准备系统根

  • 交叉编译 ROS 2 软件栈

接下来的章节将详细解释每个步骤。如需快速设置,请参阅 自动交叉编译.

备注

这些步骤在 Ubuntu 18.04(仿生)上进行了测试

1.安装开发工具

这一步与本地构建类似。不同的是,有些库和工具不是必需的,因为它们将被放在 sysroot 中。需要以下软件包

苏都 适切 更新 &&; 苏都 适切 安装 -y \
    cmake \
    笨蛋 \
    wget \
    python3-pip \
    qemu-user-static \
    g++-aarch64-linux-gnu \
    g++-arm-linux-gnueabihf \
    pkg-config-aarch64-linux-gnu python3 -m 核心 安装 -U \
    vcstool \
    Colcon-common-extensions

备注

您可以通过 pip 安装 vcstool 和 colcon-comm-extensions。这意味着您无需添加额外的 apt 仓库。

使用 Docker 构建目标环境。按照官方 文献资料 进行安装。

2.下载 ROS 2 源代码

然后创建一个工作区并下载 ROS 2 源代码:

mkdir -p ~/cc_ws/ros2_ws/src
CD ~/cc_ws/ros2_ws wget https://raw.githubusercontent.com/ros2/ros2/release-latest/ros2.repos vcs-import 来源 <; ros2.repos git 复制 https://github.com/ros-tooling/cross_compile.git -b 0.0.1 src/ros2/cross_compile
CD ..

3.准备系统根

使用 Docker 和 qemu 构建包含所有 ROS 2 依赖项的 Ubuntu arm 映像:复制 qemu-static 二进制文件到工作区。它将用于使用 docker 在目标文件系统上安装 ROS 2 的依赖项。

mkdir qemu-user-static cp /usr/bin/qemu-*-static qemu-user-static

标准 设置 ROS 2 的进程是在 arm docker 中运行的。这要归功于 qemu-static,它将模拟 arm 机器。使用的基础镜像是来自 Docker Hub 的 Ubuntu Bionic。

装卸工 构建 -t arm_ros2:latest -f ros2_ws/src/cros2/cross_compile/sysroot/Dockerfile_ubuntu_arm .docker 运行 --名称 arm_sysroot arm_ros2:latest

将生成的容器导出为压缩包并解压:

装卸工 集装箱 出口 -o sysroot_docker.tar arm_sysroot mkdir sysroot_docker tar -C sysroot_docker -xf sysroot_docker.tar lib 我们 选择 etc docker rm arm_sysroot

该容器稍后可用作虚拟目标,以运行创建的文件系统并运行演示代码。

4.建设

设置通用工具链文件使用的变量

出口 TARGET_ARCH=aarch64
出口 TARGET_TRIPLE=aarch64-linux-gnu
出口 CC=/usr/bin/$TARGET_TRIPLE-gcc
出口 CXX=/usr/bin/$TARGET_TRIPLE-g++
出口 CROSS_COMPILE=/usr/bin/$TARGET_TRIPLE-
出口 SYSROOT=~/cc_ws/sysroot_docker
出口 ros2_install_path=~/cc_ws/ros2_ws/install
出口 PYTHON_SOABI=cpython-36m-$TARGET_TRIPLE

以下软件包在交叉编译时仍会导致错误(正在调查中),必须暂时禁用。

触摸 \
    ros2_ws/src/ros2/rviz/COLCON_IGNORE \
    ros2_ws/src/ros-visualization/COLCON_IGNORE

"(《世界人权宣言》) Poco 预编译有一个已知问题,即它在搜索 libzlibpcre 而不是 SYSROOT。作为暂时的解决办法,请将这两个库链接到主机的文件系统中。

mkdir -p /usr/lib/$TARGET_TRIPLE
ln -s `pwd`/sysroot_docker/lib/$TARGET_TRIPLE/libz.so.1 /usr/lib/$TARGET_TRIPLE/libz.so ln -s `pwd`/sysroot_docker/lib/$TARGET_TRIPLE/libpcre.so.3 /usr/lib/$TARGET_TRIPLE/libpcre.so

然后,使用 colcon 开始构建,并指定工具链文件:

CD ROS2_WS COLCON 构建 --合并安装 \
    --cmake-force-configure \
    --cmake-args \
        -dcmake_verbose_makefile:bool=关于 \
        -dcmake_toolchain_file(工具链文件=";$(pwd)/src/ros2/cross_compile/cmake-toolchains/generic_linux.cmake"; \
        -安全=关于

完成!安装和构建目录将包含交叉编译的资产。

自动交叉编译

上述所有步骤都包含在 Dockerfile 中,可用于自动化/CI。

首先,下载 dockerfile 并构建镜像:

wget https://raw.githubusercontent.com/ros-tooling/cross_compile/master/Dockerfile_cc_for_arm docker 构建 -t ros2-crosscompiler:latest - <; Dockerfile_cc_for_arm

现在用(需要一点时间)

装卸工 运行 -它 --名称 ros2_cc \
    -v /var/run/docker.sock:/var/run/docker.sock \
    ros2-crosscompiler:latest

.note::-v /var/run/docker.sock 允许我们在 Docker 内部使用 Docker。

构建的结果将在 ros2_ws 目录,可以用

装卸工 cp ros2_cc:/root/cc_ws/ros2_ws .

根据预编译的 ROS 2 进行交叉编译

您可以根据预编译的 ROS 2 交叉编译软件包。 交叉编译 Arm 示例 部分,但作了如下修改:

无需下载 ROS 2 栈,只需在工作区中填充软件包(本例中为 ros2 示例)和交叉编译资产即可:

mkdir -p ~/cc_ws/ros2_ws/src
CD ~/cc_ws/ros2_ws/src git 复制 https://github.com/ros2/examples.git git 复制 https://github.com/ros-tooling/cross_compile.git -b 0.0.1
CD ..

中所述,生成并导出文件系统。 3.准备系统根但提供了 Dockerfile_ubuntu_arm64_prebuilt.这些 _预制 Dockerfile 将使用 二进制软件包 来安装 ROS 2,而不是从源代码构建。

修改环境变量 ros2_install_path 以指向安装目录:

出口 ros2_install_path=~/cc_ws/sysroot_docker/opt/ros/crystal

资料来源 setup.bash 目标文件系统上的脚本:

消息来源 $ros2_install_path/setup.bash

然后,使用 科尔康 指定 工具链文件:

胶管 构建 \
    --合并安装 \
    --cmake-force-configure \
    --cmake-args \
        -dcmake_verbose_makefile:bool=关于 \
        -dcmake_toolchain_file(工具链文件=";$(pwd)/src/cross_compile/cmake-toolchains/generic_linux.cmake";

在目标上运行

在目标机上复制文件系统,或者使用之前构建的 docker 镜像:

装卸工 运行 -它 --rm -v `pwd`/ros2_ws:/ros2_ws arm_ros2:latest

源于环境:

消息来源 /ros2_ws/install/local_setup.bash

运行一些 C++ 或 Python 示例:

玫瑰2 运行 演示节点 听众 及样品;
玫瑰2 运行 演示节点 话匣子