How to install the Raspberry Pi cross compiler on my Linux host machine?
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-gccCOLLECT_LTO_WRAPPER=/home/tudhalyas/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/../libexec/gcc/arm-linux-gnueabihf/4.7.2/lto-wrapperTarget: arm-linux-gnueabihfConfigured 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-longThread model: posixgcc 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 pi@192.168.1.PI:/{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-worldmkdir buildcd buildcmake -D CMAKE_TOOLCHAIN_FILE=$HOME/raspberrypi/pi.cmake ../makescp CMakeHelloWorld pi@192.168.1.PI:/home/pi/ssh pi@192.168.1.PI ./CMakeHelloWorld
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 pi@192.168.1.PI:/{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/rootfsexport PATH=/opt/cross-pi-gcc/bin:$PATHexport RASPBERRY_VERSION=1cmake -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 couldn't get the compiler (x64
version) to use the sysroot
until I added SET(CMAKE_SYSROOT $ENV{HOME}/raspberrypi/rootfs)
to pi.cmake
.