Compilation croisée

Pour des informations générales sur la compilation croisée, consultez article conceptuel.

Ce document vous fournit des détails sur la façon de compiler de manière croisée la pile logicielle ROS 2 ainsi que des exemples de compilation croisée vers des systèmes basés sur les cœurs Arm.

outil cross_compile

Les instructions d’utilisation de l’outil se trouvent dans le package cross_compile.

Instructions de l’ancien outil

Note

Suivez les étapes ci-dessous uniquement si vous utilisez l’ancienne version (version 0.0.1) de l’outil de compilation croisée . À toutes autres fins, suivez la documentation du package cross_compile.

Bien que ROS 2 soit une pile logicielle riche avec un certain nombre de dépendances, il utilise principalement deux types de packages différents :
  • Logiciel basé sur Python, qui ne nécessite aucune compilation croisée.

  • Logiciel basé sur CMake, qui fournit un mécanisme pour effectuer une compilation croisée.

De plus, la pile logicielle ROS 2 est construite avec Colcon qui fournit un mécanisme pour transmettre les paramètres à l’instance CMake utilisée pour la construction individuelle de chaque package/bibliothèque qui fait partie de la distribution ROS 2.

Lors de la construction native de ROS 2, le développeur doit télécharger toutes les dépendances (par exemple, Python et d’autres bibliothèques) avant de compiler les packages qui font partie de la distribution ROS 2. Lors de la compilation croisée, la même approche est requise. Le développeur doit d’abord disposer du système de fichiers du système cible avec toutes les dépendances déjà installées.

Les sections suivantes de ce document expliquent en détail l’utilisation de cmake-toolchains et de CMAKE_SYSROOT fonctionnalité pour cross-compiler ROS 2.

Fichier de chaîne d’outils CMake

Un fichier de chaîne d’outils CMake est un fichier qui définit des variables pour configurer CMake pour la compilation croisée. Les entrées de base sont :

  • CMAKE_SYSTEM_NAME : la plate-forme cible, par ex. Linux

  • CMAKE_SYSTEM_PROCESSOR : l’architecture cible, par ex. aarch64 ou arm

  • CMAKE_SYSROOT : le chemin vers le système de fichiers cible

  • CMAKE_C_COMPILER : le compilateur croisé C, par ex. aarch64-linux-gnu-gcc

  • CMAKE_CXX_COMPILER : le compilateur croisé C++, par ex. aarch64-linux-gnu-g++

  • CMAKE_FIND_ROOT_PATH : un chemin alternatif utilisé par la commande find_* pour trouver le système de fichiers

Lors de la compilation croisée de ROS 2, les options suivantes doivent être définies :

  • CMAKE_FIND_ROOT_PATH : le chemin alternatif utilisé par la commande find_*, utilisez-le pour spécifier le chemin vers le dossier ROS 2 /install

  • CMAKE_FIND_ROOT_PATH_MODE_* : la stratégie de recherche pour le programme, le paquet, la bibliothèque et l’inclusion, généralement : `` NEVER`` (regardez sur l’hôte-fs), `` ONLY`` (regardez sur sysroot) et `` BOTH`` (regarde à la fois sur sysroot et host-fs)

  • PYTHON_SOABI : le nom d’index des bibliothèques python générées par ROS 2, par ex. cpython-36m-aarch64-linux-gnu

  • THREADS_PTHREAD_ARG "0" CACHE STRING "Résultat de TRY_RUN" FORCE : force le résultat de la commande TRY_RUN à 0 (succès) car les binaires ne peuvent pas s’exécuter sur le système hôte.

Le fichier de chaîne d’outils est fourni à CMake avec le paramètre -DCMAKE_TOOLCHAIN_FILE=path/to/file. Cela définira également la variable CMAKE_CROSSCOMPILING sur true qui peut être utilisée par le logiciel en cours de construction.

Le CMAKE_SYSROOT est particulièrement important pour ROS 2 car les packages ont besoin de nombreuses dépendances (par exemple python, openssl, opencv, poco, eigen3, …). Définir CMAKE_SYSROOT sur un système de fichiers cible avec toutes les dépendances installées dessus permettra à CMake de les trouver lors de la compilation croisée.

Note

Vous pouvez trouver plus d’informations sur la page CMake documentation.

Lors du téléchargement du code source ROS 2, un fichier de chaîne d’outils générique est disponible dans le référentiel ros-tooling/cross_compile/cmake-toolchains qui peut être téléchargé séparément . D’autres exemples d’utilisation peuvent être trouvés dans la section Exemples de compilation croisée pour Arm.

Système de fichiers cible

Comme mentionné précédemment, ROS 2 nécessite différentes bibliothèques qui doivent être fournies pour la compilation croisée.

Il existe plusieurs façons d’obtenir le système de fichiers :
  • télécharger une image pré-construite

  • installer les dépendances sur la cible et exporter le système de fichiers (par exemple avec sshfs)

  • en utilisant qemu + docker (ou chroot) pour générer le système de fichiers sur la machine hôte.

Note

Vous pouvez trouver des informations sur l’utilisation de Docker + qemu dans la prochaine section « Exemples de compilation croisée pour Arm ».

Processus de construction

Le processus de construction est similaire à la compilation native. La seule différence est un argument supplémentaire à Colcon pour spécifier le toolchain-file :

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

