Handhelds.org - Open source for handheld devices

UserPreferences

BuildCrossToolchainHowto


HOWTO Build a Cross Toolchain in Brief

Most of the time you're better off using one of the PrebuiltToolchains, however if for some reason they are insufficient for your needs, or you just want to get a better idea of how things work, this document is for you. Some attemps at automating the process have been made over in GNU Toolchain Projects at http://www.handhelds.org/projects/toolchain/index.html , and a generic GNU Toolchain for ARM targets HOWTO is at http://www.armlinux.org/docs/toolchain/ . See also the generic toolchain build-and-test script at http://kegel.com/crosstool .

There also exist some tips and tricks on [Porting Software to ARM Linux].

I think this document is accurate. Some testing has been done and all tests were successful. However, this is a very complex system and testing it in it's entirety is difficult at best. Feel free to use this document, but use care. If you find any problems (especially ones you can fix) please let us know. KenCausey*

On 5-Feb-2004, I followed these instructions to build a toolchain using gcc-3.3-cvs, binutils-031031, and glibc-2.3.2, from the handhelds ftp site with kernel2419 from handhelds CVS. With minor tweaks that I've added to the instructions (and the hacks on the CrossToolchainHacksPage) I made it work.

Building a new tool chain is easy:

Note: In the examples in this HOWTO we are going to build an ARM cross tool chain using /usr/src/ as the source directory, /usr/src/build/ as the build directory, and /skiff/local/ as the installation prefix.

All of the following source code can be found in ftp://ftp.handhelds.org/projects/toolchain/source

  1. Get the source code for the Bin Utilities - binutils-2.9.5.0.22

  2. Get source code for GCC - gcc-2.95.2

  3. Get source code glibc - glibc-2.1.2

  4. Unpack the above programs in your source directory, we'll use /usr/src.

  5. Get gcc difference for Arm - gcc-2.95.2-diff-991022 (apply this with patch -p0 <../gcc-2.95.2-diff-991022 from the gcc source directory assuming the patch is in the parent directory.)

  6. Get the gcc patch for fold-const.c - gcc-fold-const.patch (apply this patch with 'patch -p0 <../../gcc-fold-const.patch' from the gcc subdirectory of the gcc source directory assuming that the patch is in the parent directory of the gcc source directory)

  7. Get glibc-crypt-2.0.111 and glibc-linuxthreads-2.1.2.tar.gz and extract each in the glibc source directory.

  8. Create the build directories

  9. Build the Bin Utilities

  10. Build gcc without glibc using the new Bin Utilities

  11. Build glibc

  12. Build gcc with glibc using the new Bin Utilities - I'm almost certain that this step is identical to the next one.

  13. Build the other GNU languages with the new gcc

  14. Be Happy. Every thing should work except for CHILL.


Create the Build directories

I highly recommend that the Tool Chain be built into a separate directory other than the sources and that that directory not reside within the source tree. Building the Tool Chain where srcdir == objdir could still work, but doesn't get extensive testing; building where objdir is a subdirectory of srcdir is unsupported:

cd /usr/src
mkdir build
cd build
mkdir binutils-2.9.5.0.22
mkdir gcc-2.95.2
mkdir glibc-2.1.2

Build the Bin Utilities

  1. Choose the prefix for the new tool chain. This is a fixed directory where the tool chain will forever reside, unless you re-build to tool chain. For example: /usr/local or /skiff/local. We will use /skiff/local in this document.

  2. Choose the target for the new tool chain. We will us arm-linux, there are other options but you will know if you need them.

  3. Choose the host, if you wish. If you do not choose, then the bin utils will use the machine type of your machine. For example, if you are creating the bin utils on an i586 then you will need an i586 or better to use the new bin utils.

  4. In the 'binutils' build directory (/usr/src/build/binutils-2.9.5.0.22/) type::

    /usr/src/binutils-2.9.5.0.22/configure --target=arm-linux --prefix=/skiff/local --host=i386
    make
    make install
    

    You will find a new set of bin utils at /skiff/local/bin. Be sure to add this directory to your PATH.

