How to cross-compile ROS2 for arm64 architecture

Another question is about the statement in https://github.com/ros2/ros2/tree/master/arm_crosscompilation

No target filesystem with Python libraries is provided here, so Python is not supported (only C++).

Does that mean if I could get a ‘rootfs’ working for aarch64 I may enable python support?

Yes, I did that earlier with an arm64 Ubuntu 16.04 rootfs and it was working fine with a simple python publisher.

Yes, that’s exactly what GitHub - esteve/ros2_raspbian_tools: Tools for crosscompiling ROS2 for the Raspberry Pi does to cross compile ROS2 for the Raspberry Pi. The scripts in the repo fetch a Raspbian image and prepare a rootfs so that CMake will find all the dependencies and compile/link against them.

The scripts in GitHub - esteve/ros2_raspbian_tools: Tools for crosscompiling ROS2 for the Raspberry Pi are generic enough that they can be adapted to cross-compile for aarch64, let me have a look at it and I’ll flesh them out. What’s your target aarch64 distribution? Ubuntu?

I am working on Jetson TX2 board, which has Ubuntu 16.04 arm64 installed. I think I can ‘rsync’ to fetch back the rootfs and try to cross-compile against.

I am not family with ‘polly’ and ‘docker’ but ‘ros2_raspbian_tools’ looks pretty good. If it could work with any rootfs rather than raspbain only that will be great.

Hmmmm, if it is about a python publish, will it work with ‘multiarch’ enabled Ubuntu box. What I am trying to do is about to install ‘libpython3-dev:arm64’ package for python dev headers and libs. However, it seems ‘ament’ cannot find them in ‘/usr/include’ or ‘/usr/lib’.

Yeah, you’ll need python3-dev:arm64 because it contains the pkgconfig files for Python3 that ament uses to “discover” the location of the Python headers and libraries.

The instructions in https://github.com/ros2/ros2/tree/master/arm_crosscompilation use the changes I made to ROS2 to cross-compile it for Android and iOS (i.e. Removed Boost and ported to C++11. Added support for Android and iOS by esteve · Pull Request #26 · eProsima/Fast-DDS · GitHub, https://github.com/ros2/rmw_fastrtps/pull/27 and a bunch of others). But if you want to target a Linux distro, it’s best to use a rootfs instead since you’ll end up with a complete ROS2 environment, I’m going to update the guide in the wiki to reflect that.

To setup the python support, I used an already created ubuntu-base:
http://cdimage.ubuntu.com/ubuntu-base/releases/16.04/release/ubuntu-base-16.04.1-base-arm64.tar.gz

And then I installed the needed packages using chroot + qemu-aarch64-static

In the toolchain file I used the variable CMAKE_SYSROOT to specify the path of my rootfs to ament/cmake and compile.

Thank you, @esteve and @pokitoz. I got cross-compilation done for Jetson TX2.

Here is a brief for who is interesting on this.

    set(CMAKE_SYSTEM_NAME Linux)
    set(CMAKE_SYSTEM_VERSION 1)
    set(CMAKE_SYSTEM_PROCESSOR aarch64)
    set(CMAKE_SYSROOT $ENV{SYSROOT})
    # specify the cross compiler
    set(CMAKE_C_COMPILER $ENV{CROSS_COMPILE}gcc)
    set(CMAKE_CXX_COMPILER $ENV{CROSS_COMPILE}g++)
    # where is the target environment
    set(CMAKE_FIND_ROOT_PATH ${CMAKE_CURRENT_LIST_DIR}/install)
    set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
    set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
    set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
    set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

    # This assumes that pthread will be available on the target system
    # (this emulates that the return of the TRY_RUN is a return code "0"
    set(THREADS_PTHREAD_ARG "0"
      CACHE STRING "Result from TRY_RUN" FORCE)
  • Apt ‘sources.list’
    deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ xenial main restricted
    #deb-src [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ xenial main restricted
    deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main restricted
    #deb-src [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ xenial-updates main restricted
    deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted
    #deb-src [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ xenial-security main restricted
  • Install ‘libpython3-dev:arm64’

  • Ignore ‘rviz’ and ‘opencv’ related packages

    src/ament/ament_tools/scripts/ament.py build \
        --force-cmake-configure \
        --skip-packages resource_retriever \
                        rviz_assimp_vendor \
                        rviz_ogre_vendor \
                        rviz_yaml_cpp_vendor \
                        rviz_rendering \
                        rviz_rendering_tests \
                        rviz_common \
                        rviz2 \
                        rviz_default_plugins \
        --cmake-args \
            -DCMAKE_TOOLCHAIN_FILE=`pwd`/aarch64_toolchainfile.cmake \
            -DTHIRDPARTY=ON \
            -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \
            -DPYTHON_INCLUDE_DIR=$(python3 -c "from distutils.sysconfig import get_python_inc; print(get_python_inc() + ';' + '/usr/include')") \
            -DPYTHON_LIBRARY=$(python3 -c "import distutils.sysconfig as sysconfig; print(sysconfig.get_config_var('LIBDIR'))")/aarch64-linux-gnu/libpython3.5m.so --
