Shell Script for Building a Complete GCC Cross-Compiler

This article illustrates how to install on a Debian-based distribution the complete toolchain to cross compile in a shell-script automated way. A short intro In several cases it happens that the platform you’re developing on and the computer you’re developing for don’t match. For instance, you may want to develop an application for ARM or PowerPC on your x86 computer. In order to do that, it is necessary to build a cross-compiler that will enable you to build applications for other targets on your machine i.e. a compiler that knows how to write machine code for your target platform.  The required process to install the compiler is provided in the following bash script: a script to download packages for, configure, build and install a GCC cross-compiler from scratch.

#!/bin/sh

#-------------------------------------------------------------------------------------------
# Author: Charalambos Konstantinou 
# W: http://harryskon.com/
# Github: https://github.com/harryskon/cross_compilers
# 
# This script will download packages for, configure, build and install a GCC cross-compiler.
# 
# Published also @ http://w3-tutorials.com/item/29-shell-script-for-building-a-complete-gcc-cross-compiler
#-------------------------------------------------------------------------------------------

# See http://gcc.gnu.org/install/specific.html for more examples on host and target specifics
# For our case: HOST="x86_64-pc-linux-gnu"

# Choose your target: https://gcc.gnu.org/install/specific.html
TARGET="powerpc-eabisim"
# Tried parallel build with e.g. MAKEOPTS="-j 2" but didn't work thus leave it empty
MAKEOPTS=""

abort() {
 echo "**************************************************************"
 echo error: $@
 echo "**************************************************************"
 exit 1
}
success() {
 echo "***************************************************************"
 echo success: $@
 echo "***************************************************************"
 echo "\a"
 sleep 3s
}

# GCC should not be build in the source directory: why? http://gcc.gnu.org/ml/gcc-bugs/2007-06/msg00234.html
prepare_clean_build() {
 rm -rf $BUILDDIR
 mkdir $BUILDDIR
 cd $BUILDDIR
}

CROSSDIR=$HOME/ppc
BUILDDIR=$CROSSDIR/build
SOURCEDIR=$CROSSDIR/sources
DOWNLOADS=$CROSSDIR/downloads
INSTDIR=$CROSSDIR/cross-gcc

export PATH="$INSTDIR/bin:$PATH"

test -d $CROSSDIR || mkdir $CROSSDIR
test -d $DOWNLOADS || mkdir $DOWNLOADS
test -d $SOURCEDIR || mkdir $SOURCEDIR
test -d $INSTDIR && rm -rf $INSTDIR; mkdir $INSTDIR

# 1. Install binutils (containing the assembler and the linker)
 BINUTILS=binutils-2.25
 cd $DOWNLOADS
 test -f $BINUTILS.tar.gz || wget http://ftp.gnu.org/gnu/binutils/$BINUTILS.tar.gz
 cd $SOURCEDIR
 test -d $BINUTILS || tar -xzf $DOWNLOADS/$BINUTILS.tar.gz
 prepare_clean_build
 $SOURCEDIR/$BINUTILS/configure --prefix=$INSTDIR --target=$TARGET --disable-nls --disable-werror
 make $MAKEOPTS all install || abort "building of $BINUTILS failed"
 success "$BINUTILS successfully installed to $INSTDIR"

# 2. Install GMP (GNU multiple precision arithmetic library)
 GMP=gmp-4.3.2
 cd $DOWNLOADS
 test -f $GMP.tar.bz2 || wget ftp://gcc.gnu.org/pub/gcc/infrastructure/$GMP.tar.bz2
 cd $SOURCEDIR
 test -d $GMP || tar -xjf $DOWNLOADS/$GMP.tar.bz2
 prepare_clean_build
 $SOURCEDIR/$GMP/configure --disable-shared --enable-static --prefix=$INSTDIR
 make $MAKEOPTS all install || abort "building of $GMP failed"
 success "$GMP successfully installed to $INSTDIR"

# 3. Install MPFR (library for multiple-precision floating-point computations)
 MPFR=mpfr-2.4.2
 cd $DOWNLOADS
 test -f $MPFR.tar.bz2 || wget ftp://gcc.gnu.org/pub/gcc/infrastructure/$MPFR.tar.bz2
 cd $SOURCEDIR
 test -d $MPFR || tar -xjf $DOWNLOADS/$MPFR.tar.bz2
 prepare_clean_build
 $SOURCEDIR/$MPFR/configure --disable-shared --enable-static --prefix=$INSTDIR --with-gmp=$INSTDIR
 make $MAKEOPTS all install || abort "building of $MPFR failed"
 success "$MPFR successfully installed to $INSTDIR"

