Package: ros-cross-compile
Notice: This repository is deprecated. It is outdated and will not be supported anymore.It is recommended to use a native cross-compilation method, which can be up to 8 times faster.
See details in this ROS Discourse discussion:https://discourse.ros.org/t/call-for-help-maintainership-of-the-ros-cross-compile-tool/26511ROS / ROS 2 Cross Compile ToolA tool to automate compiling ROS and ROS 2 workspaces to non-native architectures.:construction:ros_cross_compilerelies on running emulated builds
using QEmu, #69 tracks progress toward enabling cross-compilation.Supported targetsThis tool supports compiling a workspace for all combinations of the following:Architecture:armhf,aarch64,x86_64ROS DistroROS:melodic,noeticROS 2:foxy,galactic,humble,rollingOS:Ubuntu,DebianNOTE: ROS 2 supports Debian only as a Tier 3 platform.
This means that there are notaptrepositories available for the ROS 2 Core on this platform.
Because of that, when targeting Debian for a ROS 2 workspace, you must also include the source for the core as well.
It is recommended to use a release branch ofros2.reposfromhttps://github.com/ros2/ros2to do so, rather thanmaster, so that you are not affected by development branch bugs and API changes.Supported hostsThis tool officially supports running on the following host systems.
Note that many others likely work, but these are being thoroughly tested.Ubuntu 20.04 FocalOSX MojaveInstallationPrerequisitesThis tool requires that you have already installedDockerFollow the instructions to add yourself to thedockergroup as well, so you can run containers as a non-root userPython 3.7 or higherIf you are using a Linux host, you must also install QEmu (Docker for OSX performs emulation automatically):sudoapt-getinstallqemu-user-staticInstalling ros_cross_compileTo install the stable release,pip3installros_cross_compileIf you would like the latest nightly build, you can get it from Test PyPIpip3install--index-urlhttps://test.pypi.org/simple/ros_cross_compileHow it works, high levelCollect dependenciesCreate a Docker image that hasrosdepRun therosdepimage against your target workspace to output a script that describes how to install its dependenciesCreate "sysroot image" that has everything needed for building target workspaceUse a base image for the target architecture (aarch64, armhf, ...)Install build tools (compilers, cmake, colcon, etc)Run the dependency installer script collected in Step 1 (if dependency list hasn't changed since last run, this uses the Docker cache)BuildRuns the "sysroot image" using QEmu emulationcolcon build(Optional) Create runtime imageCreates a docker image that can be used on the target platform to run the build. See "Runtime Image" section.UsageThis package installs theros_cross_compilecommand.
The command's first argument is the path to your ROS workspace.Here is a simple invocation for a standard workflow.ros_cross_compile/path/to/my/workspace--archaarch64--osubuntu--rosdistrofoxyFor information on all available options, runros_cross_compile -h.
See the following sections for information on the more complex options.Package Selection and Build CustomizationTo choose which packages to install dependencies for, this tool runscolcon liston your workspace.
To build, it runscolcon build.You can provide arbitrary arguments to these commands via thecolcondefaults.yaml.You can either specify the name of this file viaros_cross_compile --colcon-defaults /path/to/defaults.yaml, or if not specified, a file calleddefaults.yamlwill be used if present.For example, there are repositories checked out in your workspace that contain packages that are not needed for your application - some repos provide many packages and you may only want one!
In this scenario there is a "bringup" package that acts as the entry point to your application:# my_workspace/defaults.yamllist:# only install dependencies for source packages that my package depends onpackages-up-to:[my_application_bringup]build:# only build up to my packagepackages-up-to:[my_application_bringup]# example of a boolean commandline argumentmerge-install:trueOther configurations can be passed and used as command line args. Examples are CMake build arguments, like the build type or the verb configurations for the event handlers:# my_workspace/defaults.yamlbuild:cmake-args:["-DCMAKE_BUILD_TYPE=Release"]event-handlers:["console_direct+"]Custom rosdep scriptYour ROS application may need nonstandard rosdep rules.
If so, you have the option to provide a script to be run before therosdep installcommand collects keys.This script has access to the "Custom data directory" same as the "Custom setup script", see the following sections. If you need any extra files for setting up rosdep, they can be accessed via this custom data directory.Note that:Rosdeps for melodic collected in an Ubuntu focal container for all other ROS distros
rosdeps collected in an Ubuntu Focal container, so scripts must be compatible with thatHere is an example script for an application that adds extra rosdep source listscp./custom-data/rosdep-rules/raspicam-node.yaml/etc/ros/rosdep/custom-rules/raspicam-node.yamlecho"yaml file:/etc/ros/rosdep/custom-rules/raspicam-node.yaml">/etc/ros/rosdep/sources.list.d/22-raspicam-node.listTool invocation for this example:ros_cross_compile/path/to/my/workspace--archaarch64--osubuntu\--custom-rosdep-script/path/to/rosdep-script.sh\--custom-data-dir/arbitrary/local/directoryCustom setup scriptYour ROS application may have build needs that aren't covered byrosdep install.
If this is the case (for example you need to add extra apt repos), use the option--custom-setup-scriptto execute arbitrary code in the sysroot container.The path provided may be absolute, or relative to the current directory.Keep in mindIt's up to the user to determine whether the script is compatible with chosen base platformMake sure to specify non-interactive versions of commands, for exampleapt-get install -y, or the script may hang waiting for inputYou cannot make any assumptions about the state of the apt cache, so runapt-get updatebefore installing packagesThe script runs as root user in the container, so you don't needsudoBelow is an example script for an application that installs some custom Raspberry Pi libraries.apt-getupdate
apt-getinstall-ysoftware-properties-common# Install Raspberry Pi library that we have not provided a rosdep rule foradd-apt-repositoryppa:rpi-distro/ppa
apt-getinstall-ypigpioAdditionally, a custom setup script may control the build environment by populating the/custom-data/setup.bashfile which will be sourced before building.Custom post-build scriptYou may want to perform arbitrary post-processing on your build outputs, in the event of a sucessful build - use--custom-post-build-scriptfor this.
Keep in mind that it is run at the root of the built workspace.Following is an example setup that allows a user to runcolcon bundleto create a portable bundle of the cross-compiled application.Here are the contents of./postbuild.sh#!/bin/bashset-eux

