Sitemap

Building an AArch64 Toolchain for Raspberry Pi 4 with crosstool-NG

5 min readSep 20, 2026

--

My step-by-step journey building an AArch64 cross-compilation toolchain for Raspberry Pi 4 with crosstool-NG on Ubuntu 24.04 LTS.

Press enter or click to view image in full size
AI-generated illustration. Unfortunately, crosstool-NG does not actually look this cool.

Table of Contents

Prerequisites

All steps in this article were tested using the following host and target hardware.

Host PC
OS: Ubuntu 24.04 LTS (64-bit)
CPU: AMD Ryzen 5 4500U
RAM: 12 GB
Architecture: x86_64

Target Board
Board:
Raspberry Pi 4 Model B
SoC: Broadcom BCM2711
CPU: Quad-core ARM Cortex-A72
Architecture: ARMv8-A (AArch64)
RAM: 2 GB
Target OS: Raspberry Pi OS 64-bit

Note: The host PC specifications above are not strict requirements. They simply describe the machine I used to build the toolchain.

First, install the required packages using:

sudo apt-get install autoconf automake bison bzip2 cmake flex g++ gawk gcc \
gettext git gperf help2man libncurses5-dev libstdc++6 libtool \
libtool-bin make patch python3-dev rsync texinfo unzip wget xz-utils

Building crosstool-NG

In your workspace, clone the current crosstool-NG Git repository and check out the latest release. At the time of writing, I am using crosstool-ng-1.29.0.

git clone https://github.com/crosstool-ng/crosstool-ng.git
cd crosstool-ng
git checkout crosstool-ng-1.29.0

Prepare the crosstool-NG source tree with bootstrap, check the build environment, and generate the Makefiles and configuration with configure.

Then build and install it:

./bootstrap
./configure --prefix="${PWD}" # Install into the current directory
make
make install

We can now use bin/ct-ng to configure and build our toolchain.

Building a Toolchain for Raspberry Pi 4

Run the following command to see the available target samples:

./bin/ct-ng list-samples

There are quite a few samples, so filtering the output with grep makes it easier to find the Raspberry Pi 4 targets:

./bin/ct-ng list-samples | grep rpi4

Example output:

[L...]   aarch64-rpi4-linux-gnu
[L...] armv8-rpi4-linux-gnueabihf
L (Local) : sample was found in current directory
G (Global) : sample was installed with crosstool-NG
X (EXPERIMENTAL): sample may use EXPERIMENTAL features
B (BROKEN) : sample is currently broken
O (OBSOLETE) : sample needs to be upgraded

I am using a Raspberry Pi 4 Model B, which has a quad-core Cortex-A72 (ARMv8-A) 64-bit SoC.

Therefore, I chose:

aarch64-rpi4-linux-gnu

The armv8-rpi4-linux-gnueabihf target is intended for a 32-bit ARM userspace using the hard-float ABI.

Note: In the AArch64 execution state used by 64-bit ARMv8-A systems, floating-point and SIMD support are part of the architecture. Therefore, there is no separate hf/hard-float toolchain naming convention like the one commonly seen with 32-bit ARM toolchains.

If a sample for your board is not available, you may be able to start with a generic target that closely matches the architecture and then customize its configuration.

Get IceJ’s stories in your inbox

Join Medium for free to get updates from this writer.

For example, for a 64-bit ARM Linux target, I might start with:

aarch64-unknown-linux-gnu

I have not tested this configuration with the Raspberry Pi 4, however.

Inspecting the sample configuration

We can inspect a sample configuration by adding the show- prefix:

./bin/ct-ng show-aarch64-rpi4-linux-gnu

Example output:

[L...]   aarch64-rpi4-linux-gnu
Languages : C,C++
OS : linux-7.1
Binutils : binutils-2.47
Compiler : gcc-16.2.0
Linkers :
C library : glibc-2.44
Debug tools : gdb-17.2
Companion libs : expat-2.7.1 gettext-0.26 gmp-6.3.0 isl-0.27
libiconv-1.18 mpc-1.3.1 mpfr-4.2.2 ncurses-6.5
zlib-1.3.1 zstd-1.5.7
Companion tools :

Next, select the Raspberry Pi 4 sample:

./bin/ct-ng aarch64-rpi4-linux-gnu

Example output:

