Compiling a large project on a raspberry may take days compared to several minutes on a x86 CPU. The Raspberry Pi has very little RAM. In comparison, cross-compiling and linking the same code on a modern machine takes a fraction of the time. Since we are going to run on an Intel processor, and we want to build object code for the ARM processor for the Raspberry Pi, we need a cross-compiler and its associated tools, which is usually called a toolchain. We will be using crosstool-ng to build the toolchain. While there are a lot of different methods for building cross-compilers, the quickest and easiest is to use crosstool-ng. This is a set of scripts that bring up a menuconfig-like interface to choose your compiler settings, then goes off and downloads what it needs, patches it, configures it, builds it and installs it all for you.
First, we need to create a directory to host, download and extract the sources. Create a directory in your home directory called src. We will be storing all the files needed for cross compiling there. Inside the directory, create a directory called toolchain, where we will store all the toolchains. Download the ‘crosstool-ng’ there from crosstool-ng.org. Once downloaded, extract the files and go to the extracted directory. Run ./configure –prefix=/opt/cross where /opt/cross stores the executables for the cross compiler. Make sure that /opt/cross/bin is in your HOME environment variable. Then finally, run make and install to install the crosstool-ng.
To configure crosstool-ng, we need to run ct-ng menuconfig which will bring up the configuration menu. Go into Paths and misc options. Enable Try features marked as EXPERIMENTAL. Go back to the main menu and select Target options. Change the Target architecture to arm. Leave Endianness set to Little endian and Bitness set to 32-bit. Go back to the main menu and select Operating system. Change Target OS to linux. Go back to the main menu and select Binary utilities. Change binutils version to whichever is the latest that isn’t marked as experimental. Go back to the main menu and select C compiler. Enable the Show Linaro versions (EXPERIMENTAL) option. n the gcc version field, choose the linaro-4.6-2012.04 (EXPERIMENTAL) compiler. All the other settings are fine left at their default values. Exit the configuration tool and save your changes. Run ct-ng build.
In order to get the cross compiler to work, we also need to install some other tools. We need bison which is a general purpose parser generator. Cvs which is used to store the history of a file. We need flex which is a open source lexical analyzer generator. We need gperf which is a hash generator. We need texinfo and texinfo and libtool. In Linxu, you can install them all by running sudo apt-get update and then sudo apt-get install bison cvs flex gperf texinfo automake libtool. Once the tools are installed, run make and make install.
Crosstool-NG is configured with a graphical user interface that presents a menu-structured set of options. These options let you specify the way you want your toolchain built, where you want it installed, what architecture and specific processor it will support, etc. The value for those options are then stored in a configuration file.
The configurator works the same way you configure your Linux kernel. To start the customization, open menuconfig by typing ct-ng menuconfig. First allow extending the toolchain after it is created since it is read only by default. Next, change the Target options to the cpu version of your Raspberry Pi ( e.g. cortex-a72 ). Next, change the Tuple’s vendor string in Toolchain options to your Raspberry Pi version ( e.g. rpi3 ). Once That is not, re=run ct-ng build to build the toolchain.
To test the toolchain, create a simple, hello world program. If we can compile and run it on target, the toolchain is working. In order to compile it using the toolchain, we need to add the bin dir to PATH by adding ~/x-tools/aarch64-rpi3-linux-gnu/bin to our path either by editing your environment variables or typing PATH=$PATH:~/x-tools/aarch64-rpi3-linux-gnu/bin in the terminal. Compile the code using by typing in the following in the terminal, aarch64-rpi3-linux-gnu-g++ hello_world.cpp -o hello_world. If you are using C, you would use aarch64-rpic-linux-gnu-gcc instead. There should be no build errors and a file named hello_world will be created. To test the program, copy the file to your Raspberry Pi and run it.
The example above is a simple case of cross compiling for the Raspberry Pi where there are no special libraries that need to be included. When there are libraries that need to be added to the compile, it gets more complicated. In our next article, we will cover some of those cases.