交叉编译
有关交叉编译的背景信息,请参阅 概念文章。
本文档为您提供有关如何交叉编译ROS 2软件栈的详细信息,以及提供基于Arm核心的系统的交叉编译示例。
交叉编译工具
使用该工具的说明在 cross_compile package 中。
传统工具说明
注解
只有在使用旧版本(发布版 0.0.1)的交叉编译工具时才按照以下步骤操作。对于其他情况,请参考 cross_compile 包文档。
- 尽管ROS 2是一个具有多个依赖项的丰富软件堆栈,但它主要使用两种不同类型的软件包:
基于Python的软件,不需要进行交叉编译。
基于CMake的软件,提供了进行交叉编译的机制。
此外,ROS 2 软件栈使用 Colcon 构建,它提供了一种机制,可以将参数传递给用于构建 ROS 2 发行版中每个包/库的单独构建的 CMake 实例。
在本地构建 ROS 2 时,开发人员需要在编译 ROS 2 发行版中的包之前下载所有的依赖项(例如 Python 和其他库)。在交叉编译时,也需要相同的方法。开发人员必须首先拥有目标系统的文件系统,并已安装所有的依赖项。
本文档的后续部分详细说明了使用 cmake-toolchains 和 CMAKE_SYSROOT 功能进行 ROS 2 交叉编译的方法。
CMake 工具链文件
CMake工具链文件是用于配置CMake进行交叉编译的文件,它定义了变量。基本条目如下:
CMAKE_SYSTEM_NAME
:目标平台,例如``linux``
CMAKE_SYSTEM_PROCESSOR
:目标架构,例如``aarch64``或``arm``
CMAKE_SYSROOT
:目标文件系统的路径
CMAKE_C_COMPILER
:C交叉编译器,例如``aarch64-linux-gnu-gcc``
CMAKE_CXX_COMPILER
:C++交叉编译器,例如``aarch64-linux-gnu-g++``
CMAKE_FIND_ROOT_PATH
:``find_*``命令用来查找文件系统的替代路径
在进行ROS 2交叉编译时,需要设置以下选项:
CMAKE_FIND_ROOT_PATH
:``find_*``命令使用的替代路径,用于指定ROS 2 ``/install``文件夹的路径
CMAKE_FIND_ROOT_PATH_MODE_*
:程序、包、库和包含文件的搜索策略,通常有:``NEVER``(在主机文件系统上查找)、``ONLY``(在sysroot上查找)和``BOTH``(在sysroot和主机文件系统上都查找)
PYTHON_SOABI
:由ROS 2生成的Python库的索引名称,例如``cpython-36m-aarch64-linux-gnu``
THREADS_PTHREAD_ARG "0" CACHE STRING "Result from TRY_RUN" FORCE
:将``TRY_RUN``命令的结果强制为0(成功),因为二进制文件无法在主机系统上运行。
将工具链文件提供给CMake时,使用``-DCMAKE_TOOLCHAIN_FILE=path/to/file``参数。这还将把``CMAKE_CROSSCOMPILING``变量设置为``true``,软件构建时可以使用该变量。
对于ROS 2来说,``CMAKE_SYSROOT``非常重要,因为软件包需要许多依赖项(例如python、openssl、opencv、poco、eigen3等)。将``CMAKE_SYSROOT``设置为安装了所有依赖项的目标文件系统,将允许CMake在交叉编译过程中找到它们。
注解
您可以在CMake的 文档 页面上找到更多信息。
在下载ROS 2源代码时,存储库`ros-tooling/cross_compile/cmake-toolchains <https://github.com/ros-tooling/cross_compile>`__中提供了一个通用的工具链文件,可以单独下载。有关如何使用它的更多示例,请参阅`Cross-compiling examples for Arm`_部分。
目标文件系统
如前所述,ROS 2需要不同的库文件来进行交叉编译。
- 获取文件系统有多种方式:
下载预构建的映像
在目标设备上安装依赖项并导出文件系统(例如使用sshfs)
使用qemu + docker(或chroot)在主机上生成文件系统。
注解
您可以在接下来的`Cross-compiling examples for Arm`_部分找到有关如何使用Docker + qemu的信息。
构建过程
构建过程类似于本地编译,唯一的区别是给 Colcon
添加了一个额外的参数来指定 toolchain-file
:
colcon build --merge-install \
--cmake-force-configure \
--cmake-args \
-DCMAKE_TOOLCHAIN_FILE="<path_to_toolchain/toolchainfile.cmake>"
toolchain-file
提供给 CMake 有关 交叉编译器
和 目标文件系统
的信息。Colcon
将在 ROS 2 的每个软件包上使用给定的 toolchain-file 来调用 CMake。
为 Arm 进行交叉编译示例
在 下载 ROS 2 源代码 后,您可以通过 git clone 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 交叉编译资产
准备 sysroot
交叉编译ROS 2软件栈
下面的章节详细解释了每个步骤。如果需要快速设置,请参阅`Automated Cross-compilation`_。
注解
这些步骤在Ubuntu 18.04(Bionic)上进行了测试
1. 安装开发工具
这个步骤与本地构建类似。不同之处在于一些库和工具不需要,因为它们将在sysroot中。需要以下软件包:
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安装vcstool和colcon-common-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 src < ros2.repos
git clone https://github.com/ros-tooling/cross_compile.git -b 0.0.1 src/ros2/cross_compile
cd ..
3. 准备 sysroot
使用Docker和qemu构建带有所有ROS 2依赖项的arm Ubuntu镜像:将``qemu-static``二进制文件复制到工作空间。它将用于使用Docker在目标文件系统上安装ROS 2依赖项。
mkdir qemu-user-static
cp /usr/bin/qemu-*-static qemu-user-static
ROS 2的标准:doc:设置 <../Installation/Alternatives/Ubuntu-Development-Setup>`过程在arm docker内运行。这得益于``qemu-static`
,它将模拟一个arm机器。使用的基础镜像是来自Docker Hub的Ubuntu Bionic。
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文件并解压缩:
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
此容器稍后可用作虚拟目标,以运行创建的文件系统和运行演示代码。
4. 构建
设置通用工具链文件使用的变量
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
以下软件包在交叉编译过程中仍然导致错误(正在调查中),现在必须禁用它们。
touch \
ros2_ws/src/ros2/rviz/COLCON_IGNORE \
ros2_ws/src/ros-visualization/COLCON_IGNORE
预构建的 Poco
存在一个已知问题,它在主机系统上搜索 libz
和 libpcre
而不是 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 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
完成!安装目录和构建目录将包含交叉编译的资源。
自动交叉编译
上述所有步骤也包含在一个Dockerfile中,可以用于自动化/持续集成。
首先,下载Dockerfile并构建镜像:
wget https://raw.githubusercontent.com/ros-tooling/cross_compile/master/Dockerfile_cc_for_arm
docker build -t ros2-crosscompiler:latest - < Dockerfile_cc_for_arm
现在运行镜像:(这将需要一些时间!)
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。
构建的结果将在 ros2_ws
目录中,可以使用以下命令导出:
docker cp ros2_cc:/root/cc_ws/ros2_ws .
针对预构建的 ROS 2 进行交叉编译
您可以将您的软件包与预构建的 ROS 2 进行交叉编译。步骤与之前的“为 ARM 进行交叉编译示例”_ 部分相似,只需进行以下修改:
不需要下载ROS 2堆栈,只需将您的软件包(在此示例中是ros2 examples)和交叉编译资产填充到您的工作空间中:
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. 准备sysroot`_中所述的方法生成和导出文件系统,但使用提供的``Dockerfile_ubuntu_arm64_prebuilt``。这些``_prebuilt`` Dockerfile将使用:doc:`二进制包 <../Installation/Ubuntu-Install-Debians>`来安装ROS 2,而不是从源代码构建。
修改环境变量``ROS2_INSTALL_PATH``,指向安装目录:
export ROS2_INSTALL_PATH=~/cc_ws/sysroot_docker/opt/ros/crystal
在目标文件系统上调用``setup.bash``脚本:
source $ROS2_INSTALL_PATH/setup.bash
然后,使用``Colcon``指定``toolchain-file``来开始构建:
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"