[an error occurred while processing this directive] Next Previous Contents

4. How to configure, build, and install GCC as a cross-compiler

4.1 Unix Systems


  1. The author has more familiarity with Newlib than Glibc so Newlib will be used in all examples below.
  2. GAS and GLD are now distributed in the `binutils' distribution, so all further references to GAS and GLD in this section will use Binutils instead.
  3. If you have a `make' that understands VPATH (like GNU make), it is highly recommended that you build the pieces in a different directory from the sources. The examples below will assume this. Also, if you do decide to build in a directory different from the source, GNU make is generally the only make that can handle this correctly.
The pieces have to be built and installed in a particular order. Why? Clearly the cross-compiler is needed to build the libraries, so GCC must be built before Newlib. Also, GCC has its own library (called libgcc) so Binutils must be built before GCC.

Here is the recommended order:

  1. Binutils
  2. GCC
  3. Newlib
  4. GDB


The build procedure would then look like this.

cd /home/foo

mkdir build-binutils build-gcc build-newlib build-gdb

# Configure, build and install binutils
 cd build-binutils
../binutils-2.9.1/configure --target=$target --prefix=$prefix -v
make all install

# Configure, build and install gcc
cd ../build-gcc
../gcc-2.8.1/configure --target=$target --prefix=$prefix -v
make all install

# Configure, build and install newlib 
cd ../build-newlib 
../newlib-1.8.1/configure --target=$target --prefix=$prefix -v 
# The settings for FOO_FOR_TARGET aren't necessary if you put $prefix/bin 
# in your path before running this. 
make all install \ 
        CC_FOR_TARGET=$i/${target}-gcc \ 
        AS_FOR_TARGET=$i/${target}-as \ 
        LD_FOR_TARGET=$i/${target}-ld \ 
        AR_FOR_TARGET=$i/${target}-ar \ 

# Configure, build and install gdb
cd ../build-gdb 
../gdb-4.17/configure --target=$target --prefix=$prefix -v
make all install

4.2 One Pass Installation

Is there an easier way? Yes!

