Build cross compile toolchain for Raspberry Pi 5 on (K)Ubuntu 22.04

In order to cross compile the libraries or applications for Raspberry Pi5 on the computers with different architecture we need a cross-compiler toolchain (gcc, libc, binutils and so on). However, it is not enough if you are building, for example, an application which requires the third-party libraries. In such a case we have to provide gcc with a directory (–sysroot=dir option) that works as a root for headers and libraries of the Raspberry Pi 5 root file system.
I will build it for the last Raspbian OS release (2024-03-12-raspios-bookworm-arm64-full.img) on (and for) Kubuntu 22.04 platform.

1. Build cross-compiler toolhain

To build a cross compiler toolchain (gcc-12.2.0, glibc, binutils and so on) I have used the script which is based on the build script from Slackware AArch64 cross-compiler script. To see the build script click here…
If you are going to build the cross compile toolchain you need to change the install directory variable in the building script.

2. Build a Rapberry Pi 5 “sysroot” by using “mk-sbuild” tool

2.1. Setting up the Development Machine

dev@ku22$sudo apt install build-essential ubuntu-dev-tools cmake curl git

2.2. Import the necessary keys into the GNU Privacy Guard (GPG)

dev@ku22$wget -qO- https://ftp-master.debian.org/keys/archive-key-11.asc | gpg --import -

2.3. Create a minimal RPI5 file system

dev@ku22$$HOME/.mk-sbuild.rc < mk-sbuild --arch=arm64 bookworm --debootstrap-keyring "$HOME/.gnupg/pubring.kbx" --debootstrap-mirror=http://deb.debian.org/debian
--name rpi-bookworm

If everything is OK then you will find the just generated file system under
${HOME}/rpi5-sysroot/rpi-bookworm-arm64 directory.

Now if you need to install some libraries from the Debian repository you should use the “sbuild-apt” command. For example, to install “libjpeg-dev”and “libpng-dev” libraries I used the next command (from ${HOME}/rpi5-sysroot):

dev@ku22$sudo sbuild-apt rpi-bookworm-arm64 apt-get install libjpeg-dev libpng-dev

3. Configure QtCreator for using Raspberry Pi 5 cross compiler

By this time you should be able to ssh from your host machine (running Qt Creator) into your Raspberry Pi 5 board. If you are not able to do so, please check your network connectivity before proceeding any further!

3.1. Create new Linux-based device associated with Raspberry Pi5 from the “Preferences – Qt Creator” form (Devices tab).

(more details at: https://doc.qt.io/qtcreator/creator-how-to-find-preferences.html )

3.2. Create Raspberry Pi 5 development kit

(more details at: https://doc.qt.io/qtcreator/creator-how-to-add-custom-compilers.html)
Note 1: on tab “Compilers” specify the C/C++ compiler path as:
${HOME}/cross-gcc-rpi5/bin/aarch64-linux-gcc
${HOME}/cross-gcc-rpi5/bin/aarch64-linux-g++
Note 2: on tab “Kit” specify the sysroot path as:
/rpi-bookworm-arm64

4. Using Cmake tool to build from the command line

A variable CMAKE_TOOLCHAIN_FILE is specified on the command line when cross-compiling with CMake. It is the path to a file which contains locations for compilers and toolchain utilities, and other target platform and compiler related information.
I use “rpi5-toolchain.cmake” file which has the next contents:

set( CMAKE_SYSTEM_NAME Linux )
# target architecture
set( CMAKE_SYSTEM_PROCESSOR armv8)

# define sysroot path for RPI5 distribution
set( CMAKE_SYSROOT ${HOME}/rpi5-sysroot/rpi-bookworm-arm64 )
set( TOOLCHAIN_DIR ${HOME}/cross-gcc-rpi5/bin )
set( CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})

# define the cross compiler locations
set( CMAKE_C_COMPILER ${TOOLCHAIN_DIR}/aarch64-linux-gcc )
set( CMAKE_CXX_COMPILER ${TOOLCHAIN_DIR}/aarch64-linux-g++ )
set( CMAKE_LINKER ${TOOLCHAIN_DIR}/aarch64-linux-ld )
set( CMAKE_AR ${TOOLCHAIN_DIR}/aarch64-linux-ar )
set( CMAKE_OBJCOPY ${TOOLCHAIN_DIR}/aarch64-linux-objcopy )
set( CMAKE_STRIP ${TOOLCHAIN_DIR}/aarch64-linux-strip )

# use our definitions for compiler tools
set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER )

# search for libraries and headers in the target directory only
set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY )
set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY )
set( CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY )

Below is a simple bash script that I used for building C MQTT PAHO library and where a variable “CMAKE_TOOLCHAIN_FILE” is used.

#!/bin/sh
C_VER=v1.3.13
RPI5_SYSROOT=$HOME/rpi5-sysroot/rpi-bookworm-arm64
TOOLCHAIN_FILE=$HOME/cross-gcc-rpi5/toolchain-rpi5.cmake
export PATH=$HOME/cross-gcc-rpi5/bin:$HOME/cross-gcc-rpi5/aarch64-linux/bin:$PATH
BDIR=$PWD
mkdir -p "$BDIR"/paho
mkdir -p "$BDIR"/build
cd "$BDIR"/paho
git clone https://github.com/eclipse/paho.mqtt.c.git
cd "$BDIR"/paho/paho.mqtt.c
git checkout tags/"$C_VER"
cd "$BDIR"/build<br>
cmake -DPAHO_BUILD_STATIC=TRUE \
    -DCMAKE_TOOLCHAIN_FILE="$TOOLCHAIN_FILE" \
    -DCMAKE_INSTALL_PREFIX:PATH=/usr \
    "$BDIR"/paho/paho.mqtt.c || { echo "config error"; exit 1; }
cmake --build . --config Release || { echo "build error"; exit 1; }
cmake --install . || { echo "install error"; exit 1; }
echo "Done"
exit 0