Next
Previous
Contents
4. How to configure, build, and install GCC as a cross-compiler
4.1 Unix Systems
Notes:
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:
Suppose
The build procedure would then look like this.
cd /home/foo
host=sparc-sun-solaris2
target=m68k-coff
prefix=/bar
i=$prefix/bin
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 \
RANLIB_FOR_TARGET=$i/${target}-ranlib
# 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
./binutils-2.9.1/
bfd/
binutils/
config/
gas/
include/
ld/
libiberty/
opcodes/
texinfo/
./gcc-2.95.2/
./newlib-1.8.2/
config/
libgloss/
newlib/
texinfo/
into
./src/
bfd/
binutils/
config/
gas/
gcc/
include/
ld/
libgloss/
libiberty/
newlib/
opcodes/
texinfo/
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 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 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?
Yes. 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?
Yes. 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 Password: [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
src=/path/to/source/tree rel=/path/to/install/tree host=sparc-sun-solaris2 target=m32r-elf 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 Subscription requests should be sent to
gnu-win32-request@cygnus.comwith
a body of 1 line containing ` 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 After you have run the script, you will be able to compile DOS programs
using the compiler [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 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 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 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.
#!/bin/sh
# 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
here=`pwd`
target=$1
action=$2
build=`src/config.guess`
host=i386-pc-msdosdjgpp
src=$here/src
rel=/tmp/test
relexec=$rel/H-${host}
# Build directory for the $build cross $target toolchain.
b2t=$here/b-${build}-x-${target}
# Build directory for the $host cross $target toolchain.
h2t=$here/b-${host}-x-${target}
# Bail if no target given.
if [ x"$target" = x ]
then
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
fi
######################################################################
#
# 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
fi
(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.
CC_FOR_BUILD=gcc
CXX_FOR_BUILD=gcc
# These are for building programs and libraries that run on $host.
CC=$host-gcc
AR=$host-ar
RANLIB=$host-ranlib
# 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"
GCC_FOR_TARGET="$CC_FOR_TARGET"
CC_FOR_TARGET="$CC_FOR_TARGET"
CXX_FOR_TARGET="$CC_FOR_TARGET"
# use the correct names for as, ld, and nm.
if [ -f $b2t/gas/as-new ]
then
AS_FOR_TARGET=$b2t/gas/as-new
LD_FOR_TARGET=$b2t/ld/ld-new
NM_FOR_TARGET=$b2t/binutils/nm-new
else
AS_FOR_TARGET=$b2t/gas/as.new
LD_FOR_TARGET=$b2t/ld/ld.new
NM_FOR_TARGET=$b2t/binutils/nm.new
fi
AR_FOR_TARGET=$b2t/binutils/ar
RANLIB_FOR_TARGET=$b2t/binutils/ranlib
# $DLLTOOL_FOR_TARGET is only needed for win32 hosted systems, but
# it doesn't hurt to always pass it.
DLLTOOL_FOR_TARGET=$b2t/binutils/dlltool
# For go32 cannot use -g because it can overflow coff debug info tables.
CFLAGS=-O
CXXFLAGS=-O
# 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
fi
cd $h2t
make -w all \
LANGUAGES="c c++" \
CFLAGS="$CFLAGS" \
CXXFLAGS="$CXXFLAGS" \
CC_FOR_BUILD="$CC_FOR_BUILD" \
CXX_FOR_BUILD="$CXX_FOR_BUILD" \
CC="$CC" \
AR="$AR" \
RANLIB="$RANLIB" \
GCC_FOR_TARGET="$CC_FOR_TARGET" \
CC_FOR_TARGET="$CC_FOR_TARGET" \
CXX_FOR_TARGET="$CC_FOR_TARGET" \
AS_FOR_TARGET=$AS_FOR_TARGET \
LD_FOR_TARGET=$LD_FOR_TARGET \
AR_FOR_TARGET=$AR_FOR_TARGET \
NM_FOR_TARGET=$NM_FOR_TARGET \
RANLIB_FOR_TARGET=$RANLIB_FOR_TARGET \
DLLTOOL_FOR_TARGET="$DLLTOOL_FOR_TARGET"
# All done, install if asked to.
if [ x"$action" = xinstall ] ; then
make -w install \
LANGUAGES="c c++" \
CFLAGS="$CFLAGS" \
CXXFLAGS="$CXXFLAGS" \
CC_FOR_BUILD="$CC_FOR_BUILD" \
CXX_FOR_BUILD="$CXX_FOR_BUILD" \
CC="$CC" \
AR="$AR" \
RANLIB="$RANLIB" \
GCC_FOR_TARGET="$CC_FOR_TARGET" \
CC_FOR_TARGET="$CC_FOR_TARGET" \
CXX_FOR_TARGET="$CC_FOR_TARGET" \
AS_FOR_TARGET=$AS_FOR_TARGET \
LD_FOR_TARGET=$LD_FOR_TARGET \
AR_FOR_TARGET=$AR_FOR_TARGET \
NM_FOR_TARGET=$NM_FOR_TARGET \
RANLIB_FOR_TARGET=$RANLIB_FOR_TARGET \
DLLTOOL_FOR_TARGET="$DLLTOOL_FOR_TARGET"
fi
# 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:
Once the tree is built and installed in MSDOS, you need to create a file
called The following may be copied to the file #= 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. #= DJDIR=%:/>DJGPP% +USER=dosuser +TMPDIR=%DJDIR%/tmp +EMU387=%DJDIR%/bin/emu387.dxe +LFN=n [bison] BISON_HAIRY=%DJDIR%/lib/bison.hai BISON_SIMPLE=%DJDIR%/lib/bison.sim [cpp] CPLUS_INCLUDE_PATH=%/>;CPLUS_INCLUDE_PATH%%DJDIR%/lang/cxx;%DJDIR%/include;%DJDIR%/contrib/grx20/include #C_INCLUDE_PATH=%/>;C_INCLUDE_PATH%%DJDIR%/include;%DJDIR%/contrib/grx20/include #OBJCPLUS_INCLUDE_PATH=%/>;OBJCPLUS_INCLUDE_PATH%%DJDIR%/include;%DJDIR%/lang/objc #OBJC_INCLUDE_PATH=%/>;OBJC_INCLUDE_PATH%%DJDIR%/include;%DJDIR%/lang/objc [gcc] #COMPILER_PATH=%/>;COMPILER_PATH%%DJDIR%/bin #LIBRARY_PATH=%/>;LIBRARY_PATH%%DJDIR%/lib;%DJDIR%/contrib/grx20/lib GCC_EXEC_PREFIX=%/>;GCC_EXEC_PREFIX%%DJDIR%/ [gxx] #COMPILER_PATH=%/>;COMPILER_PATH%%DJDIR%/bin #LIBRARY_PATH=%/>;LIBRARY_PATH%%DJDIR%/lib;%DJDIR%/contrib/grx20/lib GCC_EXEC_PREFIX=%/>;GCC_EXEC_PREFIX%%DJDIR%/ [info] INFOPATH=%/>;INFOPATH%%DJDIR%/info;%DJDIR%/gnu/emacs/info INFO_COLORS=0x1f.0x31 [emacs] INFOPATH=%/>;INFOPATH%%DJDIR%/info;%DJDIR%/gnu/emacs/info [less] LESSBINFMT=*k<%X> LESSCHARDEF=8bcccbcc12bc5b95.b127.b LESS=%LESS% -h5.0.0.7.0$ [locate] +LOCATE_PATH=%DJDIR%/lib/locatedb.dat [ls] +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: [dir] +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: [vdir] +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 @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 Next Previous Contents |