If you study the top-level Makefile that comes with binutils-2.9.1, newlib-1.8.1, or gdb-4.17, you'll see that they're all quite similar (not surprising since they're essentially the same file). You'll also discover that it is capable of building and installing the entire toolchain in one pass. The catch is that is assumes a directory layout different than what would normally appear when you unpack the sources.

What we now need to do is turn this directory layout




Where's GDB? GDB is left out because it shares sources with Binutils (e.g. bfd, include, libiberty, and opcodes). One can't `mix and match' them, they each need there own copies (since they were tested and released with their own copies). GDB can be built separately afterwards.

One might well ask what's the point of this pseudo one-pass installation and that would be a good question. It simplifies the installation a little, and in particular the `Canadian Cross' installation (see What is a Canadian Cross?. Binutils and Newlib share `config' and `texinfo' directories; we can use Binutils' copies.

A script exists to reorganize the above source tree using symlinks. It assumes:

The script is one-tree-1.6.sh ( ftp://ftp.sthoward.com/pub/crossgcc/one-tree-1.6.sh). It will create a subdirectory called src.

If one or more of the subdirecties listed above does not exist, the script will attempt to un-pack a tar file from a subdirectory called tars to create the missing source files. Finally, the src directory is created and the source files are symlinked into it.

After running the script, do this:

mkdir build
cd build
../src/configure --target=$target --prefix=$prefix -v
make all install

mkdir ../build-gdb
cd ../build-gdb
../gdb-4.17/configure --target=$target --prefix=$prefix -v
make all install

4.3 Can I build in a directory different from the source tree?


However, it requires a version of make that understands VPATH. SunOS make may or may not be sufficient: its VPATH support has problems which require extra effort to support, and developers don't always adhere to the restrictions. If you don't use GNU make, you're on your own as far as getting the build to work.

4.4 Can I use a non-GNU make?


However, there are a few things to be wary of:

4.5 Is there a script available to automate the build process?

Glad you asked. Yes, there is. It is called `build-cross.sh' ( ftp://ftp.sthoward.com/pub/crossgcc/build-cross.sh) and it builds a cross-compiler and runtime libraries on your Unix/Linux machine that targets your favourite embedded processor.

The script takes two command line parameters, with the following syntax:

sh build-cross.sh <targetname> [install]

where <targetname> is the 'configure' name for the embedded target system, and [install] is an optional flag which causes the script to install the cross-compiler tools after they have been built.

The typical way to use this script is to run it once under your normal user account, without the 'install' flag. This causes the tools to be built in your working directory, but not installed into the system's execution directory (normally /usr/<targetname> on Linux systems). Once the build is done, log in now as 'root' and run the script again, this time with the 'install' flag on the command line. This time, the tools will be installed into their final resting place, from which point they will be available for use to build programs for your embedded target.

For example, say you wanted to build a cross compiler targeting embedded PowerPC systems. The configure name to use is powerpc-eabi. A typical session might look like this:

[scotth] $ ./build-cross.sh powerpc-eabi 
(tons of messages go by while the tools are being built.) 
[scotth] $ su
[root] # ./build-cross.sh powerpc-eabi install 
(Somewhat fewer messages this time, while the tools are installed.) 
[root] # exit
[scotth] $

You can build and install in one command by always specifying the 'install' flag; however this requires that the build be performed with root privileges, since this privilege level is usually required in order to install the tools to their execution directories, and performing long builds like this with 'root' privilege can be a security risk. But if security is not an issue, this can be more convenient.

4.6 Cygnus Releases

Where are the info files?

Cygnus releases differ from FSF releases in that files that are not really source files but are built from other files (like yacc files and texinfo files) are not included. Instead, they are built with the rest of the toolchain.

How do I build a Cygnus release?

Cygnus releases are essentially the `one-pass installation' tree, except that a lot more tools are included (e.g. bison, flex, expect, gdb, make, tcl, texinfo). To build a toolchain from a Cygnus release, you should consult the documentation that came with it (there may be last minute release notes, or this FAQ may be out of date, etc.).

But for those who happen to come upon a Cygnus release, here is a quick introduction. Suppose you happen upon a Cygnus release and want to build a sparc-sun-solaris2 cross m32r-elf compiler. Do this:

mkdir build
cd build
$src/configure --target=$target --prefix=$rel
make all info install install-info
PATH=$PATH:$rel/bin ; export PATH

You can also run dejagnu on the build tree at this point with

make -k check

The gcc and g++ execute tests won't do much in this particular example unless dejagnu has been configured to use the simulator or target board for the execute tests.

4.7 Win32 hosted cross-compilers

There is work in progress that will let the GNU tools be used as a native compiler in the win32 environment and also as a cross-compiler (either win32 hosted or win32 targeted). Join the gnu-win32@cygnus.commailing list if you wish to help out. The release is kept in ftp://ftp.cygnus.com/pub/gnu-win32. The configuration for this project is i386-cygwin32.

Subscription requests should be sent to gnu-win32-request@cygnus.comwith a body of 1 line containing `subscribe gnu-win32 <your-email-address>' and nothing else (and no <>'s around your email address).

4.8 Gnu CC and MS-DOS

The primary MSDOS port is version 2 of `djgpp', a port of the GNU tools to MSDOS by dj Delorie, using `go32-v2', a 32 bit extender. See the djgpp FAQ for more details ( http://www.delorie.com/djgpp/v2faq/).

Using the djgpp runtime system, Gnu CC can run on MS-DOS as a 32-bit DOS application. It can also run on another type of system (say, Linux) and cross-compile DOS programs that will run on MS-DOS.

How do I build a cross-compiler with DJGPP?

The procedure is basically this.

