In this tutorial, we will see what is a cross-compilation toolchain? we will see how to install an ARM cross-compilation toolchain to build an application for a target device on a host machine. Target devices can be ARM based boards such as Raspberry Pi, BeagleBone, etc. But installation and use of cross-compilation tools chain are generic. That means you can follow these steps to build an application on the Host machine for all ARM based development boards.
Introduction to Cross Compilation Tool chain
A toolchain consists of a compiler and its related utilities. It is used to compile and generate Linux Kernel, drivers, root file system, bootloader, and application for the target hardware such as Raspberry Pi, Beaglebone, etc. In other words, a toolchain, which runs on the host machine such as a desktop computer or server, executes applications and produces executable binaries that run on the target device. That is why it is called a cross-compilation toolchain because it compiles the program on machine and provides a binary that runs on the other target architecture usually ARM as shown in the figure below.
Why do we need a cross compilation tool chain?
In embedded Linux based system development , cross-compilation tools are used to compile source code of four main components on the Host machine. These four main components are bootloader, root file system, Linux Kernel and main application. The main reason to use a host machine is that usually target devices do not have enough resources to compile applications.
Now, we will see all the steps to download and install ARM cross-compilation tool chain for Linux based host machines.
Download ARM Cross Toolchain
The first step is to download the arm cross toolchain for your host machine. To download the arm architecture cross toolchain, go this link:
This ARM toolchain is developed by Linaro. Hence, the first step you have to download the cross toolchain. For that, go to the above link.
As you can see on this link, there are multiple cross toolchains available for different host machines such as Windows and Linux. Furthermore, they are available for both 32-bit and 64-bit machines of Windows and Linux operating system based host machines. The name of the toolchain is arm-linux-gnueabihf. Here, arm-linux-gnueabihf stands for Linux GNU toolchain for ARM with hard float.
Now select the toolchain according to your host machine. For example, if you are using a Windows machine, you can select this one:
gcc-linaro-7.5.0-2019.12-i686-mingw32_arm-linux-gnueabihf.tar.xz
If you are using Linux based 64-bit host machine, download this toolchain:
Gcc-linaro-6.3.1-2017.02-x86_64_arm-linux-gnueabihf.tar.xz
If you are using Linux based 32-bit host machine, download this toolchain:
gcc-linaro-7.5.0-2019.12-i686_arm-linux-gnueabihf.tar.xz
Although, Linaro provides toolchains for windows and Linux based systems. But it is recommended to use a Linux based host machine for embedded linux development. Because it is mandatory to have a Linux based host machine (Ubuntu, Fedora etc) to compile the Linux source code, to compile the U-Boot source code, to compile the busy box, etc.
If you are using a Windows machine, you can install a Ubuntu or Fedora distribution in a virtual machine and use Linux as a host machine.
Because we are using an Ubuntu 64-bit machine, I will download this package:
Gcc-linaro-6.3.1-2017.02-x86_64_arm-linux-gnueabihf.tar.xz
You should download the pachae according to your host machine. After that go to the directory where you have downloaded the ARM toolchain package.
In the next step, just extract the package by right clicking and select extract here option from menu. You can also use this command to extract packages. .
tar xvf gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz
After that export the path ARM Linux gnueabihf cross toolchain. To do this , go to the bin folder inside the toolchain and include this path in the environmental variable called PATH.
export PATH=$PATH:/home/bilal/toolchain/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin
To do environmental variable setting, open your terminal and go to home directory. After that open the file name “.bashrc” with the editor of your choice.
nano /home/bilal/.bashrc
After that add this line at the end of the .bashrc and save the file.
export PATH=$PATH:/home/bilal/toolchain/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin
Note: Make sure to add the path according to your directory where you have extracted ARM cross toolchain.
After that run this command to make effect of the changes in bashrc.
source /home/bilal/.bashrc
So we have successfully installed a cross compilation toolchain for ARM. In order to see the installed binaries, just type “arm” on the command line and hit tab. You will see the installed cross compiled toolchain binaries.
Note: If you do not see the list of binaries in your command line. That means you didn’t set up the environment variable in the .bashrc file properly.
Cross Compilation for Raspberry Pi
Now let’s compile a simple hello world program for raspberry Pi on our host machine and try to run the executable file on the target device that is raspberry pi.
First create a simple hello world c program and save it in your current working directory with any name such as hello.c
#include <stdio.h>
int main() {
// printf() displays the string inside quotation
printf("Hello, World!\n");
return 0;
}
Now compile this code using arm toolchain binary like this:
arm-linux-gnueabihf-gcc hello.c
This command will generate a.out executable binary. If you try to run this command on your hosting machine, you will get as shown in the figure below. Because this executable file is created for an ARM based machine.
Now to run this a.out executable file on raspberry pi, transfer this file to raspberry pi using scp command. This command transfers the a.out file to raspberry pi in the home directory.
scp a.out pi@192.168.1.9:
Here 192.168.1.9 is the IP address of Raspberry Pi. After you run this command, a.out will be transferred to Pi.
Now ssh into your raspberry pi and run ls command to see the a.out file. After that run this file on your raspberry pi, you will get a “hello world” output on the terminal.
In summary, we can use the cross-compilation toolchain of ARM to compile applications on our host machine and the produced binary can run on the target device.
Related Tutorials:
- Embedded Linux
- Bare-metal and RTOS Based Embedded Systems
- What is Microcontrollers startup file – Understand its various Functions
- Bare Metal Embedded Systems Linker Script File
- Nested Vectored Interrupt Controller (NVIC) ARM Cortex-M Microcontrollers
- Bare Metal Embedded Systems Build Process using GNU Toolchain
- What is Interrupt Vector Table?
- Microcontroller Booting Process – Reset Sequence
Hi,
thanks for pointing out the basics of crosscompilation.
Still, it doesn’t seem basich enough for me 🙁
When executing “$arm-linux-gnueabihf-gcc hello.c” I get
hello.c:1:10: fatal error: stdio.h: No such file or directory
1 | #include
| ^~~~~~~~~
while a simple “gcc hello.c” results in a.out being created.
What am I missing ?
run this command on terminal:
sudo apt-get install libc6-dev
Thank you for the fast reply,
I am actually on Arch Linux x86_64 and have glibc as well as lib32-glibc installed.
stdio.h lives in /usr/include gcc finds it, while arm-linux-gnueabi-gcc does not.
[tc@IBB811420-ARCH linaro]$ pacman -Q | grep glib
aarch64-linux-gnu-glibc 2.34-1
glib-networking 1:2.70.0-1
glib2 2.70.0-1
glibc 2.33-5
json-glib 1.6.6-1
lib32-glibc 2.33-5
try exporting to library path arm-linux-gnueabi-gcc