CONF  aarch64-rpi4-linux-gnu
#
# configuration written to .config
#
***********************************************************Initially reported by: Bensuperpc <bensuperpc@gmail.com>
URL: https://github.com/Bensuperpc
Comment:
Raspberry PI 4 aarch64
***********************************************************Now configured for "aarch64-rpi4-linux-gnu"

This creates a .config file containing the toolchain configuration.

Customizing the configuration

Open the configuration menu:

./bin/ct-ng menuconfig

For my use case, I want to be able to modify the toolchain installation later — for example, to add additional libraries to its sysroot.

Therefore, I disable the Render the toolchain read-only option.

After saving the configuration, we are ready to build the toolchain.

./bin/ct-ng build

LD_LIBRARY_PATH sanity-check error

During my first build attempt, I encountered the following sanity-check error:

[INFO ]  Performing some trivial sanity checks
[ERROR] Don't set LD_LIBRARY_PATH. It screws up the build.

In my case, LD_LIBRARY_PATH had been set by my ROS 2 Jazzy environment.

crosstool-NG intentionally rejects this because LD_LIBRARY_PATH can cause host libraries to be loaded unexpectedly during the toolchain build.

I removed it from the current shell environment and started the build again:

unset LD_LIBRARY_PATH
./bin/ct-ng build

On my computer, the complete build took approximately 37 minutes:

[INFO ]  Build completed at 20260920.120327
[INFO ] (elapsed: 37:25.94)

By default, the resulting toolchain was installed under:

~/x-tools/aarch64-rpi4-linux-gnu

The complete toolchain takes approximately 504 MB of disk space on my system.

Toolchain Is Ready

To make the toolchain commands easier to use, add its bin directory to PATH:

export PATH="$HOME/x-tools/aarch64-rpi4-linux-gnu/bin:$PATH"

You can verify that the tools are available with:

ls ~/x-tools/aarch64-rpi4-linux-gnu/bin/aarch64-rpi4-linux-gnu-*

Example output:

aarch64-rpi4-linux-gnu-addr2line
aarch64-rpi4-linux-gnu-ar
aarch64-rpi4-linux-gnu-as
aarch64-rpi4-linux-gnu-c++
aarch64-rpi4-linux-gnu-cc
aarch64-rpi4-linux-gnu-c++filt
aarch64-rpi4-linux-gnu-cpp
aarch64-rpi4-linux-gnu-elfedit
aarch64-rpi4-linux-gnu-g++
aarch64-rpi4-linux-gnu-gcc
aarch64-rpi4-linux-gnu-gcc-16.2.0
aarch64-rpi4-linux-gnu-gcc-ar
aarch64-rpi4-linux-gnu-gcc-nm
aarch64-rpi4-linux-gnu-gcc-ranlib
aarch64-rpi4-linux-gnu-gcov
aarch64-rpi4-linux-gnu-gcov-dump
aarch64-rpi4-linux-gnu-gcov-tool
aarch64-rpi4-linux-gnu-gdb
aarch64-rpi4-linux-gnu-gdb-add-index
aarch64-rpi4-linux-gnu-gprof
aarch64-rpi4-linux-gnu-gstack
aarch64-rpi4-linux-gnu-ld
aarch64-rpi4-linux-gnu-ld.bfd
aarch64-rpi4-linux-gnu-ldd
aarch64-rpi4-linux-gnu-lto-dump
aarch64-rpi4-linux-gnu-nm
aarch64-rpi4-linux-gnu-objcopy
aarch64-rpi4-linux-gnu-objdump
aarch64-rpi4-linux-gnu-populate
aarch64-rpi4-linux-gnu-ranlib
aarch64-rpi4-linux-gnu-readelf
aarch64-rpi4-linux-gnu-size
aarch64-rpi4-linux-gnu-strings
aarch64-rpi4-linux-gnu-strip

At this point, the Raspberry Pi 4 cross-compilation toolchain is ready to use.

For example:

aarch64-rpi4-linux-gnu-gcc --version
aarch64-rpi4-linux-gnu-g++ --version

These compilers can now be used to build AArch64 Linux applications for the Raspberry Pi 4 from the Ubuntu host machine.

What’s Next?

At this point, we have successfully built an AArch64 cross-compilation toolchain for the Raspberry Pi 4.

In the next article, I’ll take a closer look at the anatomy of a cross-compilation toolchain and explain what crosstool-NG actually generated.

References

This article was written based on my own toolchain-building experience, with additional guidance and background from the following resources:

--

--

IceJ
IceJ
0 followers

Learning Embedded Systems & Robotics - sharing what I learn along the way.