How do I create a cross-compiler for DOS on my Unix/Linux machine ?

You need the following pieces:

The script assumes that the zip file is in a subdirectory named tars. It installs libraries and header files from the zip file into their final installation directory (normally /usr/i386-pc-msdosdjgpp); it then configures, compiles and installs the binary utilities, and then compiler. The script must be run with `root' privileges.

After you have run the script, you will be able to compile DOS programs using the compiler i386-pc-msdosdjgpp-gcc. For example, if you wanted to compile the program hello.c to run on DOS:

[scotth] $ i386-pc-msdosdjgpp-gcc -o hello.exe hello.c

4.9 Canadian Crosses

What is a Canadian Cross?

One cool thing about the GNU tools is that they support building a cross compiler for one host on another host (i.e. building a cross-compiler with a cross-compiler). This is called a `Canadian Cross' because at the time a name was needed, Canada had three national parties.

How do I build an MSDOS hosted cross compiler without using MSDOS?

Suppose one wanted to build an MSDOS cross m68k-coff cross compiler on a sparc-sunos4 machine. The procedure is as follows. Note that it is quite lengthy; that's because four compilers are involved (three to build the one we want).

Why four? Remember, we're building the tools completely on a Unix box, therefore all the programs that run during the build process must obviously run on the Unix box. We can't skip over to an MSDOS machine, run something there, and come back - the entire toolchain is built from scratch on the Unix box.

The first compiler that is needed is a sunos4 cross m68k-coff compiler to build the m68k-coff libraries. But in order to build that we need a sunos4 native compiler. That's two. We also need a sunos4 cross i386-pc-msdosdjgpp compiler to build the programs that run on MSDOS . Finally, we need an i386-pc-msdosdjgpp cross m68k-coff compiler: our final goal.

Four compilers. However, the process is quite straightforward once you understand all the pieces that are needed.

Previous versions of this FAQ featured a script that would build the sunos4 cross i386-pc-msdosdjgpp as part of the script. This worked because they targeted version 1 of the djgpp port of Gnu CC, which used the newlib run-time library. In order to take advantage of the considerable benefits of djgpp version 2 (such as virtual memory and better debugging support), we have elected to build the sunos4 cross i386-pc-msdosdjgpp as a separate step, using the build-djgpp.sh script file. See the section on building a Linux to djgpp cross compiler here.

