Compiling and Packaging the GNU Tools under Linux or Unix

This document shows you how to compile and package the GNU Tools for the ARM microcontroller under the Linux or Unix operating systems. Doing this creates the .tar.gz package used for the standard precompiled binary image installation for Linux and generates the GNU Tools documentation.

Please note that you probably do not need to read this document: it is much easier to install the precompiled binary image for Linux (as found on this CD-ROM). These instructions should really only be followed by system administrators wanting to retain complete control of their system… or those wanting to update this CD-ROM.

In this document, “$” will indicate the ordinary user’s shell prompt, and “#” will indicate the root superuser’s shell prompt. Anything in a bold monospaced font is what you are expected to type in; an ordinary monospaced font is used for the computer’s response. Please note that this document doesn’t show every response from the computer!

Finally, please note that creating the GNU Tools .tar.gz package on a particular system will mean that that package will only run on computers having the same (or very similar) system libraries. More information is provided later in this document.

Minimum System Requirements

In order to successfully compile the GNU Tools, you will need to meet at least the following requirements:

1. A Linux, Unix or Unix-like operating system, with all of the usual utilities, system header files and libraries, as well as the X11 Window System (with header files and libraries), Perl, GNU gzip and bzip2,
2. An ANSI-compatible C compiler tool-set, such as the GNU Compiler Collection (gcc),
3. If you want to generate the documentation, typesetting software in the form of TeX, pdfTeX, Texinfo, Ghostscript, xpdf and friends, dvipdfm and the Type 1 (Postscript) Computer Modern Roman fonts,
4. At least 900 MB of free disk space,
5. At least two to three hours of free time, and
6. The password to the root superuser’s account on your system, or access to the fakeroot(1) program.

Step-by-step Instructions

Compiling the GNU Tools is not that complicated (although there are rather a lot of steps), but be careful that you type in the commands exactly as shown. These instructions assume that you have already mounted the CD-ROM on your computer, and that the mount point (where the CD-ROM can be found within the file system) is /mnt/cdrom. See the instructions for mounting the CD-ROM for more details.

