How to install the Raspberry Pi cross compiler on my Linux host machine?
Building for newer Raspbian Debian Buster images and ARMv6
The answer by @Stenyg only works for older Raspbian images. The recently released Raspbian based on Debian Buster requires an updated toolchain:
In Debian Buster the gcc compiler and glibc was updated to version 8.3. The toolchain in git://github.com/raspberrypi/tools.git
is still based on the older gcc 6 version. This means that using git://github.com/raspberrypi/tools.git
will lead to many compile errors.
This tutorial is based on @Stenyg answer. In addition to many other solutions in the internet, this tutorial also supports older Rasperry Pi (A, B, B+, Zero) based on the ARMv6 CPU. See also: GCC 8 Cross Compiler outputs ARMv7 executable instead of ARMv6
Set up the toolchain
There is no official git repository containing an updated toolchain (See https://github.com/raspberrypi/tools/issues/102).
I created a new github repository which includes building and precompiled toolchains for ARMv6 based on GCC8 and newer:
https://github.com/Pro/raspi-toolchain
As mentioned in the project's readme, these are the steps to get the toolchain. You can also build it yourself (see the README for further details).
- Download the toolchain:
wget https://github.com/Pro/raspi-toolchain/releases/latest/download/raspi-toolchain.tar.gz
- Extract it. Note: The toolchain has to be in
/opt/cross-pi-gcc
since it's not location independent.
sudo tar xfz raspi-toolchain.tar.gz --strip-components=1 -C /opt
You are done! The toolchain is now in
/opt/cross-pi-gcc
Optional, add the toolchain to your path, by adding:
export PATH=$PATH:/opt/cross-pi-gcc/bin
to the end of the file named ~/.bashrc
Now you can either log out and log back in (i.e. restart your terminal session), or run . ~/.bashrc
in your terminal to pick up the PATH
addition in your current terminal session.
Get the libraries from the Raspberry PI
To cross-compile for your own Raspberry Pi, which may have some custom libraries installed, you need to get these libraries onto your host.
Create a folder $HOME/raspberrypi
.
In your raspberrypi
folder, make a folder called rootfs
.
Now you need to copy the entire /lib
and /usr
directory to this newly created folder. I usually bring the rpi image up and copy it via rsync:
rsync -vR --progress -rl --delete-after --safe-links [email protected]:/{lib,usr,opt/vc/lib} $HOME/raspberrypi/rootfs
where 192.168.1.PI
is replaced by the IP of your Raspberry Pi.
Use CMake to compile your project
To tell CMake to take your own toolchain, you need to have a toolchain file which initializes the compiler settings.
Get this toolchain file from here: https://github.com/Pro/raspi-toolchain/blob/master/Toolchain-rpi.cmake
Now you should be able to compile your cmake
programs simply by adding this extra flag: -D CMAKE_TOOLCHAIN_FILE=$HOME/raspberrypi/pi.cmake
and setting the correct environment variables:
export RASPBIAN_ROOTFS=$HOME/raspberry/rootfs
export PATH=/opt/cross-pi-gcc/bin:$PATH
export RASPBERRY_VERSION=1
cmake -DCMAKE_TOOLCHAIN_FILE=$HOME/raspberry/Toolchain-rpi.cmake ..
An example hello world is shown here: https://github.com/Pro/raspi-toolchain/blob/master/build_hello_world.sh
I'm gonna try to write this as a tutorial for you so it becomes easy to follow.
NOTE: This tutorial only works for older raspbian images. For the newer Raspbian based on Debian Buster see the following how-to in this thread: https://stackoverflow.com/a/58559140/869402
Pre-requirements
Before you start you need to make sure the following is installed:
apt-get install git rsync cmake libc6-i386 lib32z1 lib32stdc++6
Let's cross compile a Pie!
Start with making a folder in your home directory called raspberrypi
.
Go in to this folder and pull down the ENTIRE tools folder you mentioned above:
git clone git://github.com/raspberrypi/tools.git
You wanted to use the following of the 3 ones, gcc-linaro-arm-linux-gnueabihf-raspbian
, if I did not read wrong.
Go into your home directory and add:
export PATH=$PATH:$HOME/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin
to the end of the file named ~/.bashrc
Now you can either log out and log back in (i.e. restart your terminal session), or run . ~/.bashrc
in your terminal to pick up the PATH
addition in your current terminal session.
Now, verify that you can access the compiler arm-linux-gnueabihf-gcc -v
. You should get something like this:
Using built-in specs.
COLLECT_GCC=arm-linux-gnueabihf-gcc
COLLECT_LTO_WRAPPER=/home/tudhalyas/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/../libexec/gcc/arm-linux-gnueabihf/4.7.2/lto-wrapper
Target: arm-linux-gnueabihf
Configured with: /cbuild/slaves/oort61/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.b
uild/src/gcc-linaro-4.7-2012.08/configure --build=i686-build_pc-linux-gnu --host=i686-build_pc-
linux-gnu --target=arm-linux-gnueabihf --prefix=/cbuild/slaves/oort61/crosstool-ng/builds/arm-l
inux-gnueabihf-raspbian-linux/install --with-sysroot=/cbuild/slaves/oort61/crosstool-ng/builds/
arm-linux-gnueabihf-raspbian-linux/install/arm-linux-gnueabihf/libc --enable-languages=c,c++,fo
rtran --disable-multilib --with-arch=armv6 --with-tune=arm1176jz-s --with-fpu=vfp --with-float=
hard --with-pkgversion='crosstool-NG linaro-1.13.1+bzr2458 - Linaro GCC 2012.08' --with-bugurl=
https://bugs.launchpad.net/gcc-linaro --enable-__cxa_atexit --enable-libmudflap --enable-libgom
p --enable-libssp --with-gmp=/cbuild/slaves/oort61/crosstool-ng/builds/arm-linux-gnueabihf-rasp
bian-linux/.build/arm-linux-gnueabihf/build/static --with-mpfr=/cbuild/slaves/oort61/crosstool-
ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static --with-mpc
=/cbuild/slaves/oort61/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-
gnueabihf/build/static --with-ppl=/cbuild/slaves/oort61/crosstool-ng/builds/arm-linux-gnueabihf
-raspbian-linux/.build/arm-linux-gnueabihf/build/static --with-cloog=/cbuild/slaves/oort61/cros
stool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static --wi
th-libelf=/cbuild/slaves/oort61/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-linux/.build/a
rm-linux-gnueabihf/build/static --with-host-libstdcxx='-L/cbuild/slaves/oort61/crosstool-ng/bui
lds/arm-linux-gnueabihf-raspbian-linux/.build/arm-linux-gnueabihf/build/static/lib -lpwl' --ena
ble-threads=posix --disable-libstdcxx-pch --enable-linker-build-id --enable-plugin --enable-gol
d --with-local-prefix=/cbuild/slaves/oort61/crosstool-ng/builds/arm-linux-gnueabihf-raspbian-li
nux/install/arm-linux-gnueabihf/libc --enable-c99 --enable-long-long
Thread model: posix
gcc version 4.7.2 20120731 (prerelease) (crosstool-NG linaro-1.13.1+bzr2458 - Linaro GCC 2012.08
)
But hey! I did that and the libs still don't work!
We're not done yet! So far, we've only done the basics.
In your raspberrypi
folder, make a folder called rootfs
.
Now you need to copy the entire /lib
and /usr
directory to this newly created folder. I usually bring the rpi image up and copy it via rsync:
rsync -rl --delete-after --safe-links [email protected]:/{lib,usr} $HOME/raspberrypi/rootfs
where 192.168.1.PI
is replaced by the IP of your Raspberry Pi.
Now, we need to write a cmake
config file. Open ~/home/raspberrypi/pi.cmake
in your favorite editor and insert the following:
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_VERSION 1)
SET(CMAKE_C_COMPILER $ENV{HOME}/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-gcc)
SET(CMAKE_CXX_COMPILER $ENV{HOME}/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-g++)
SET(CMAKE_FIND_ROOT_PATH $ENV{HOME}/raspberrypi/rootfs)
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
Now you should be able to compile your cmake
programs simply by adding this extra flag: -D CMAKE_TOOLCHAIN_FILE=$HOME/raspberrypi/pi.cmake
.
Using a cmake hello world example:
git clone https://github.com/jameskbride/cmake-hello-world.git
cd cmake-hello-world
mkdir build
cd build
cmake -D CMAKE_TOOLCHAIN_FILE=$HOME/raspberrypi/pi.cmake ../
make
scp CMakeHelloWorld [email protected]:/home/pi/
ssh [email protected] ./CMakeHelloWorld