Assume the source tree has been created with the `one-tree' script. The following is the list of steps, written so that it can be copied into a shell script and run.

# This script is build-3way.sh from crossgcc FAQ 1.0 
# Before using this script it is a good idea to check with the most recent 
# version of the FAQ to see if any changes have been made.  The FAQ can be 
# obtained from http://www.sthoward.com/CrossGCC. 
# This script assumes that the source tree (in directory 'src') contains binutils, gcc, 
# and newlib, constructed with the one-tree script 
# Syntax: sh build-3way.sh targetname [install] 
# The default is to configure and build, but not install. 
# The recommended way to use this script is to modify the variables 
# build,host,target,src,rel,relexec as necessary, then run: 
# build-3way.sh targetname 
# build-3way.sh targetname install 
# The process is rather involved as there are a lot of steps. 
# On the other hand, it is really rather straightforward. 
# The goal is to build a $host cross $target toolchain.  Some hosts aren't 
# well suited to program development (eg: msdos) and other hosts may not have 
# complete GNU support yet.  Both of these cases are ideally handled by a 
# script like this where we build everything in a more familiar and 
# comfortable environment (eg: unix). 
# The toolchain we are building is composed of basically two pieces: 
# 1) programs that run in the host environment. 
#    These include gcc, cpp, cc1, as, ld, objdump, etc.  These critters 
#    are built with a $build cross $host cross-compiler. 
# 2) libraries of functions that run in the target environment. 
#    These include libgcc.a, libc.a, libm.a, etc.  These critters are 
#    built with a $build cross $target cross-compiler. 
# We end up building 3 complete toolchains: $build cross $host (done in a separate script), 
# $build cross $target, and ultimately $host cross $target. 
# Remember, the only environment in which we can run programs is $build: 
# that is the reason for the complexity. 
# The cool thing is that this can be done at all! 

set -e 




# Build directory for the $build cross $target toolchain. 
# Build directory for the $host cross $target toolchain. 

# Bail if no target given. 
if [ x"$target" = x ] 
        echo "usage: '$0 targetname' [install], where:" 
        echo " - 'targetname' specifies the target configuration to build" 
        echo " - 'install' (optional) directs the script to install the tools (in $rel)." 
        exit 1 

# The first step is to build a $build cross $host cross-compiler. 
# Previous versions of this script built this cross-compiler from the 
# same source tree as was used for the embedded target. However, this 
# doesn't really work anymore because our MS-DOS host configuration 
# no longer uses newlib as its runtime library... so now you must do 
# this step separately by running the script 'build-djgpp.sh'. 
# See the CrossGCC FAQ for more information. 

# Now build a $build cross $target toolchain. 
# The value for --prefix we give here is /tmp/junk as we don't intend 
# to install this toolchain. 

if [ ! -f $b2t/configure.done ] ; then 
    [ -d $b2t ] || mkdir $b2t 
    (cd $b2t ; CC=gcc $src/configure --host=${build} --target=${target} --prefix=/tmp/junk --with-gnu-ld
--with-gnu-as --with-newlib -v) 
    touch $b2t/configure.done 
(cd $b2t ; make -w all-gcc CC=gcc CFLAGS=-g LANGUAGES="c c++") 

# Now that we've built the tools that we need, we can finally build 
# our $host cross $target toolchain. 

# Both configure and make need to be told where to find the various pieces. 
# Define several variables of the things we need to pass to configure and make. 

# These are for building programs that run on $build. 

# These are for building programs and libraries that run on $host. 

# These are for building libraries that run on $target. 
CC_FOR_TARGET="$b2t/gcc/xgcc -B$b2t/gcc/ -isystem $src/winsup/include -isystem $b2t/${target}/newlib/targ-include -isystem $src/newlib/libc/include" 
# use the correct names for as, ld, and nm. 
if [ -f $b2t/gas/as-new ] 

# $DLLTOOL_FOR_TARGET is only needed for win32 hosted systems, but 
# it doesn't hurt to always pass it. 
# For go32 cannot use -g because it can overflow coff debug info tables. 

# Ready.  Configure and build. 
if [ ! -f $h2t/configure.done ] ; then 
    [ -d $h2t ] || mkdir $h2t 
    (cd $h2t ; CC="$CC" AR="$AR" RANLIB="$RANLIB" $src/configure --build=${build} --host=${host}
--target=${target} --prefix=$rel --exec-prefix=$relexec --with-gnu-ld --with-gnu-as -v) 
    touch $h2t/configure.done 

cd $h2t 
make -w all \ 
        LANGUAGES="c c++" \ 
        CFLAGS="$CFLAGS" \ 
        CC="$CC" \ 
        AR="$AR" \ 
        RANLIB="$RANLIB" \ 
# All done, install if asked to. 
if [ x"$action" = xinstall ] ; then 
    make -w install \ 
        LANGUAGES="c c++" \ 
        CFLAGS="$CFLAGS" \ 
        CC="$CC" \ 
        AR="$AR" \ 
        RANLIB="$RANLIB" \ 

# Almost done.  Before the toolchain is usable we need to 
# - convert the coff files to .exe's, 
# - convert file names to follow MSDOS's 8.3 rules, 
# - Change \n to \r\n in text files (like headres). 
# The package dosrel-1.0 is set up to do all this. 
# See ftp://ftp.sthoward.com/pub/crossgcc/dosrel-1.0.tar.gz 

exit $?

Before the tools are usable, a few things must be done:

ftp://ftp.sthoward.com:/pub/crossgcc/dosrel-1.0.tar.gzcontains a set of tools to do this. It works on the `install tree' created by the above procedure and produces a tar/zip'able tree that is ready to install and use.