1. Log in as an ordinary user, not as the root superuser. This is highly recommended and is standard Unix practice. In fact, you should never directly log in as the root superuser; this helps save you from your own mistakes and/or any viruses that can destroy the working of your system!
2. Create a directory to contain the sources. Note that at least 900 MB of space is required for the source code, build, installation and final output files. In this document, /var/tmp/src will be used for the sources:
mkdir /var/tmp/src
cd /var/tmp/src
3. Locate the appropriate sources, either on this CD-ROM, or by downloading the source code archives from the Internet. Assuming the CD-ROM is mounted on /mnt/cdrom, the source code archives can be found in [List] /mnt/cdrom/gnutools/src.
4. Unpack the sources:
gzip -dc /mnt/cdrom/gnutools/src/binutils-2.14.tar.gz | tar xv
gzip -dc /mnt/cdrom/gnutools/src/gcc-core-3.3.tar.gz | tar xv
gzip -dc /mnt/cdrom/gnutools/src/gcc-g++-3.3.tar.gz | tar xv
gzip -dc /mnt/cdrom/gnutools/src/insight-5.3.tar.gz | tar xv
gzip -dc /mnt/cdrom/gnutools/src/newlib-1.11.0.tar.gz | tar xv
gzip -dc /mnt/cdrom/gnutools/src/make-3.80.tar.gz | tar xv
If your version of tar is compatible with GNU tar, you can use tar xzvf ... instead of gzip -dc ... | tar xv: this will save a couple of minutes…
If you are using sources that you downloaded from the Internet, you would replace /mnt/cdrom/gnutools/src with the location of those sources, of course. Archives having .tar.gz on the end of their filename require GNU gzip; those with .tar.bz2 require bzip2.
5. Apply the appropriate patches (on this CD-ROM, or from the Internet) to the sources:
gzip -dc /mnt/cdrom/gnutools/src/binutils-2.14.patch.gz | patch -p0
gzip -dc /mnt/cdrom/gnutools/src/gcc-3.3.patch.gz | patch -p0
gzip -dc /mnt/cdrom/gnutools/src/insight-5.3.patch.gz | patch -p0
gzip -dc /mnt/cdrom/gnutools/src/newlib-1.11.0.patch.gz | patch -p0
gzip -dc /mnt/cdrom/gnutools/src/make-3.80.patch.gz | patch -p0
Please note that parts of these patches may not need to be applied to later versions of the GNU Tools. You are on your own if you decide to use versions of software different from those described in this document! However, you might like to see if later versions of the patches exist on the Internet before giving up.
6. Create a directory that will contain the combined sources and change to it:
mkdir combined
cd combined
7. Create symbolic links to the real source code files for the binutils, gcc and newlib packages, using the symlink-tree script that is supplied on the CD-ROM:
/mnt/cdrom/utils/unsw/src/symlink-tree ../binutils-2.14 ../gcc-3.3 ../newlib-1.11.0
Please note that you may need to insert a corrective step (essentially, step 7a) after doing this to fix up certain symbolic links, depending on the version numbers of the archive files. See the section on common problems for more details. This corrective step is not necessary with gcc 3.3 and binutils 2.14.
8. Create a separate directory in which to build the sources. In this document, /var/tmp/build will be used:
mkdir /var/tmp/build
cd /var/tmp/build
mkdir combined insight-5.3 make-3.80
9. Configure the combined sources:
cd /var/tmp/build/combined
/var/tmp/src/combined/configure --target=arm-elf --with-newlib
Please note that you can (and should) specify compiler options on the command line. Assuming you are using the bash shell, you can do this by specifying variable definitions in front of configure. The following command line, for example, specifies gcc-3.3 as the C compiler and enables both optimisation level 2 and debugging (the -O2 and -g compiler options, respectively):
CC=gcc-3.3 CFLAGS="-O2 -g" /var/tmp/src/combined/configure --target=arm-elf --with-newlib
If you do specify compiler options on the command line, you will need to do so for step 10 as well.
10. Configure insight. This package requires the X11 Window System header files and libraries:
cd ../insight-5.3
/var/tmp/src/insight-5.3/configure --target=arm-elf
11. Compile the combined sources. Once you have issued this command, you can go for an extended coffee break…
cd ../combined && make all && cd ../insight-5.3 && make all && cd ../combined
(If the compilation terminates with an error, read the section on common problems for some suggestions of what you should check.)
12. Create an installation directory. In this document, /var/tmp/install will be used:
mkdir /var/tmp/install
mkdir /var/tmp/install/usr
mkdir /var/tmp/install/usr/local
(By the way, if you are a Unix guru, you are probably wondering why the above commands don’t simply use the -p flag with mkdir. The reason is that not all Unix systems support this flag. If your’s does, by all means, use it! See mkdir(1) for more details.)
13. Create the final package and documentation directory. In this document, /var/tmp/final will be used:
mkdir /var/tmp/final
14. Still in the /var/tmp/build/combined directory, change to the root superuser’s account, or use the fakeroot command to emulate it. Either:
/bin/su
or (preferred):
fakeroot
(You should use the fakeroot command if at all possible, since it does not use the root superuser’s account — it emulates it instead. This means, for example, that your system will be kept more secure against any accidents or problems. Unfortunately, this command is usually only found on Debian GNU/Linux systems, although you could download the source code and compile it for yourself. See the Debian fakeroot package page on the Web for more information.)
15. Install the GNU Tools to the installation directory:
cd ../combined
make prefix=/var/tmp/install/usr/local LN_S="ln -s" LDFLAGS=-s INSTALL_PROGRAM="install -c -s" install
cd ../insight-5.3
make prefix=/var/tmp/install/usr/local LN_S="ln -s" LDFLAGS=-s INSTALL_PROGRAM="install -c -s" install
16. Change to the installation directory and create the package file. You should substitute arch with an appropriate architecture, such as linux-i386, and date with an appropriate date, such as 2003-06:
cd /var/tmp/install
tar cvf /var/tmp/final/arm-elf-gnutools-arch-date.tar usr
gzip -9 /var/tmp/final/arm-elf-gnutools-arch-date.tar
17. Create the uninstallation program, using the mkuninst script found on the CD-ROM:
cd /var/tmp/final
/mnt/cdrom/utils/unsw/src/mkuninst -F arm-elf-gnutools-arch-date.tar.gz
exit
18. You have successfully compiled the GNU Tools for the ARM microcontroller! The remaining steps generate the documentation for these tools as PDF files. If you do not need the GNU Tools documentation, you may safely skip to step 29.
19. Create preliminary documents for the newlib package. You should still be in the /var/tmp/build/combined directory:
cd arm-elf/newlib/libc
make targetdep.tex
cd ../libm
make targetdep.tex
cd ../../..
20. Create DVI files for all of the documentation. This requires TeX and Texinfo, of course:
make LN_S="ln -s" dvi
cd ../insight-5.3
make LN_S="ln -s" dvi
cd ../combined
21. Generate the necessary figures used in one of the documents:
cd etc
for q in /var/tmp/src/combined/etc/*.ein; do
sed -e 's/^%%Orientation: Portrait$/%%Orientation: Landscape/' < $q \
| epstopdf -f -o `basename $q .ein`.pdf
done
cd ../..
(By the way, once you enter the second line, your shell prompt will change, from whatever you usually have, to “>”. That is why “>” is shown above instead of “$”.)
22. Generate the PDF version of the document files:
for q in `find . -name '*.dvi'`; do
d=`dirname $q`; f=`basename $q`
( cd $d; mv $f $f.orig
make TEXI2DVI="texi2dvi --pdf" $f
mv $f.orig $f )
done
23. Create the reference card for the GNU Debugger:
cd insight-5.3/gdb/doc
make refcard.pdf
24. Create the documentation for the libiberty library:
cd ../../../arm-elf/libiberty
texi2dvi --pdf /var/tmp/src/combined/libiberty/libiberty.texi
cd ../../..
25. Copy the necessary files into the final directory:
cp -p combined/arm-elf/libiberty/libiberty.pdf /var/tmp/final/gnu-libiberty.pdf
cp -p combined/arm-elf/newlib/libc/libc.pdf /var/tmp/final/newlib-c-library.pdf
cp -p combined/arm-elf/newlib/libm/libm.pdf /var/tmp/final/newlib-math-library.pdf
cp -p combined/binutils/doc/binutils.pdf /var/tmp/final/gnu-binary-utilities.pdf
cp -p combined/etc/configure.pdf /var/tmp/final/gnu-configure-build.pdf
cp -p combined/etc/standards.pdf /var/tmp/final/gnu-coding-standards.pdf
cp -p combined/gas/doc/as.pdf /var/tmp/final/gnu-assembler.pdf
cp -p combined/gcc/cpp.pdf /var/tmp/final/gnu-c-preprocessor.pdf
cp -p combined/gcc/cppinternals.pdf /var/tmp/final/gnu-c-preprocessor-internals.pdf
cp -p combined/gcc/gcc.pdf /var/tmp/final/gnu-compiler.pdf
cp -p combined/gcc/gccint.pdf /var/tmp/final/gnu-compiler-internals.pdf
cp -p combined/ld/ld.pdf /var/tmp/final/gnu-linker.pdf
cp -p insight-5.3/gdb/doc/gdb.pdf /var/tmp/final/gnu-debugger.pdf
cp -p insight-5.3/gdb/doc/gdbint.pdf /var/tmp/final/gnu-debugger-internals.pdf
cp -p insight-5.3/gdb/doc/refcard.pdf /var/tmp/final/gnu-debugger-quickref.pdf
26. Configure the GNU Make package. You will not be building this package (since you already have make(1) on your system), but you will generate the appropriate documentation:
cd /var/tmp/build/make-3.80
/var/tmp/src/make-3.80/configure
27. Generate the reference manual for GNU Make:
make TEXI2DVI="texi2dvi --pdf" dvi
28. Copy the document into the final directory:
cp -p doc/make.pdf /var/tmp/final/gnu-make.pdf
29. (Optional) Remove the source code, build and installation files to reclaim about 850 MB of disk space (the final package and documentation files take about 50 MB of space):
cd /var/tmp
rm -fr src build install
30. You have successfully compiled the GNU Tools for the ARM microcontroller! You can find the final package and documentation files (if generated) in the /var/tmp/final directory.

Dependencies on System Libraries

Warning: Compiling the GNU Tools automatically creates a number of dependencies on the system shared libraries. This means that the resulting package must be run on a system with the same versions of the same libraries, or sometimes on a system with newer versions of the same libraries. This means that you will need to consider the version numbers of the libraries on the target system when creating the GNU Tools package. For best results, you should compile the GNU Tools on a system that is as close as possible to the target… preferrably even compile the tools on the target system.

For example, compiling the GNU Tools on a Debian GNU/Linux 3.0 system (which has Version 2.2.5 of the GNU C Library, found as the file /lib/libc-2.2.5.so) will result in a package can be run on any system with Version 2.2.5 (or possibly later versions) of the GNU C Library. It will not run on a system with Version 2.2.2 or earlier of the library! Similarly, compiling the GNU Tools on a system with Version 2.3.1 of the GNU C Library will mean that the tools will not work on a system with only Version 2.2.x of the library (for some value x).

Determining whether a later version of the system libraries will work with a particular package is not particularly hard. The key to doing so is to check the shared object version number of the shared library being used on the compiling system: all target systems having the same shared object version number will work correctly. Please notice that this shared object version number may not be the same as the library package number!

As an example, the GNU Tools package uses the GNU C Library on Linux systems. Thus, on the compiling system (the computer system on which step 9 is run), typing “ls -la /lib/libc.so.*” might give you “/lib/libc.so.6 -> libc-2.2.5.so”. This means that the GNU Tools package will depend on shared object version 6 of the GNU C Library (which corresponds to Version 2.2.5 of that Library on this system). Hence, any system with shared object version 6 will be able to use the package, as long as the real library version number is also greater than 2.2.5.

You can determine the shared object version numbers that you need by installing the GNU Tools package on your compiling system (by following instructions similar to the Linux pre-compiled package installation document), then typing:

ldd /usr/local/bin/* /usr/local/arm-elf/* | awk '{print $3}' | sort | uniq | grep '^/'

This command line assumes that you have the ldd(1) command on your system; you may have to replace this command with something appropriate to your system if your system is not using the GNU C Library.

Common Problems

In most cases, you will not encounter any problems in compiling the GNU Tools. There might be exceptions, however. The following is a list of things you should check if the compilation (the “make all” step) terminates with an error:

1. Check that you entered all commands exactly as specified. Please note that your browser may split up commands over a number of lines (depending on the width of your browser window); that does not mean you do the same! Each shell prompt (“$”, “#” or “>”) indicates a single command line.
2. One of the non-obvious things to check is that the /usr/local/arm-elf/sys-include directory does not exist on your system. If it does exist, remove it and reissue make all. If that still fails, type rm -fr /var/tmp/build/combined/*, then jump back to step 9.
3. The method of compilation described in this document sometimes fails due to version mismatches of files in shared directories. The usual symptom is an error message that a particular function or include file could not be found (an “undefined reference”). Fixing this requires you to experiment a little with the symlink-tree program (used in step 7). It helps to understand just what is going on.
All of the individual components (source code archives) that form part of the GNU Tools are generated from a single CVS repository. Parts of these archives are directories that are shared between various components. Sometimes these shared directories can become “out of sync” with each other: this happens if the individual components are released at different times, and development continues on files in those shared directories in the meantime.
This problem is a real one for some versions of binutils and gcc! You may need to rearrange the order of directories listed in the symlink-tree command line (step 7) before you proceed to step 9: in general, the package that was released later (by date) is listed before an older package. Alternatively, you can experiment with the following command lines to fix the problem:
cd /var/tmp/src/combined
for d in include libiberty; do
( cd $d
for q in `ls -lA | grep gcc | awk '{print $9}'`; do
if [ -e ../../binutils-version/$d/$q ]; then
echo $d/$q; rm $q; ln -s ../../binutils-version/$d/$q
fi; done
); done
(Note the use of the back-tick character “`” in these command lines. You also need to replace version with the version number of the binutils package, such as 2.13.2.1)
If you get as far as step 10 before you realise that you need to perform these acrobatics, you will need to delete everything in /var/tmp/build/combined (try rm -fr /var/tmp/build/combined/*), fix what is needed, then jump to step 9.

If none of these suggestions help you, it is probably time to search for answers on the Internet, or to consult expert help. Happy compiling!