交叉编译 [207]
目录 []
本文档为您提供有关如何交叉编译ROS 2软件栈的详细信息,以及提供基于Arm核心的系统的交叉编译示例。 [209]
交叉编译工具 [210]
使用该工具的说明在 cross_compile package 中。 [211]
传统工具说明 [212]
注解
只有在使用旧版本(发布版 0.0.1)的交叉编译工具时才按照以下步骤操作。对于其他情况,请参考 cross_compile 包文档。 [213]
- 尽管ROS 2是一个具有多个依赖项的丰富软件堆栈,但它主要使用两种不同类型的软件包: [214]
此外,ROS 2 软件栈使用 Colcon 构建,它提供了一种机制,可以将参数传递给用于构建 ROS 2 发行版中每个包/库的单独构建的 CMake 实例。 [217]
在本地构建 ROS 2 时,开发人员需要在编译 ROS 2 发行版中的包之前下载所有的依赖项(例如 Python 和其他库)。在交叉编译时,也需要相同的方法。开发人员必须首先拥有目标系统的文件系统,并已安装所有的依赖项。 [218]
本文档的后续部分详细说明了使用 cmake-toolchains 和 CMAKE_SYSROOT 功能进行 ROS 2 交叉编译的方法。 [219]
CMake 工具链文件 [220]
CMake工具链文件是用于配置CMake进行交叉编译的文件,它定义了变量。基本条目如下: [221]
在进行ROS 2交叉编译时,需要设置以下选项: [228]
CMAKE_FIND_ROOT_PATH
:``find_*``命令使用的替代路径,用于指定ROS 2 ``/install``文件夹的路径 [229]
CMAKE_FIND_ROOT_PATH_MODE_*
:程序、包、库和包含文件的搜索策略,通常有:``NEVER``(在主机文件系统上查找)、``ONLY``(在sysroot上查找)和``BOTH``(在sysroot和主机文件系统上都查找) [230]
PYTHON_SOABI
:由ROS 2生成的Python库的索引名称,例如``cpython-36m-aarch64-linux-gnu`` [231]
THREADS_PTHREAD_ARG "0" CACHE STRING "Result from TRY_RUN" FORCE
:将``TRY_RUN``命令的结果强制为0(成功),因为二进制文件无法在主机系统上运行。 [232]
将工具链文件提供给CMake时,使用``-DCMAKE_TOOLCHAIN_FILE=path/to/file``参数。这还将把``CMAKE_CROSSCOMPILING``变量设置为``true``,软件构建时可以使用该变量。 [233]
对于ROS 2来说,``CMAKE_SYSROOT``非常重要,因为软件包需要许多依赖项(例如python、openssl、opencv、poco、eigen3等)。将``CMAKE_SYSROOT``设置为安装了所有依赖项的目标文件系统,将允许CMake在交叉编译过程中找到它们。 [234]
在下载ROS 2源代码时,存储库`ros-tooling/cross_compile/cmake-toolchains <https://github.com/ros-tooling/cross_compile>`__中提供了一个通用的工具链文件,可以单独下载。有关如何使用它的更多示例,请参阅`Cross-compiling examples for Arm`_部分。 [236]
目标文件系统 [237]
如前所述,ROS 2需要不同的库文件来进行交叉编译。 [238]
- 获取文件系统有多种方式: [239]
注解
您可以在接下来的`Cross-compiling examples for Arm`_部分找到有关如何使用Docker + qemu的信息。 [243]
构建过程 [244]
构建过程类似于本地编译,唯一的区别是给 Colcon
添加了一个额外的参数来指定 toolchain-file
: [245]
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。 [246]
为 Arm 进行交叉编译示例 [247]
在 下载 ROS 2 源代码 后,您可以通过 git clone https://github.com/ros-tooling/cross_compile.git -b 0.0.1 src/ros2/cross_compile
将交叉编译资产添加到工作空间。这些是关于如何为 Arm 内核进行交叉编译的可行示例。 [248]
下面的章节详细解释了每个步骤。如果需要快速设置,请参阅`Automated Cross-compilation`_。 [258]
注解
这些步骤在Ubuntu 18.04(Bionic)上进行了测试 [259]
1. 安装开发工具 [260]
这个步骤与本地构建类似。不同之处在于一些库和工具不需要,因为它们将在sysroot中。需要以下软件包: [261]
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仓库。 [262]
2. 下载ROS 2源代码 [264]
然后创建一个工作空间并下载ROS 2源代码: [265]
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 [266]
使用Docker和qemu构建带有所有ROS 2依赖项的arm Ubuntu镜像:将``qemu-static``二进制文件复制到工作空间。它将用于使用Docker在目标文件系统上安装ROS 2依赖项。 [267]
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。 [268]
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文件并解压缩: [269]
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
此容器稍后可用作虚拟目标,以运行创建的文件系统和运行演示代码。 [270]
4. 构建 [271]
设置通用工具链文件使用的变量 [272]
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
以下软件包在交叉编译过程中仍然导致错误(正在调查中),现在必须禁用它们。 [273]
touch \
ros2_ws/src/ros2/rviz/COLCON_IGNORE \
ros2_ws/src/ros-visualization/COLCON_IGNORE
预构建的 Poco
存在一个已知问题,它在主机系统上搜索 libz
和 libpcre
而不是 SYSROOT。暂时的解决方法是,请将这两个库链接到主机的文件系统中。 [274]
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 指定工具链文件启动构建: [275]
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
完成!安装目录和构建目录将包含交叉编译的资源。 [276]
自动交叉编译 [277]
上述所有步骤也包含在一个Dockerfile中,可以用于自动化/持续集成。 [278]
首先,下载Dockerfile并构建镜像: [279]
wget https://raw.githubusercontent.com/ros-tooling/cross_compile/master/Dockerfile_cc_for_arm
docker build -t ros2-crosscompiler:latest - < Dockerfile_cc_for_arm
现在运行镜像:(这将需要一些时间!) [280]
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。 [281]
构建的结果将在 ros2_ws
目录中,可以使用以下命令导出: [282]
docker cp ros2_cc:/root/cc_ws/ros2_ws .
针对预构建的 ROS 2 进行交叉编译 [283]
您可以将您的软件包与预构建的 ROS 2 进行交叉编译。步骤与之前的“为 ARM 进行交叉编译示例”_ 部分相似,只需进行以下修改: [284]
不需要下载ROS 2堆栈,只需将您的软件包(在此示例中是ros2 examples)和交叉编译资产填充到您的工作空间中: [285]
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,而不是从源代码构建。 `[286]
修改环境变量``ROS2_INSTALL_PATH``,指向安装目录: [287]
export ROS2_INSTALL_PATH=~/cc_ws/sysroot_docker/opt/ros/crystal
在目标文件系统上调用``setup.bash``脚本: [288]
source $ROS2_INSTALL_PATH/setup.bash
然后,使用``Colcon``指定``toolchain-file``来开始构建: [289]
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"