There are multiple ways to install a cross compiler on Fedora 17. The simplest way was described in Part 1. The problem is that the available cross-build binary utilities for ARM (sudo yum info gcc-arm-linux-gnu
) does not support cross-building of user space programs. A slightly more complicated option is to use build frameworks like OpenEmbedded or crosstool-ng.
Install crosstool-ng
By the time of writing this post the latest stable version of crosstool-ng is 1.16.0. Installation of a stable version is quite straightforward and it is very clearly described in “Download and usage section” of crosstool-ng.org. For your reference I copy it here with slight modifications.
su - #change to root
#Install dependencies
yum install bison flex gperf libtool texinfo gcc gcc-c++ gmp-devel
#Download and install crosstool-ng
cd /opt
wget http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.16.0.tar.bz2
bunzip2 crosstool-ng-1.16.0.tar.bz2
tar xf crosstool-ng-1.16.0.tar
cd crosstool-ng-1.16.0
#The --prefix parameter shall be set to the installation directory
./configure --prefix=/opt/crosstool-ng-1.16.0
make
make install
#For auto-completion, do not forget to install 'ct-ng.comp' into your bash completion directory
cp ct-ng.comp /etc/bash_completion.d/
The bash_completion will automatically pick up the auto completion parameters after restart. You can read more about autocopletion feature of bash here and here.
Edit the .bash_profile of root user and also your user and add the /opt/crosstool-ng-1.16.0/bin
to PATH
in order make the crostool-ng comands available from shell.
PATH=$PATH:/opt/crosstool-ng-1.16.0/bin
Configure the toolchain
The crosstool-ng has been installed and ready to build a toolchain for the Raspberry Pi (or other environment)
su -
mkdir /opt/crosstool-ng-1.16.0-config
cd /opt/crosstool-ng-1.16.0-config
ct-ng menuconfig
The last command will pop up a kernel-like menuconfig configuration interface where the following changes needs to be made.
- Paths and misc options
- Enable “Try features marked as EXPERIMENTAL”
- Set the “Prefix directory” from “${HOME}/x-tools/${CT_TARGET}” to “/opt/crosstool-ng-1.16.0-tools/${CT_TARGET}”, please note that the /opt/crosstool-ng-1.16.0-config directory will contain the configuration, downloaded tools, temporary build files and the /opt/crosstool-ng-1.16.0-tools will contain your actual toolchain.
- Toolchain options
- Tuple’s version string is set to “unknown” by default, if would like to change it please see the “Note” in the bottom of this post
- Target options
- Be sure that the “Target Architecture” is set to “arm”
- Be sure that “Little Endian” and “32bit” are selected
- Be sure that “Floating point” is set to “hardware (FPU)”
- Be sure that “Use EABI” is selected
- Operating system
- C compiler
- Enable “Show Linaro versions”
- The “gcc version” should automatically change to latest linaro version, if not then set it manually. Currently the latest is “linaro-4.7-2012.07”
- Enable “C++” in order to have C++ compiler
- Disable “Link libstdc++ statically into gcc binary” otherwise you will get the the following error “[ERROR] Static linking impossible on the host system ‘x86_64-build_unknown-linux-gnu'”
- Disable “GRAPHITE loop optimisations” otherwise you will get the the following error “Installing PPL for host [ERROR] configure: error: Cannot find GMP version 4.1.3 or higher.”
Exit from the menuconfig save the changes and build it still as root
ct-ng build
The build takes a while, but after it is done the toolchain should appear in the /opt/crosstool-ng-1.16.0-tools
directory.
Switch from root to your regular user and append the /opt/crostool-ng-1.16.0-tools/arm-unknown-linux-gnueabi/bin
to PATH variable in .bash_profile to make the cross compiler binaries available in shell
PATH=$PATH:/opt/crosstool-ng-1.16.0/bin:/opt/crosstool-ng-1.16.0-tools/arm-unknown-linux-gnueabi/bin
Now you have a full featured cross-compile environment and you can build user space programs or you can compile kernel as described in Part 1. Of course in the CROSS_COMPILE parameter you need to specify the /opt/crosstool-ng-1.16.0-tools/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi-
instead of /usr/bin/arm-linux-gnu-
. For example:
make ARCH=arm CROSS_COMPILE=/opt/crosstool-ng-1.16.0-tools/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi- oldconfig
After you have executed every kernel compilation step described in the Part 1 you should see
pi@raspberrypi ~ $ uname -a
Linux raspberrypi 3.2.27-crosstool-ng #1 PREEMPT Tue Oct 2 20:28:03 CEST 2012 armv6l GNU/Linux
To test the cross-building capability of user space programs just creat a little hello world as hello.c
#include <stdio.h>
int main () {
printf("Hello Cross Compiled Pi\n");
return 0;
}
Compile it and check the result of compilation with file command
~ $ arm-unknown-linux-gnueabi-gcc -o arm-hello hello.c
~ $ file arm-hello
arm-hello: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 3.5.0, not stripped
After transfering it to Raspberry pi with scp
pi@raspberrypi ~ $ ./arm-hello
Hello Cross Compiled Pi
Note: The “arm-unknown-linux-gnueabi” name is crated based on form “arch-vendor-kernel-system”. You can set the vendor to whatever you think fits better. For that you can navigate to “Toolchain options” -> “Tuple’s vendor string” and change it from “unknown” to e.g. “rpi” and build the whole tool-chain as described above, after this modification your tools will be named like “arm-rpi-linux-gnueabi”.