交叉编译 [待校准@5934]

有关交叉编译的背景信息,请参见 conceptual article[待校准@5935]

本文档为您提供了如何交叉编译ROS 2软件堆栈的详细信息,并提供了基于Arm内核交叉编译到系统的示例。 [待校准@5936]

交叉编译工具 [待校准@5937]

使用该工具的说明在 cross_compile package 中。 [待校准@5938]

传统工具说明 [待校准@5939]

注解

仅当您使用交叉编译工具的旧版本 ( 0.0.1 版) 时,请按照以下步骤操作。对于所有其他目的,遵循 cross_compile 包装文件。 [待校准@5940]

尽管ROS 2是具有许多依赖项的丰富软件堆栈,但它主要使用两种不同类型的包: [待校准@5941]

此外,ROS 2软件堆栈是用 Colcon 构建的, Colcon 提供了一种机制,将参数转发到CMake实例,该实例用于作为ROS 2发行版一部分的每个包/库的单独构建。 [待校准@5944]

在本机构建ROS 2时,开发人员需要在编译作为ROS 2发行版一部分的包之前下载所有依赖项 (例如Python和其他库)。交叉编译时,需要使用相同的方法。开发人员必须首先拥有已安装所有依赖项的目标系统文件系统。 [待校准@5945]

本文档的下一节详细解释了使用 cmake-toolchains and the CMAKE_SYSROOT 特性交叉编译ROS 2。 [待校准@5946]

CMake工具链-文件 [待校准@5947]

CMake工具链文件是定义变量以配置CMake以进行交叉编译的文件。基本条目如下: [待校准@5948]

  • CMAKE_SYSTEM_NAME: the target platform, e.g. linux [待校准@5949]

  • CMAKE_SYSTEM_PROCESSOR: the target architecture, e.g. aarch64 or arm [待校准@5950]

  • [需手动修复的语法]``CMAKE_SYSROOT``:目标文件系统的路径 [待校准@5951]

  • CMAKE_C_COMPILER: the C cross-compiler, e.g. aarch64-linux-gnu-gcc [待校准@5952]

  • CMAKE_CXX_COMPILER: the C++ cross-compiler, e.g. aarch64-linux-gnu-g++ [待校准@5953]

  • 找到文件系统的``CMAKE_FIND_ROOT_PATH``: an alternative path used by the find_* command [待校准@5954]

交叉编译ROS 2时,需要设置以下选项: [待校准@5955]

  • CMAKE_FIND_ROOT_PATH: the alternative path used by the find_* command, use it to specify the path to ROS 2 /install folder [待校准@5956]

  • [需手动修复的语法]``CMAKE_FIND_ROOT_PATH_MODE_*``: the search strategy for program,package,library, and include, usually: NEVER (look on the host-fs), ONLY (look on sysroot), and BOTH (查看sysroot和host-fs) [待校准@5957]

  • PYTHON_SOABI: the index name of the python libraries generated by ROS 2, e.g. cpython-36m-aarch64-linux-gnu [待校准@5958]

  • [需手动修复的语法]``THREADS_PTHREAD_ARG "0" CACHE STRING "Result from TRY_RUN" FORCE``: Force the result of the TRY_RUN cmd到0 (成功),因为二进制文件不能在主机系统上运行。 [待校准@5959]

工具链文件通过 -DCMAKE_TOOLCHAIN_FILE=path/to/file 参数提供给CMake。这也将 CMAKE_CROSSCOMPILING 变量设置为 true ,这可以被正在构建的软件使用。 [待校准@5960]

[需手动修复的语法] CMAKE_SYSROOT 对ROS 2特别重要,因为包需要许多依赖项 (例如python、openssl、tcl、poco、本征3、。……)。将[需手动修复的语法] CMAKE_SYSROOT 设置为安装了所有依赖项的目标文件系统将允许CMake在交叉编译期间找到它们。 [待校准@5961]

注解

您可以在CMake documentation 页面找到更多信息。 [待校准@5962]

下载ROS 2源文件时,仓库 ros-tooling/cross_compile/cmake-toolchains 有一个通用的工具链文件,可以单独下载。关于使用它的更多例子可以在 Cross-compiling examples for Arm 部分找到。 [待校准@5963]

目标文件系统 [待校准@5964]

如前所述,ROS 2需要提供不同的库来交叉编译。 [待校准@5965]

获取文件系统有多种方法: [待校准@5966]

注解

你可以找到如何使用Docker + qemu下 Cross-compiling examples for Arm 型材。 [待校准@5970]

构建流程 [待校准@5971]

构建过程类似于本机编译。唯一的区别是对 Colcon 的一个额外的参数来指定 toolchain-file : [待校准@5972]

colcon build --merge-install \
    --cmake-force-configure \
    --cmake-args \
        -DCMAKE_TOOLCHAIN_FILE="<path_to_toolchain/toolchainfile.cmake>"

[需手动修复的语法] toolchain-file 向CMake提供 cross-compilertarget file-system 的信息。在ROS 2的每个包中, Colcon 将使用给定的工具链文件调用CMake。 [待校准@5973]

Arm交叉编译示例 [待校准@5974]

downloading the ROS 2 source code ,你可以添加交叉编译资产工作区通过 ''git克隆https://github.com/ros工装/cross_compile.git b 0.0.1 src/ros2/cross_compile ”。这些是关于如何交叉编译Arm内核的工作示例。 [待校准@5975]

支持以下目标: [待校准@5976]
这些是主要步骤: [待校准@5979]

