Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Asoragna/ubuntu arm64 #3

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 45 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,35 @@ The supported architectures are:

## Requirements

- Docker

If you don't have Docker installed follow [this link](../docker_setup.md).
Ensure that you have support for building and running ARM Docker containers.

Install some other dependencies
This tool requires a Linux-based OS.
It is tested only on Ubuntu 20.04, other distributions may or may not work.

- Install Docker following official instructions https://docs.docker.com/desktop/install/linux-install/
- Manage Docker as non-root user (log out and log back in after running the commands)
```
sudo groupadd docker
sudo usermod -aG docker $USER
```
- Install qemu dependencies
```
sudo apt-get update && sudo apt-get install qemu binfmt-support qemu-user-static
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes --credential yes
docker run --rm -t arm64v8/ubuntu uname -m
```
- Install additional minor requirements
```
sudo apt-get update && sudo apt-get install -y curl gnupg2 lsb-release software-properties-common
sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null
sudo apt-get update && sudo apt-get install -y python3-vcstool wget
```

## Build the Framework

```
sudo apt update && sudo apt install -y curl gnupg2 lsb-release software-properties-common
curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add -
sudo apt update && sudo apt install -y python3-vcstool wget
bash build.sh
```

## Build

bash build.sh

This will build the cross-compilation framework.
It mainly consists of a bunch of `Dockerfile`s which provide a Docker environment with all the cross-compilation dependencies installed for each of the supported architectures.

Expand All @@ -65,15 +77,19 @@ Let's go through an example showing how to manually cross-compile ROS 2 Foxy SDK

Source the environment variables for this architecture using

source env.sh raspbian
```
source env.sh raspbian
```

Create a sysroot for the architecture.
This command will download a sysroot for the archicture specified by the `TARGET_ARCHITECTURE` environment variable (the argument passed to the `env.sh` script above, `raspbian` in this case).
Note that if you already have a sysroot with the same name inside the `sysroots` directory, it will be overwritten by the new one.

If you want to use your own sysroot, instead of generating a new one, you can skip the last instruction and just place your sysroot in the `sysroots` directory. Your sysroot directory must be renamed to `raspbian` or as the specified `TARGET_ARCHITECTURE` that you passed to `env.sh`.

bash get_sysroot.sh
```
bash get_sysroot.sh
```

Create a ROS 2 workspace that you want to cross-compile.
- The cross-compilation script will mount the workspace as a Docker volume. This does not go well with symbolic links. For this reason ensure that the workspace contains the whole source code and not a symlink to the repositories.
Expand All @@ -82,26 +98,34 @@ Create a ROS 2 workspace that you want to cross-compile.
We provide convenient scripts for downloading the ROS 2 sources for a specific distribution.
If you want to cross-compile generic ROS 2 packages, see the [advanced section](advanced.md).

bash get_ros2_sources.sh --distro=foxy --ros2-path=~/ros2_cc_ws
```
bash get_ros2_sources.sh --distro=foxy --ros2-path=~/ros2_cc_ws
```

Cross-compile the workspace

bash cc_workspace.sh ~/ros2_cc_ws
```
bash cc_workspace.sh ~/ros2_cc_ws
```

The result of the cross-compilation will be found in `~/ros2_cc_ws/install`.

#### Debug options

If you are runing the compilation steps one by one, you can also add a debug flag to the last command:

bash cc_workspace.sh ~/ros2_cc_ws --debug
```
bash cc_workspace.sh ~/ros2_cc_ws --debug
```

This will let you go inside the Docker container used for compilation rather than starting the compilation process.
Once you are inside you can start building using any of the following scripts, depending on your target architecture:

/root/compilation_scripts/compile.sh
/root/compilation_scripts/cross_compile.sh

```
/root/compilation_scripts/compile.sh
/root/compilation_scripts/cross_compile.sh
```

Running in this debug mode also allows you to easily modify these scripts.
Common modifications are the following:
- Comment the line at the beginning where it clears the build directory.
Expand Down
3 changes: 2 additions & 1 deletion automatic_cross_compile.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# TARGET=[raspbian]