apt-getupdate
apt-getinstall-ywget
wgethttp://packages.osrfoundation.org/gazebo.key-O-|apt-keyadd-

apt-getinstall-ypython3-apt
pip3install-usetuptoolspip
pip3install-Ucolcon-ros-bundle

colconbundle\--build-basebuild_"${TARGET_ARCH}"\--install-baseinstall_"${TARGET_ARCH}"\--bundle-basebundle_"${TARGET_ARCH}"Now, runros_cross_compile /path/to/my/workspace --arch aarch64 --os ubuntu \
  --custom-post-build-script ./postbuild.shAfter the build completes, you should see the bundle outputs inbundle_aarch64Custom data directoryYour custom setup or rosdep script (see preceding sections) may need some data that is not otherwise accessible.
For example, you need to copy some precompiled vendor binaries to a specific location, or provide custom rosdep rules files.
For this use case, you can use the option--custom-data-dirto point to an arbitrary path.
The sysroot build copies this directory into the build environment, where it's available for use by your custom setup script at./custom-data/.Example:Custom data directory (/arbitrary/local/directory)/arbitrary/local/directory/
+-- my-data/
|   +-- something.txtSetup Script (/path/to/custom-setup.sh)#!/bin/bashcatcustom-data/something.txtTool invocation:ros_cross_compile/path/to/my/workspace--archaarch64--osubuntu\--custom-setup-script/path/to/custom-setup.sh\--custom-data-dir/arbitrary/local/directoryNow, during the sysroot creation process, you should see the contents ofsomething.txtprinted during the execution of the custom script.NOTE: for trivial text files, as in the preceding example, you could have created those files fully within the--custom-setup-script. But for large or binary data such as precompiled libraries, this feature comes to the rescue.Runtime Imageros_cross_compilecan optionally create and tag a Docker image that contains the build output and its runtime dependencies.The argument--runtime-tagtakes a single value, which is the tag used for the output image.OUTPUT_IMAGE=my_registry/image_name:image_tag
ros_cross_compile $workspace --runtime-tag $OUTPUT_IMAGEOne way to deploy this image is to push it to a registry, from where it can be pulled onto a target platformdocker push $OUTPUT_IMAGEThe image contains any necessary emulation binaries to run locally if desired for smoke testing.docker run -it $OUTPUT_IMAGE
# In the shell inside the running container, the setup is already sourced for the default entrypoint
ros2 launch my_package my.launch.pyNote: Currently this feature is a thin layer on top of the image used for building, so it is not a fully minimal image - it contains build tools, build dependencies, and test dependencies in addition to the necessary runtime dependencies.
Future work is planned to slim down this output image to a properly minimal runtime.
This work is tracked inhttps://github.com/ros-tooling/cross_compile/issues/263.TutorialFor a new user, this section walks you through a representative use case, step by step.This tutorial demonstrates how to cross-compile theROS 2 Demo Nodesagainst ROS 2 Foxy, to run on an ARM64 Ubuntu system.
You can generalize this workflow to use on any workspace for your project.NOTE: this tutorial assumes a Debian-based (including Ubuntu) Linux distribution as the host platform.Creating a simple source workspaceCreate a directory for your workspace and checkout the sourcesmkdir -p cross_compile_ws/src
cd cross_compile_ws
git clone -b foxy https://github.com/ros2/demos src/demosCreate a filedefaults.yamlin this directory with the following contents. This file narrows down the set of built packages, rather than building every single package in the source repository. This file is optional - see preceding section "Package Selection and Build Customization
" for more information.build:
  # only build the demo_nodes_cpp package, to save time building all of the demos
  packages-up-to:
    - demo_nodes_cpp
  # make a merged install space, which is easier to distribute
  merge-install: true
  # add some output for readability
  event-handlers:
    - console_cohesion+
    - console_package_list+Running the cross-compilationros_cross_compile.--rosdistrofoxy--archaarch64--osubuntu--colcon-defaults./defaults.yamlHere is a detailed look at the arguments passed to the script (ros_cross_compile -hwill print all valid choices for each option):.The first argument toros_cross_compileis the directory of the workspace to be built. This could be any relative or absolute path, in this case it's just., the current working directory.--rosdistro foxyYou may specify either a ROS and ROS 2 distribution by name, for examplenoetic(ROS) orgalactic(ROS 2).--arch aarch64Target the ARMv8 / ARM64 / aarch64 architecture (which are different names for effectively the same thing).--os ubuntuThe target OS is Ubuntu - the tool chooses the OS version automatically based on the ROS Distro's target OS. In this case for ROS 2 Foxy - Ubuntu 20.04 Focal Fossa.Outputs of the buildRun the following commandlscross_compile_wsIf the build succeeded, the directory looks like this:build_aarch64/