1 Like

Hi jcadam, esteve,

I try to reproduce the cross-compilation of the complete stack and get some issue during the process.
I try to follow esteve approach with docker to build the rootfs based on a arm64v8 ubuntu docker image. The cmake used is similar to the one above, and I’m using esteve “build_ros2.bash” script to trigger the build.
During the process, I got the following error:
fatal error: Eigen/Core: No such file or directory
#include <Eigen/Core>

CMake ignore the manually specified location : “DEIGEN3_INCLUDE_DIR=”${RASPBERRYPI_CROSS_COMPILE_SYSROOT}/usr/include/eigen3"
and use the default “/usr/include” path:
– Using Eigen3 include dirs: /usr/include/eigen3

I’m struggling to understand why CMake ignore the specified path… Any idea ?

Hi…i am a new user here. As per my knowledge the 64-bit ARM environment is relatively new. This means that most applications, including ROS, need to be ported to the new processor. For a complicated application like ROS, this may necessitate a variety of code and environment changes to support the new computer architecture.

board assembly

Hi ChesLans,

There is no issue to build ROS2 for aarch64. You can follow the wiki instruction on your aarch64 machine and build the complete stack, it will just take some time =)
For cross-compilation, you can build a subset of ROS2 by following the instruction here.
@jcadam and @esteve already have successfully cross-compile the complete ROS2 for raspi (arm 32) and the Jetson TX2 (arm 64).

FYI to the community, none of the above mentioned approaches work with the release of Crystal without a good deal of digging into the scripts to address moved or added dependencies like python-catkin-pkg-modules, and others. At least I haven’t been able to find a working solution…so I’m going at it from scratch. As soon as I have it, I’ll post.

1 Like

Hi @binary42,

A new documentation page just get merged explaining how to achieve cross-compilation of the Crystal release, based on the assets available at ros2/cross_compile

Please let me know if you have any issue with it !

It sounds like you have achieved building the ROS2 libs for Android. Unfortunately, the first link is dead. Can you pleas point me to the latest documentation to this topic.

I don’t know which link you’re referring to, could you be more specific? Thanks.

I am trying to build ros2 foxy fitzroy on the google coral dev board with an aarch64 which runs mendel linux (derivative of debian 10 buster) which is supported as trier3. I have managed to build ros melodic on the coral itself, but I’m constantly failing to build foxy fitzroy.

I would like to try cross-compilation, but I don’t know where to start. Does anyone has any ideas?

The link https://github.com/ros2/ros2/tree/master/arm_crosscompilation is dead unfortunately.

You could probably take a look at ros-tooling/cross_compile.

For future questions, you might want to post an issue on their tracker or post on ROS Answers.

Hello, after successfully cross-compiling ROS2 foxy base in a Google Coral running Mendel (based on Debian 10 buster) I am able to successfully build packages, but when I need to include the rclcpp package in the CMakeLists.txt to build the package in the ROS2 tutorials, it fails because of trace tools dependency. I have tried removing trace tools, as I understand it is not necessary but apparently the talker executable needs it… has anyone encountered something similar or solved this in any way? Thank you in advance!

answers.ros.org is more appropriate for this kind of question. I see you’ve posted there already, so I’ll try to help you out over there :smiley:

1 Like