# Set env variables
ROS2_DISTRO="${ROS2_DISTRO:=master}"
ROS2_DISTRO="${ROS2_DISTRO:=rolling}"

# Check that all variables are defined before start
if [[ -z "$TARGET" ]]
Expand Down Expand Up @@ -70,6 +70,7 @@ vcs export --exact $WORKSPACE_DIR/src > $ROS2_SRCS_HEADS
CC_CMD="bash $THIS_DIR/cc_workspace.sh $WORKSPACE_DIR --no-it"
if ! $CC_CMD; then
echo "Error: the cross-compilation step failed"
rm -rf $RESULTS_DIR
exit 1
fi

Expand Down
11 changes: 7 additions & 4 deletions build.sh
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
#!/bin/bash

THIS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"

DOCKER_ENVS_DIR=${THIS_DIR}/docker_environments

# build the cross compilation base docker image
docker build -t ros2_cc_base -f docker_environments/Dockerfile_base .
docker build -t ros2_cc_base -f ${DOCKER_ENVS_DIR}/Dockerfile_base ${THIS_DIR}

prefix="docker_environments/Dockerfile_"
prefix="${DOCKER_ENVS_DIR}/Dockerfile_"

# Build all the other dockerfiles in the docker_environments directory
for dockerfile_name in docker_environments/*
for dockerfile_name in ${DOCKER_ENVS_DIR}/*
do
# Check this is a Dockerfile (i.e. it starts with the prefix)
if [[ $dockerfile_name != $prefix* ]]; then
Expand All @@ -21,4 +25,3 @@ do
docker build -t ros2_cc_$platform_name -f $dockerfile_name .
fi
done

2 changes: 1 addition & 1 deletion cc_workspace.sh
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ else
fi

INTERACTIVE_DOCKER_ARG="-it"
COMMAND=(/bin/bash -c "source /root/.bashrc && bash $COMPILATION_SCRIPT")
COMMAND=(/bin/bash -c "bash $COMPILATION_SCRIPT")

for i in "$@"
do
Expand Down
2 changes: 2 additions & 0 deletions compilation_scripts/compile.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## script for compiling the current workspace

source /root/.bashrc

# clear out everything first
rm -rf build install log

Expand Down
20 changes: 19 additions & 1 deletion compilation_scripts/cross_compile.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,20 @@
## accepts as argument the path to the toolchain file to be used
## if no argument is provided, it looks for a default toolchain in the current directory.

source /root/.bashrc

if [ -z "$1" ]; then
TOOLCHAIN_PATH=`pwd`/toolchainfile.cmake
echo "Using toolchain ${TOOLCHAIN_PATH}"
else
TOOLCHAIN_PATH=$1
fi

# this is needed to avoid https://stackoverflow.com/questions/72978485
git config --global --add safe.directory '*'

# clear out everything first
rm -rf build install log
#rm -rf build install log
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is temporarily commented out, but I want to add a command line option to enable/disable it


ROS2_SETUP=/root/sysroot/setup.bash
if [ -f "$ROS2_SETUP" ]; then
Expand All @@ -24,11 +29,24 @@ if [ -f "$ARCH_SPECIFIC_TOOLCHAIN" ]; then
source $ARCH_SPECIFIC_TOOLCHAIN
fi

# Note: maybe these should be set from the toolchain CMake file, but it didn't work
PYTHON_LIBRARY_ARG=""
if [ ! -z ${PYTHON_LIBRARY} ]; then
PYTHON_LIBRARY_ARG="-DPYTHON_LIBRARY=${PYTHON_LIBRARY}"
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to set these flags from the toolchain.cmake file, but it didn't work...
this is not nice but it works

echo "Using python library ${PYTHON_LIBRARY_ARG}"
fi
PYTHON_INCLUDE_DIR_ARG=""
if [ ! -z ${PYTHON_INCLUDE_DIR} ]; then
PYTHON_INCLUDE_DIR_ARG="-DPYTHON_INCLUDE_DIR=${PYTHON_INCLUDE_DIR}"
echo "Using python include ${PYTHON_INCLUDE_DIR_ARG}"
fi

COLCON_CMD="colcon \
build \
--merge-install \
--cmake-force-configure \
--cmake-args \
${PYTHON_LIBRARY_ARG} ${PYTHON_INCLUDE_DIR_ARG} \
-DCMAKE_TOOLCHAIN_FILE=$TOOLCHAIN_PATH \
-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON \
-DTHIRDPARTY=ON \
Expand Down
20 changes: 11 additions & 9 deletions docker_environments/Dockerfile_base
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

FROM ubuntu:18.04
FROM ubuntu:20.04
LABEL maintainer="Alberto Soragna asoragna at irobot dot com"

# working directory
Expand Down Expand Up @@ -35,21 +35,23 @@ ENV LANG en_US.UTF-8

# Setup sources
RUN apt-get update && apt-get install -y curl gnupg2 lsb-release
RUN curl http://repo.ros2.org/repos.key | apt-key add -
RUN sh -c 'echo "deb [arch=amd64,arm64] http://repo.ros2.org/ubuntu/main `lsb_release -cs` main" > /etc/apt/sources.list.d/ros2-latest.list'
RUN apt-get update
RUN curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg
RUN echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | tee /etc/apt/sources.list.d/ros2.list > /dev/null

# install development tools and ROS tools
RUN apt-get update && apt-get install -y \
build-essential \
cmake \
python3-colcon-common-extensions \
python-rosdep \
python3-pip
python3-rosdep \
python3-pip \
python3-dev \
python3-numpy \
ros-dev-tools

RUN pip3 install -U \
argcomplete \
git+https://github.com/lark-parser/lark.git@0.7d \
git+https://github.com/lark-parser/lark.git \
importlib-resources


Expand All @@ -59,7 +61,7 @@ RUN pip3 install -U \
# These packages are required when cross-compiling additional packages once the sysroot already contains the ROS2 SDK
# add the sysroot python modules to PYTHONPATH
RUN echo ' \n\
export PYTHONPATH=/root/sysroot/usr/lib/python3.6/site-packages/:$PYTHONPATH' >> $HOME/.bashrc
export PYTHONPATH=/root/sysroot/usr/lib/python3.10/site-packages/:$PYTHONPATH' >> $HOME/.bashrc

# TODO: here there is a terrible hack.
# we have problems when a package depends both on ROS2 SDK and on Python.
Expand All @@ -70,4 +72,4 @@ RUN echo ' \n\
export AMENT_PREFIX_PATH="/root/sysroot/usr;/root/sysroot/usr/bin"' >> $HOME/.bashrc

# copy the compilation scripts into the docker image
COPY compilation_scripts $HOME/compilation_scripts
COPY compilation_scripts $HOME/compilation_scripts
8 changes: 2 additions & 6 deletions docker_environments/Dockerfile_raspbian
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,14 @@
FROM ros2_cc_base
LABEL maintainer="Alberto Soragna asoragna at irobot dot com"


###### INSTALL ROS2 REQUIREMENTS

# TODO: numpy should be installed on the RaspberryPi sysroot (Python3.6 version) but pip and build from sources fail
RUN pip3 install -U \
numpy


###### INSTALL RASPBIAN CROSS-COMPILATION REQUIREMENTS

# install gcc6 compiler and toolchain
# install g++ arm compiler
RUN apt-get update && apt-get install -y \
gcc-6 \
g++-6 \
g++-6-arm-linux-gnueabihf
g++-arm-linux-gnueabihf
7 changes: 7 additions & 0 deletions docker_environments/Dockerfile_ubuntu_arm64
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

FROM ros2_cc_base
LABEL maintainer="Alberto Soragna asoragna at irobot dot com"

# install g++ aarch64 compiler
RUN apt-get update && apt-get install -y \
g++-aarch64-linux-gnu
16 changes: 16 additions & 0 deletions get_sources/ubuntu_arm64/humble/get_sources.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/bash

if [[ $# -ne 1 ]]; then
echo "Illegal number of parameters. Required to specify path."
exit 1
fi


THIS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
WORKSPACE_DIR_PATH="$1"

# Download sources
REPOS_FILE_PATH="$THIS_DIR/ros2.repos"

cd $WORKSPACE_DIR_PATH
vcs import src < $REPOS_FILE_PATH
Loading