cc_internals/
defaults.yaml
install_aarch64/
log/
src/The created directoryinstall_aarch64is the installation of your ROS workspace for your target architecture.cc_internalsis used byros_cross_compileto cache artifacts between builds - as a user you will not need to inspect itYou can verify that the build created binaries for the target architecture (note "ARM aarch64" in below output. Yoursha1may differ):$fileinstall_aarch64/demo_nodes_cpp/lib/demo_nodes_cpp/talker
install_aarch64/demo_nodes_cpp/lib/demo_nodes_cpp/talker:ELF64-bitLSBsharedobject,ARMaarch64,version1(SYSV),dynamicallylinked,interpreter/lib/ld-linux-aarch64.so.1,BuildID[sha1]=f086db477d6f5f919414d63911366077f1051b80,forGNU/Linux3.7.0,notstrippedUsing the build on a target platformCopyinstall_aarch64onto the target system into a location of your choosing. It contains the binaries foryourworkspace.If your workspace has any dependencies that are outside the source tree - that is, ifrosdephad anything to install during the build - then you still need to install these dependencies on the target system.Note first: if you needrosdepto install packages via the package manager, then your system will need its package manager sources (APT for Ubuntu). SeeSetup Sourcesportion of ROS 2 installation instructions for an example of how to do this on Ubuntu.# Run this on the target system, which must have rosdep already installed# remember `rosdep init`, `rosdep update`, `apt-get update` if you need themrosdepinstall--from-pathsinstall_aarch64/share--ignore-src--rosdistrofoxy-yNow you may use the ROS installation as you would on any other systemsourceinstall_aarch64/setup.bash
ros2rundemo_nodes_cpptalker# and in a different shellros2rundemo_nodes_cpplistenerTroubleshootingIf you are running in docker with/var/run/docker.sockmounted and see the following error:No src/ directory found at /ws, did you remember to mount your workspace?You may need to try running in docker-in-docker. This approach is demonstrated to work in gitlab-ci with a privileged runner and the followinggitlab.ymlas an example:image:teracy/ubuntu:18.04-dind-19.03.3services:-docker:19.03.3-dindvariables:# Disable TLS or we get SSLv1 errors. We shouldn't need this since we mount the /certs volume.# We also need to connect to the docker daemon via DOCKER_HOST.DOCKER_TLS_CERTDIR:""DOCKER_HOST:tcp://docker:2375build-stuff:stage:buildtags:-rosbefore_script:# Install packages-apt update-apt install -qq -y qemu-user-static python3-pip rsync# Set up the workspace-cd ${CI_PROJECT_DIR}/..-rm -rf cross_compile_ws/src-mkdir -p cross_compile_ws/src-cp -r ${CI_PROJECT_DIR} cross_compile_ws/src/-rsync -a ${CI_PROJECT_DIR}/../cross_compile_ws ${CI_PROJECT_DIR}-cd ${CI_PROJECT_DIR}# Install ros_cross_compile-pip3 install ros_cross_compilescript:-ros_cross_compile cross_compile_ws --arch aarch64 --os ubuntu --rosdistro melodicartifacts:paths:-$CI_PROJECT_DIR/cross_compile_ws/install_aarch64expire_in:1 weekLicenseThis library is licensed under the Apache 2.0 License.Build statusROS 2 ReleaseBranch NameDevelopmentSource Debian PackageX86-64 Debian PackageARM64 Debian PackageARMHF Debian packageLatestmasterN/AN/AN/AN/AFoxyfoxy-develN/AN/A