# 4. Install MPC (library for the arithmetic of complex numbers with arbitrarily high precision)
 MPC=mpc-0.8.1
 cd $DOWNLOADS
 test -f $MPC.tar.gz || wget ftp://gcc.gnu.org/pub/gcc/infrastructure/$MPC.tar.gz
 cd $SOURCEDIR
 test -d $MPC || tar -xzf $DOWNLOADS/$MPC.tar.gz
 prepare_clean_build
 $SOURCEDIR/$MPC/configure --disable-shared --enable-static --prefix=$INSTDIR --with-gmp=$INSTDIR --with-mpfr=$INSTDIR
 make $MAKEOPTS all install || abort "building of $MPC failed"
 success "$MPC successfully installed to $INSTDIR"

# 5. Install GCC (version 4 and above need GMP, MPFR and MPC development libraries to be installed)
 GCC=gcc-4.8.4
 cd $DOWNLOADS
 test -f $GCC.tar.bz2 || wget http://mirrors.kernel.org/gnu/gcc/$GCC/$GCC.tar.bz2
 cd $SOURCEDIR
 test -d $GCC || tar -xjf $DOWNLOADS/$GCC.tar.bz2
 prepare_clean_build
 $SOURCEDIR/$GCC/configure --prefix=$INSTDIR --target=$TARGET --disable-nls --disable-libssp --enable-languages="c" --without-headers --with-newlib --with-gmp=$INSTDIR --with-mpfr=$INSTDIR --with-mpc=$INSTDIR
 make $MAKEOPTS all install || abort "building of $GCC failed"
 success "$GCC successfully installed to $INSTDIR"

# 6. Install newlib (library implementation intended for use on embedded systems)
 NEWLIB=newlib-2.2.0
 cd $DOWNLOADS
 test -f $NEWLIB.tar.gz || wget ftp://sources.redhat.com/pub/newlib/$NEWLIB.tar.gz
 cd $SOURCEDIR
 test -d $NEWLIB || tar -xzf $DOWNLOADS/$NEWLIB.tar.gz
 prepare_clean_build
 $SOURCEDIR/$NEWLIB/configure --prefix=$INSTDIR --target=$TARGET --disable-nls
 make $MAKEOPTS all install || abort "building of $NEWLIB failed"
 success "$NEWLIB successfully installed to $INSTDIR"


echo "Use cross-compiler by typing:"
echo "$INSTDIR/bin/$TARGET-gcc sourcefile.c"
echo "For more options type: $INSTDIR/bin/$TARGET-gcc --help"
echo "For example: include the -msim option to choose the specific (ppc) machine type"
Advertisements

How to Build Cross Compilers for Embedded Systems

The following steps explain how to build a cross compiler on your *nix machine:

Download the following sources

Set environment variables

Before setting the environment variables you have to choose your target: in this tutorial our target is powerpc-eabi (Embedded PowerPC system in big endian mode). Check here for other targets.


% export TARGET=powerpc-eabi
% export PREFIX=/usr/local/$TARGET #specify the PATH you want the cross-compiled binaries
% export PATH=$PATH:$PREFIX/bin

Compiling and installing binutils

% tar xzfv binutils-2.25.tar.gz
% mkdir build-binutils
% cd build-binutils
% ../binutils-2.25/configure --target=$TARGET --prefix=$PREFIX
% make all
% make install

Compiling and installing GCC

% tar xjfv gcc-4.8.4.tar.bz2
% mkdir build-gcc
% cd build-gcc
% ../gcc-4.8.4/configure --target=$TARGET --prefix=$PREFIX --without-headers --with-newlib --with-gnu-as --with-gnu-ld
% make all-gcc
% make install-gcc

Compiling and installing newlib

% tar xzfv newlib-2.2.0-1.tar.gz
% mkdir build-newlib
% cd build-newlib
% ../newlib-2.2.0-1/configure --target=$TARGET --prefix=$PREFIX
% make all
% make install

Reconfigure GCC with newlib

% cd build-gcc
% ../gcc-4.8.4/configure --target=$TARGET --prefix=$PREFIX --with-newlib --with-gnu-as --with-gnu-ld --disable-shared --disable-libssp
% make all
% make install

Compiling and installing GDB with PSIM (Emulator of the PowerPC Architecture)

% tar xjfv gdb-7.8.2.tar.bz2
% mkdir build-gdb
% cd build-gdb
% ../gdb-7.8.2/configure --target=$TARGET --prefix=$PREFIX –enable-sim-powerpc --enable-sim-stdio
% make all
% make install

Done! Let’s test our tool chain (-m options here)

% powerpc-eabi-gcc -mcpu=440 hw.c -o hw -msim
% powerpc-eabi-run hello