接下来的部分将详细解释这些步骤中的每一个。要快速安装,请看一下 Automated Cross-compilation[待校准@5985]

注解

这些步骤在Ubuntu 18.04 (仿生) 上进行了测试 [待校准@5986]

1.安装开发版本工具 [待校准@5987]

此步骤类似于本机构建时。不同之处在于,一些库和工具不是必需的,因为它们将位于sysroot中。以下包需要 [待校准@5988]

sudo apt update && sudo apt install -y \
    cmake \
    git \
    wget \
    python3-pip \
    qemu-user-static \
    g++-aarch64-linux-gnu \
    g++-arm-linux-gnueabihf \
    pkg-config-aarch64-linux-gnu

python3 -m pip install -U \
    vcstool \
    colcon-common-extensions

注解

您可以通过pip安装vc凳和colcon-common-extension。这意味着您不需要添加额外的apt仓库。 [待校准@5989]

Docker用于构建目标环境。按照官方 documentation 进行安装。 [待校准@5990]

2.下载ROS 2源文件代码 [待校准@5991]

然后创建工作区并下载ROS 2源文件: [待校准@5992]

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 src < ros2.repos
git clone https://github.com/ros-tooling/cross_compile.git -b 0.0.1 src/ros2/cross_compile
cd ..

3.准备sysroot [待校准@5993]

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

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

ROS 2的标准 setup 进程在arm docker中运行。多亏了 qemu-static ,这才有可能,它将模拟一个手臂机器。使用的基本映像是来自Docker Hub的Ubuntu仿生。 [待校准@5995]

docker build -t arm_ros2:latest -f ros2_ws/src/ros2/cross_compile/sysroot/Dockerfile_ubuntu_arm .
docker run --name arm_sysroot arm_ros2:latest

将生成的容器导出到tarball并将其提取: [待校准@5996]

docker container export -o sysroot_docker.tar arm_sysroot
mkdir sysroot_docker
tar -C sysroot_docker -xf sysroot_docker.tar lib usr opt etc
docker rm arm_sysroot

稍后可以将此容器用作虚拟目标,以运行创建的文件系统并运行例程代码。 [待校准@5997]

4.建造 [待校准@5998]

设置通用工具链文件使用的变量 [待校准@5999]

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

以下包在交叉编译期间仍然会导致错误 (正在调查中),必须暂时禁用。 [待校准@6000]

touch \
    ros2_ws/src/ros2/rviz/COLCON_IGNORE \
    ros2_ws/src/ros-visualization/COLCON_IGNORE

预建的 Poco 有一个已知的问题,它在主机系统上搜索 libzlibpcre ,而不是SYSROOT。作为目前的解决方法,请将两个库链接到主机的文件系统中。 [待校准@6001]

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指定toolchain-file开始构建: [待校准@6002]

cd ros2_ws

colcon build --merge-install \
    --cmake-force-configure \
    --cmake-args \
        -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \
        -DCMAKE_TOOLCHAIN_FILE="$(pwd)/src/ros2/cross_compile/cmake-toolchains/generic_linux.cmake" \
        -DSECURITY=ON

成交!安装和构建目录将包含交叉编译的资产。 [待校准@6003]

自动交叉编译 [待校准@6004]

上述所有步骤也包含在Dockerfile中,可用于自动化/CI。 [待校准@6005]

首先,下载dockerfile并构建映像: [待校准@6006]

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

现在使用以下命令运行映像 :( 这需要一段时间!) [待校准@6007]

docker run -it --name ros2_cc \
    -v /var/run/docker.sock:/var/run/docker.sock \
    ros2-crosscompiler:latest

。。注意:-v /var/run/docker.sock允许我们在Docker中使用Docker。 [待校准@6008]

构建的结果将在 ros2_ws 目录中,该目录可以通过以下方式导出: [待校准@6009]

docker cp ros2_cc:/root/cc_ws/ros2_ws .

针对预构建的ROS 2进行交叉编译 [待校准@6010]

可以跨编译包对预建ROS 2步骤类似以前 Cross-compiling examples for Arm 型材,以下修改: [待校准@6011]

无需下载ROS 2堆栈,只需使用包 (本例中为ros2示例) 和交叉编译资产填充工作区: [待校准@6012]

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

生成和导出文件系统,如 3. Prepare the sysroot 中所述,但提供了 Dockerfile_ubuntu_arm64_prebuilt 。这些 _prebuilt Dockerfile将使用 binary packages 安装ROS 2,而不是从源文件构建。 [待校准@6013]

修改环境变量 ROS2_INSTALL_PATH 以指向安装目录: [待校准@6014]

export ROS2_INSTALL_PATH=~/cc_ws/sysroot_docker/opt/ros/crystal

在目标文件系统上获取 setup.bash 脚本: [待校准@6015]

source $ROS2_INSTALL_PATH/setup.bash

然后,开始建立 Colcon 指定 toolchain-file : [待校准@6016]

colcon build \
    --merge-install \
    --cmake-force-configure \
    --cmake-args \
        -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \
        -DCMAKE_TOOLCHAIN_FILE="$(pwd)/src/cross_compile/cmake-toolchains/generic_linux.cmake"

在目标上运行 [待校准@6017]

在目标上复制文件系统或使用先前构建的docker映像: [待校准@6018]

docker run -it --rm -v `pwd`/ros2_ws:/ros2_ws arm_ros2:latest

资源环境: [待校准@6019]

source /ros2_ws/install/local_setup.bash

运行一些C++ 或python示例: [待校准@6020]

ros2 run demo_nodes_cpp listener &
ros2 run demo_nodes_py talker