Build gcc (the hard way) without glibc

  1. Make your Kernel headers available to the new compilers:

  2. Type:

    cd /usr/src/gcc-2.95.2/gcc/config/arm
    

  3. Use your favorite editor to modify the file t-linux. Append -Dinhibit_libc -D__gthr_posix_h to the line that starts TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC. Which should result in:

    TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC -Dinhibit_libc -D__gthr_posix_h
    

  4. Type:

    cd /usr/src/build/gcc-2.95.2
    

  5. Add /skiff/local/bin to your PATH. If you are using the bash shell type: export PATH=/skiff/local/bin:$PATH

  6. Type:

    /usr/src/gcc-2.95.2/configure --target=arm-linux --host=i386-pc-linux-gnu  --prefix=/skiff/local --disable-threads --with-cpu=strongarm110 --enable-languages=c
    

    At this point, only the gcc portion can be built and installed. Later once gcc and glibc have been installed, the rest can be built.

  7. Type:

    make
    

    (Note that it may error when configuring libiberty - this is ok, just continue..) (Note you need autoheader to make this work, autoheader is in the package autoconf) (If you get an error on "crti.o", try doing make -i LANGUAGE=c, and then make -i LANGUAGES=c install)

  8. Type:

    make install
    

  9. In the /skiff/local/bin directory you should now find a program arm-linux-gcc this is the new c compiler from an i386 host to an arm4l target without threads or glibc.

  10. In the final 2 steps we need to configure arm-linux-gcc for arm4l targets, type:

    cd /skiff/local/lib/gcc-lib/arm-linux/2.95.2
    

  11. Use your favorite editor to modify the file specs, to get the correct behaviour from gcc. If you are using gcc-2.95.2 from ftp://ftp.handhelds.org then this change has probably already been made, but check that the *link section of your specs file is as follows:

    *link:
    %{h*} %{version:-v}    %{b} %{Wl,*:%*}    %{static:-Bstatic} %{shared:-shared}    %{symbolic:-Bsymbolic}    %{rdynamic:-export-dynamic} %{!dynamic-linker: -dynamic-linker /lib/ld-linu*so.2}    -X    %{mbig-endian:-EB} %{mapcs-26:-m armelf_linux26} %{!mapcs-26:-m armelf_linux} -p
    

Building glibc

  1. Type:

    cd /usr/src/build/glibc-2.1.2
    

  2. Type:

    /usr/src/glibc-2.1.2/configure arm-linux --build=i386-pc-linux-gnu --prefix=/skiff/local/arm-linux --enable-add-ons=linuxthreads,crypt
    

    For later versions of glibc, you'll want to add --host=arm-linux.

  3. Type:

    make
    

    If you get: error: asm-specifier for variable _a1 conflicts with asm clobber list, then apply the glibc_a1 hack on the CrossToolchainHacksPage.

    If you get: error: va_start used in function with fixed args, then apply the va_start hack on the CrossToolchainHacksPage.

    If you get: Error: garbage following instruction ldr lr,[sp],#4 ldr ip,=__libc_multiple_threads, then apply the sysdep hack on the CrossToolchainHacksPage.

  4. Type:

    make install
    

Building GCC with threads and additional languages

  1. Type:

    cd /usr/src/gcc-2.95.2/gcc/config/arm
    

  2. Use your favorite editor to modify the file t-linux to remove -Dinhibit_libc -D__gthr_posix_h from the line that starts TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC. The result should be:

    TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer - fPIC
    

  3. Type:

    cd /usr/src/gcc-2.95.2/libchill
    

    (If you do not have the libchill directory, then presumably you can skip this step.)

  4. Use your favorite editor to modify the file basicio.c by inserting after line 40 a new line #define PATH_MAX 4095.

    (This file (basicio.c) is not present in gcc-3.3.)

  5. Type:

    cd /usr/src/build/gcc-2.95.2
    

  6. Type:

    rm -rf *
    

  7. Type:

    /usr/src/gcc-2.95.2/configure --target=arm-linux --host=i386-pc-linux-gnu  --prefix=/skiff/local --with-cpu=strongarm110
    

    (For kicks, I added --with-cpu=xscale, but I'm not sure it matters Anyone?)

    If you get an error on libc.so: file format not recognized; treating as linker script, then apply the arm_lib hack from the CrossToolchainHacksPage.

  8. Type:

    make
    

    If you're using a newer version of gcc (>=3) and get an error like this: storage class specified for parameter `type name', apply the __thread hack from the CrossToolchainHacksPage.

  9. Type:

    make install
    

Look in the /skiff/local/bin directory everthing should be there. At this time the GCC testsuite is not supported.

That's all folks.

Author: GeorgeFrance

Editor: KenCausey (you can blame me for all the typos and errors )

Notes

I tried using the toolchain script but couldn't get it to compile without errors (2006-06-18). As it's not that easy to spot the problem in that script, I reverted to compiling everything by hand.

Above procedure works for more recent versions of binutils, GCC and glibc with some minor modifications, too. Here are some hints if it doesn't work for you:

Good luck!

-- WolfgangKempin 2006-06-19 10:17:01