Building GCC Cross compiler for Power PC - linux ----------------------------------------------- Download the latest tars binutils, glibc, glibc-linuxthreads, gcc from the gnu website - ftp://ftp.gnu.org create a working forlder (say F1) for your build. Inside that (F1), create a source folder and keep all the tars in that folder. Now untar each of the tars (binutils, gcc and glibc) in the working folder F1. Untar the glibc-linuxthreads in the glibc folder. tar x{z|j}vf "tar file name" Go into your kernel source directory (usually in /usr/src/linux-version). Go into the include directory and change the asm sym-link to point to asm-ppc (to get the kernel/sys call headers for the ppc). ln -s asm-ppc asm A) Build Binutils: As most of the sites suggest, start by building the toolchain in separate directories from where you downloaded and unzipped the sources. So, I do build-binutils, build-gcc and so on... Also, you can specify the PATH you want the cross-compiled binaries to go with --prefix option. The most convenient way is to do configure --help to know the oft needed arguments for configuration. The next step is to configure the binutils for powerpc as target. mkdir build-binutils & cd build-binutils ../binutils-2.14/configure --target=powerpc-linux --prefix=/opt/crossgcc/powerpc-linux make all install After binutils is done, add the cross-compiled binaries to your PATH by export PATH=$PATH:/opt/crossgcc/powerpc-linux/bin B) Build Minimal GCC: mkdir build-gcc & cd build-gcc ../gcc-3.3.2/configure --target=powerpc-linux --prefix=/opt/crossgcc/powerpc-linux --disable-shared --disable-threads --enable-languages=c --with-newlib make all-gcc install-gcc We faced a error here where the compilation was asking for a header file 'signal.h' which is present in the glibc package but wsa not available as glibc was not yet build. The error was displayed as follows. =================================== make \ CFLAGS="-g -O2 -W -Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -pedantic -Wno-long-long " \ CONFIG_H="config.h auto-host.h ../../gcc-3.4.0/gcc/../include/ansidecl.h" \ MAKEOVERRIDES= \ -f libgcc.mk all make[2]: Entering directory `/root/ppc_crossgcc/gcc/build-gcc/gcc' for d in libgcc nof libgcc/nof; do \ if [ -d $d ]; then true; else /bin/sh ../../gcc-3.4.0/gcc/mkinstalldirs $d; fi; \ done mkdir -p -- libgcc mkdir -p -- nof mkdir -p -- libgcc/nof if [ -f stmp-dirs ]; then true; else touch stmp-dirs; fi /root/ppc_crossgcc/gcc/build-gcc/gcc/xgcc -B/root/ppc_crossgcc/gcc/build-gcc/gcc/ -B/opt/crossgcc/powerpc-linux/powerpc-linux/bin/ -B/opt/crossgcc/powerpc-linux/powerpc-linux/lib/ -isystem /opt/crossgcc/powerpc-linux/powerpc-linux/include -isystem /opt/crossgcc/powerpc-linux/powerpc-linux/sys-include -O2 -DIN_GCC -DCROSS_COMPILE -W -Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -isystem ./include -fPIC -g -DHAVE_GTHR_DEFAULT -DIN_LIBGCC2 -D__GCC_FLOAT_NOT_NEEDED -Dinhibit_libc -I. -I -I../../gcc-3.4.0/gcc -I../../gcc-3.4.0/gcc/ -I../../gcc-3.4.0/gcc/../include -fPIC -mstrict-align -DL_muldi3 -c ../../gcc-3.4.0/gcc/libgcc2.c -o libgcc/./_muldi3.o In file included from ./tm.h:10, from ../../gcc-3.4.0/gcc/libgcc2.c:43: ../../gcc-3.4.0/gcc/config/rs6000/linux.h:100:20: signal.h: No such file or directory In file included from ./tm.h:10, from ../../gcc-3.4.0/gcc/libgcc2.c:43: ../../gcc-3.4.0/gcc/config/rs6000/linux.h:109: error: parse error before "stack_t" ../../gcc-3.4.0/gcc/config/rs6000/linux.h:109: warning: no semicolon at end of struct or union ../../gcc-3.4.0/gcc/config/rs6000/linux.h:111: error: parse error before "uc_sigmask" ../../gcc-3.4.0/gcc/config/rs6000/linux.h:111: warning: type defaults to `int' in declaration of `uc_sigmask' ../../gcc-3.4.0/gcc/config/rs6000/linux.h:111: warning: data definition has no type or storage class ../../gcc-3.4.0/gcc/config/rs6000/linux.h:110: error: storage size of `uc_mcontext' isn't known make[2]: *** [libgcc/./_muldi3.o] Error 1 make[2]: Leaving directory `/root/ppc_crossgcc/gcc/build-gcc/gcc' make[1]: *** [stmp-multilib] Error 2 make[1]: Leaving directory `/root/ppc_crossgcc/gcc/build-gcc/gcc' make: *** [all-gcc] Error 2 ========================================= To get rid of this error, applied the following patch . ========================================= --- gcc-3.4.0/gcc/config/rs6000/linux.h.orig 2004-10-03 05:43:56.000000000 +0200 +++ gcc-3.4.0/gcc/config/rs6000/linux.h 2005-02-09 14:36:33.000000000 +0100 @@ -104,6 +104,8 @@ /* Do code reading to identify a signal frame, and set the frame state data appropriately. See unwind-dw2.c for the structs. */ +#ifndef inhibit_libc + #ifdef IN_LIBGCC2 #include <signal.h> @@ -187,3 +189,5 @@ enum { SIGNAL_FRAMESIZE = 64 }; (FS)->retaddr_column = CR0_REGNO; \ goto SUCCESS; \ } while (0) + +#endif /* inhibit_libc */ ========================================= After this, the compilation should proceed without any problems. You can very well cross-compile Linux kernel with this minimal gcc, though may not be able to compile other applications. C) Build Glibc After the minimal gcc is done; the next major step is to cross-compile glibc. I have had troubles compiling glibc in the past what with some of the patches not being applied to the glibc tree. But after some help from googling, I was able to put the right combination of arguments in place. Be sure to download glibc-linuxthreads and unzip it in the glibc source directory. I found out that glibc needs linuxthreads to compile correctly. It might not be this way but I could not compile it otherwise. So, here is what to do If compiled as is, glibc would give a compile error for glibc-2.3.2/stdio-common/sscanf.c ... you have to change the parameter declaration for sscaf function in sscanf.c. In glibc-2.3.2/stdio-common/sscanf.c change the parameter declaration for the sscanf function to "int sscanf (const char *s, const char *format, ...)"; delete the former declaration which should be "int sscanf(s, f) const char*s; const char* format;" (or something similar to that). In the build-glibc directory run... mkdir build-glibc & cd build-glibc ../glibc-2.3.2/configure --prefix=/opt/crossgcc/powerpc-linux --target=powerpc-linux --host=powerpc-linux --enable-add-ons=linuxthreads --with-headers=/usr/src/linux-"version"/include/ --with-binutils=/opt/crossgcc/powerpc-linux/powerpc-linux/bin make all install It should be a breeze after that. It was worth noting that --target option does not work with glibc, you have to use --host={target-platform}-linux for glibc to work. D) Build complete GCC After glibc is compiled, you can reconfigure gcc as ../gcc-3.4.0/configure --target=powerpc-linux --prefix=/opt/crossgcc/powerpc-linux --enable-shared --enable-threads --enable-languages=c --with-cpu=405 --without-fp --with-libs=/opt/crossgcc/powerpc-linux/lib make all install Now you should have a complete working version of gcc.