ros-tooling / cross_compile

A tool to build ROS and ROS2 workspaces for various targets
Apache License 2.0
188 stars 60 forks source link

Raspbian support #15

Closed alsora closed 5 years ago

alsora commented 5 years ago

This PR includes the previous https://github.com/ros2/cross_compile/pull/13.

Complete instructions for cross-compiling ROS2 for RaspberryPi

Build cross-compilation docker environment

docker build -t ros2-crosscompiler:latest - < Dockerfile_cc_for_arm

Generate sysroot

docker build -t raspbian_ros2:latest -f cross_compile/sysroot/Dockerfile_raspbian_arm .
docker create --name arm_sysroot raspbian_ros2
docker container export -o sysroot_docker.tar arm_sysroot
docker rm arm_sysroot
mkdir sysroot_docker
tar -C sysroot_docker -xf sysroot_docker.tar lib usr opt etc

Create ROS2 workspace

mkdir -p ws/src
cd ws
wget https://raw.githubusercontent.com/ros2/ros2/crystal/ros2.repos
vcs import src < ros2.repos

Ignore some packages

touch \
  ws/src/ros2/demos/COLCON_IGNORE \
  ws/src/ros2/rviz2/COLCON_IGNORE \
  ws/src/ros-visualization/COLCON_IGNORE

Add the toolchain to workspace

cp cmake-toolchains/generic_linux.cmake ws/

Create a Docker container and enter in it

docker run -it \
  -v sysroot_docker:/root/sysroot \
  -v ws:/root/ws \
  --entrypoint "" \
  -w="/root/ws" \
  ros2-crosscompiler:latest bash

Inside the Docker container

export TARGET_ARCH=armhf
export SYSROOT=/root/sysroot
export ROS2_INSTALL_PATH=/root/ws/install
export TARGET_TRIPLE=arm-linux-gnueabihf
export CROSS_COMPILE_C=$TARGET_TRIPLE-gcc-6
export CROSS_COMPILE_CXX=$TARGET_TRIPLE-g++-6
export TARGET_C_FLAGS="-Wl,-rpath-link=$ROS2_INSTALL_PATH/lib"
export TARGET_CXX_FLAGS="-Wl,-rpath-link=$ROS2_INSTALL_PATH/lib"
export PYTHON_SOABI=cpython-36m-$TARGET_TRIPLE

Then you can finally cross-compile

colcon \
    build \
    --merge-install \
    --cmake-force-configure \
    --executor sequential \
    --cmake-args \
    -DCMAKE_TOOLCHAIN_FILE=`pwd`/generic_linux.cmake \
    -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \
    -DTHIRDPARTY=ON \
    -DBUILD_TESTING:BOOL=OFF

Future work

If this works for everyone, I would proceed to automate it to have a single command for both raspberrypi and armv8.

christianrauch commented 5 years ago

To summarise, you are using two docker files: The Dockerfile_raspbian_arm to generate the Raspbian rootfs and Dockerfile_cc_for_arm for the actual compilation. Compiling within a Docker container virtualised with qemu has additional costs compared to "true" cross-compilation on a workstation without virtualisation. Using qemu virtualisation, the arm instructions form the compiler inside Docker need to be translated to the host architecture, adding overhead to the compile time. Having a true cross-compilation, that is running a compiler that generates target binaries on the host architecture, would be much faster. It would also reduce the dependency on Docker, since the rootfs could be generated once using Docker and reused for multiple cross-compilations on the host.

alsora commented 5 years ago

@christianrauch

This is just a first PR to enable Raspbian cross-compilation. My idea was that, after this gets merged, to update how cross-compilation works for all platforms.

The final idea would be to have:

With this first PR, I haven't removed qemu from the second Dockerfile, because I didn't want to break something in the already present ARM v8 cross-compilation, but rather only add support for Raspbian.

alsora commented 5 years ago

Closing this PR in favor of https://github.com/ros2/cross_compile/pull/18