Modify the steps in dosrel-1.0/README as follows:

  1. Build and install the DOS hosted cross-compiler using the Canadian-Cross method.
  2. Configure this directory the same way you configured the DOS cross-compiler. We build in the source directory here. The argument to --exec-prefix violates DOS's 8.3 rules but the violation is harmless.eg: /path/to/binutils-2.9.1/configure --srcdir=. --build=$build host=i386-go32 --target=$target --prefix=$prefix --exec-prefix=$prefix/H-i386-go32 -v
  3. Run `make dos-tree GO32_STRIP=/path/to/b-sparc-sun-solaris2-x-i386-go32/binutils/strip-new'.
  4. Subdirectory `dos-tree' is now ready to copy over to DOS and use. You will need to edit `set-env.bat' in the `bin' directory to tell GCC and the various pieces where you installed them.

Once the tree is built and installed in MSDOS, you need to create a file called DJGPP.ENV that sets up several parameters for the djgpp runtime system. Then you need to set the environment variable DJGPP to point to this file; and you need to set the PATH variable to include the directory where your newly-built compiler resides.

The following may be copied to the file DJGPP.ENV:

#= djgpp.env, modified for cross-compilation support 
#= Don't edit this line unless you move djgpp.env outside 
#= of the djgpp installation directory.  If you do move 
#= it, set DJDIR to the directory you installed DJGPP in. 







LESS=%LESS% -h5.$


+LS_COLORS=no=00:fi=00:di=36:lb=37;07:cd=40;33;01:ex=32:*.cmd=32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01; 1:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.deb=01;31:*.jpg=01;34:*.gif=01;34:*.bmp=01;34:*.ppm=01;3 :*.tga=01;34:*.xbm=01;34:*.xpm=01;34:*.tif=01;34:*.mpg=01;37:*.avi=01;37:*.gl=01;37:*.dl=01;37:*~=08:*.bak=08: 

+LS_COLORS=no=00:fi=00:di=36:lb=37;07:cd=40;33;01:ex=32:*.cmd=32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01; 1:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.deb=01;31:*.jpg=01;34:*.gif=01;34:*.bmp=01;34:*.ppm=01;3 :*.tga=01;34:*.xbm=01;34:*.xpm=01;34:*.tif=01;34:*.mpg=01;37:*.avi=01;37:*.gl=01;37:*.dl=01;37:*~=08:*.bak=08: 

+LS_COLORS=no=00:fi=00:di=36:lb=37;07:cd=40;33;01:ex=32:*.cmd=32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01; 1:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.deb=01;31:*.jpg=01;34:*.gif=01;34:*.bmp=01;34:*.ppm=01;3 :*.tga=01;34:*.xbm=01;34:*.xpm=01;34:*.tif=01;34:*.mpg=01;37:*.avi=01;37:*.gl=01;37:*.dl=01;37:*~=08:*.bak=08:

The following can be copied to a .bat file and run; replace `c:\bar' with the correct value.

@echo off 
rem set up path and environment variable for cross-compilation 
rem you may want to move this file to a directory that is on your path 

rem this batch file assumes that the base directory is "c:\bar" 
rem if you install it somewhere else, then modify this to suit. 

set DJGPP=c:/bar/djgpp.env 
path c:\bar\bin;%PATH%

4.10 Disk space requirements

How much disk space is required? Disk space requirements vary depending on the host and target. The source tree occupies about 80MB. Very roughly:

A sparc-sunos4.1.4 cross m68k-coff toolchain requires about 100MB to build, and about 40MB installed. Note that the programs are not stripped by default. Stripping them will save you a considerable amount of space.

Next Previous Contents [an error occurred while processing this directive]