Le toolchain-file fournit à CMake les informations du cross-compiler et du target file-system. Colcon appellera CMake avec le fichier de chaîne d’outils donné sur chaque paquet de ROS 2.

Exemples de compilation croisée pour Arm

Après téléchargement du code source ROS 2, vous pouvez ajouter des ressources de compilation croisée à l’espace de travail via git clone https://github.com/ ros-tooling/cross_compile.git -b 0.0.1 src/ros2/cross_compile. Ce sont des exemples de travail sur la façon de compiler de manière croisée pour les cœurs Arm.

Les cibles suivantes sont prises en charge :
  • Ubuntu-arm64 : à utiliser avec n’importe quel système basé sur ARMv8-A.

  • Ubuntu-armhf : à utiliser avec tout système moderne basé sur ARMv7-A.

Voici les principales étapes :
  • Installation des outils de développement

  • Téléchargement du code source ROS 2

  • Téléchargement des assets de compilation croisée ROS 2

  • Préparation de la racine système

  • Compilation croisée de la pile logicielle ROS 2

Les sections suivantes expliquent en détail chacune de ces étapes. Pour une configuration rapide, jetez un œil à la compilation croisée automatisée.

Note

Ces étapes ont été testées sur un Ubuntu 18.04 (Bionic)

1. Installer les outils de développement

Cette étape est similaire à la construction native. La différence est que certaines bibliothèques et certains outils ne sont pas nécessaires car ils se trouveront plutôt dans le sysroot. Les packages suivants sont requis

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

Note

Vous pouvez installer vcstool et colcon-common-extensions via pip. Cela signifie que vous n’êtes pas obligé d’ajouter des référentiels apt supplémentaires.

Docker est utilisé pour créer l’environnement cible. Suivez la documentation officielle pour l’installation.

2. Téléchargez le code source de ROS 2

Créez ensuite un espace de travail et téléchargez le code source de 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. Préparez la racine système

Construisez une image arm Ubuntu avec toutes les dépendances ROS 2 en utilisant Docker et qemu : Copiez le binaire qemu-static dans l’espace de travail. Il sera utilisé pour installer les dépendances ROS 2 sur le système de fichiers cible avec docker.

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

Le processus standard setup de ROS 2 est exécuté dans un docker arm. Ceci est possible grâce à qemu-static, qui émulera une machine à bras. L’image de base utilisée est une Ubuntu Bionic de Docker Hub.

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

Exportez le conteneur résultant dans une archive tar et extrayez-le :

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

Ce conteneur peut être utilisé ultérieurement comme cible virtuelle pour exécuter le système de fichiers créé et exécuter le code de démonstration.

4. Construire

Définir les variables utilisées par le fichier de chaîne d’outils générique

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

Les packages suivants provoquent toujours des erreurs lors de la compilation croisée (en cours d’investigation) et doivent être désactivés pour le moment.

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

Le pré-construit Poco a un problème connu où il recherche libz et libpcre sur le système hôte au lieu de SYSROOT. Comme solution de contournement pour le moment, veuillez lier les deux bibliothèques au système de fichiers de l’hôte.

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

Ensuite, démarrez une construction avec colcon en spécifiant le fichier de chaîne d’outils :

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

Fait! Les répertoires d’installation et de construction contiendront les actifs compilés de manière croisée.

Compilation croisée automatisée

Toutes les étapes ci-dessus sont également incluses dans un Dockerfile et peuvent être utilisées pour l’automatisation/CI.

Tout d’abord, téléchargez le dockerfile et créez l’image :

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

Maintenant lancez l’image avec : (ça va prendre du temps !)

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

..note :: Le -v /var/run/docker.sock nous permet d’utiliser Docker dans Docker.

Le résultat de la construction se trouvera dans le répertoire ros2_ws, qui peut être exporté avec :

docker cp ros2_cc:/root/cc_ws/ros2_ws .

Compilation croisée avec un ROS 2 pré-construit

Il est possible de cross-compiler vos packages avec un ROS 2 pré-construit. Les étapes sont similaires à la section précédente Exemples de compilation croisée pour Arm, avec les modifications suivantes :

Au lieu de télécharger la pile ROS 2, remplissez simplement votre espace de travail avec votre package (exemples ros2 dans ce cas) et les ressources de compilation croisée :

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 ..

Générez et exportez le système de fichiers comme décrit dans 3. Préparez le sysroot, mais avec le Dockerfile_ubuntu_arm64_prebuilt fourni. Ces Dockerfile _prebuilt utiliseront les packages binaires pour installer ROS 2 au lieu de compiler à partir des sources.

Modifiez la variable d’environnement ROS2_INSTALL_PATH pour qu’elle pointe vers le répertoire d’installation :

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

Sourcez le script setup.bash sur le système de fichiers cible :

source $ROS2_INSTALL_PATH/setup.bash

Ensuite, démarrez une compilation avec Colcon en spécifiant le 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"

Courir sur la cible

Copiez le système de fichiers sur votre cible ou utilisez l’image docker précédemment construite :

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

Source l’environnement :

source /ros2_ws/install/local_setup.bash

Exécutez certains des exemples C++ ou Python :

ros2 run demo_nodes_cpp listener &
ros2 run demo_nodes_py talker