#!/bin/bash # # We force bash, because csh/ash # may not work with the variables # # make.sh: All-in-One Single-Pass Cross-Compiler Build Script Doohickey # # (c) 2001, David A. Desrosiers # hacker at gnu dash designs dot com # ################## # # License # ################## # # This script is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2 of the License, or (at your option) # any later version. # # This script is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., 59 # Temple Place - Suite 330, Boston, MA 02111-1307, USA. # ################### # # Portions of this script were taken from a similar script I found on the # web awhile back, but have long since forgotten where, author unknown. If # anybody knows, please email me so I can give proper credit. # # This script can be run as a normal user (or root if you want to install # the packages to a non-standard path), and will completely build a # cross-development toolchain, plus kernel (alternately), for *-linux in # general. The target arm-linux was used in testing, though any other # architecture is possible here, and the basic flow holds for building any # other cross-build environment. # # This script only very weakly depends on the host system, as long as it has # a halfway-working gcc and gmake or make. This script was tested on # i686-unknown-linux-gnu, Sparc E3500, kernel-2.4.6-pre5, gcc-2.95.3, make # and gmake-3.79.1, glibc-2.2.3 # # Many different HOWTO documents were read, digested, tested, corrected, and # discarded in the process of developing this script. You can find some of # them by using your favorite search engine, or follow the following links # to see some good examples: # # http://www.armlinux.org/docs/toolchain/toolchHOWTO/x183.html # http://handhelds.org/z/wiki/HOWTO%20Build%20a%20Cross%20Toolchain%20in%20Brief # http://bytesex.org/cross-compiler.html # http://www.objsw.com/CrossGCC/FAQ-4.html # http://www.macbsd.com/macbsd/howto/cc-HOWTO # http://www.xraylith.wisc.edu/~khan/software/gnu-win32/cygwin-cross-howto.txt # http://www.xraylith.wisc.edu/~khan/software/gnu-win32/mingw-cross-howto.txt # http://www.multimania.com/pmandin/en/howto/cross295.html # http://www.delorie.com/howto/djgpp/linux-x-djgpp.html # # After days of frustration following these and similar other documents and # HOWTOs, and asking dozens of people in various irc channels, I got # frustrated and decided to start scripting this all out in one fell swoop. # I picked up that old script I had lying around here, and touched it up # quite a bit to get it working for this process. Originally I was using it # to build prc-tools, but this is just as applicable. # # It's purposely over-commented, because I already get too much email # ################## # # TODO List: # ################## # # 2001-12-31 David A. Desrosiers # # * Wow, what a bonehead. I left one space between each var, not allowed. # Fixed. # # 2001-08-29 David A. Desrosiers # # * Oops! My bad, fixed a bug in the indenting of the declared variables. # I'm so used to making things line up in perl, that I forgot you can't # do that in shell. Fixed. # # 2001-08-29 David A. Desrosiers # # * From a Linuxworld BOF on Embedded Linux, I have some more ideas for # this to make it a bit more robust, smarter, and fault-tolerant. # Anyone who cares to update this please let me know, and send me a # patch! # # 2001-06-24 David A. Desrosiers # # * The script needs to be a bit smarter than it is at the moment. When # you abort the script and run it again, it should clean up and # restart, instead of error out. # ############################################################################# set -e ############################################################################# # # Set some basic variables here for architecture, path, install prefix and # others. # # ARCH = target architecture, what we are building FOR # # HOST = what architecture is THIS build process running # on? We use config.guess in this case, because it is the most # accurate. The latest copy of this can be found at the following # url: ftp://ftp.gnu.org/pub/gnu/config/ # # TARGET = binary target name(s) # # PRISTINE = path to the clean, untouched # (unpacked) sources # # BUILD = path to the temporary build directories. We do *NOT* run # ./configure inside the source trees directly! # # PREFIX = final resting place on disk where the compiled objects will # reside # # HEADERS = path to where the (patched) kernel headers reside. This *MUST* # end in '/include' or you'll have a mess in your target tree # when files are copied over to $PREFIX # ############################################################################# WORKDIR=/src/compiling/cross ARCH=arm HOST=`sh $WORKDIR/config.guess` TARGET=$ARCH-linux PRISTINE=/src/compiling/cross BUILD=/src/compiling/cross/build PREFIX=/usr/local/cross HEADERS=/usr/src/arm-linux-2.4/include ############################################################################# # # Set your versions here, without this, everything below will fail in # wonderfully-undesirable ways. This is basically the version number # directly from the tarball itself, minus the '.tar.gz' part, so if # you have 'gcc-3.2.1.tar.gz', you'd put 'gcc-3.2.1' for GCC below. # # Sources: # # Binutils.......: ftp://ftp.gnu.org/pub/gnu/binutils/ # gcc............: ftp://ftp.gnu.org/pub/gnu/gcc/ # glibc..........: ftp://ftp.gnu.org/pub/gnu/glibc/ # gdb............: ftp://ftp.gnu.org/pub/gnu/gdb/ # config.guess...: ftp://ftp.gnu.org/pub/gnu/config/config.guess ############################################################################# BINUTILS=binutils-2.11 GCC=gcc-2.95.3 GLIBC=glibc-2.2.3 if [ ! -d $PRISTINE -o ! -d $BUILD -o ! -d $PREFIX ]; then echo "$0: configuration error" exit fi KERNELHOME=/usr/src/arm-linux-2.4 PATH=$PREFIX/bin:$PATH ############################################################################# # # Verify variables before we start. MAKE SURE THESE ARE RIGHT! # ############################################################################# echo "### PATHS ####################################" echo "Target architecture : $TARGET" echo "Virgin source directory : $PRISTINE" echo "Installation prefix : $PREFIX" echo "" echo "### TOOLS ####################################" echo "binutils version : $BINUTILS" echo "gcc version : $GCC" echo "glibc version : $GLIBC" echo "" echo "" echo "Pausing for 5 seconds, hit ^C to quit, or wait to continue" sleep 5 ############################################################################# # # configure, build, and install binutils # ############################################################################# echo "#################################################" echo "### building $BINUTILS"; date echo "#################################################" cd $BUILD mkdir $BINUTILS-$ARCH cd $BINUTILS-$ARCH $PRISTINE/$BINUTILS/configure --prefix=$PREFIX --target=$TARGET --with-headers=$HEADERS make make install ############################################################################# # # configure the kernel for the target architecture # ############################################################################# echo "#################################################" echo "### configuring kernel for $TARGET-linux"; date echo "#################################################" cd $KERNELHOME # Currently commented out while testing #make mrproper #make oldconfig # $PREFIX/$TARGET/include was created by the install of binutils Should we # "cp -a" instead of "ln -s"? certainly not now, because it doesn't include # version.h yet. # # gcc config (coming up) will look for $PREFIX/$TARGET/sys-include/limits.h, # to decide whether or not to chain its limits.h via #include_next. We need # that test to succeed. # #( cd $PREFIX/$TARGET # mkdir -p include # ln -s include sys-include # cd include # ln -s $KERNELHOME/include/asm-$ARCH asm # ln -s $KERNELHOME/include/linux linux #) ############################################################################# # # configure and build the first pass of gcc, we will need two of these. The # first one is built without threads or glibc support. It is then used to # build glibc itself, then gcc is built a second time, but this time with # glibc and thread support. # ############################################################################# echo "#################################################" echo "### configuring $GCC without glib"; date echo "#################################################" # consider using a path such as $GCC-$ARCH-nolibc, which should be totally # separate from the second build directory and structure. Not necessary, # just being anal. cd $BUILD mkdir $GCC-$ARCH cd $GCC-$ARCH $PRISTINE/$GCC/configure --target=$TARGET --prefix=$PREFIX --enable-languages=c --disable-threads --with-headers=$HEADERS --with-cpu=strongarm110 ############################################################################# # patch gcc/Make-target and gcc/Makefile for the first compile phase, that # happens without use of glibc. The Makefiles really ought to leave a # better hook for this step. I tried overriding the variables from the # command line, but they don't propagate to make in the gcc subdir. ############################################################################# ( cd gcc mv Make-target Make-target.orig sed -e '/^TARGET_LIBGCC2_CFLAGS/s/$/ -Dinhibit_libc -D__gthr_posix_h/' \ -e 's/ _dvmd_lnx$/ _dvmd_tls/' \ Make-target mv Makefile Makefile.orig sed -e '/^TARGET_LIBGCC2_CFLAGS/s/$/ -Dinhibit_libc -D__gthr_posix_h/' \ -e 's/ _dvmd_lnx$/ _dvmd_tls/' \ Makefile ) make ############################################################################# # # Q: Why do we get... # # checking whether the C compiler (/src/compiling/cross/build/gcc-2.95.3-arm/gcc/xgcc -B/src/compiling/cross/build/gcc-2.95.3-arm/gcc/ -B/usr/local/cross/arm-linux/bin/ -g -O2 ) works... no # configure: error: installation or configuration problem: C compiler cannot create executables. # # ...near the end of that last "make"? # # A: ld: cannot open crt1.o: No such file or directory # # Check the config.log in the $GCC/gcc directory for the exact error, it # should be obvious and will be one of two things, either a missing # crt1.o (or a path which it searched for was wrong), or missing headers # (again, a broken path). # ############################################################################# make install ############################################################################# # # Actually go through the steps and build the linux kernel for the target # architecture, using the configured sources built several steps up # ############################################################################# # # See below: This has to happen before glibc build, and therefore also # before the second stage of the gcc build. echo "#################################################" echo "### building the linux kernel now"; date echo "#################################################" #cd $KERNELHOME #make dep #make zImage ############################################################################# # # configure, build, and install glibc +crypt +linuxthreads # # If we're using glibc 2.1.x or earlier, you will need to add 'crypt' to the # enable-add-ons line. Since we're using 2.2.3 in this script, and crypt is # now part of glibc, we no longer need to statically declare it (and doing # so will cause ./configure to throw an error) # ############################################################################# echo "#################################################" echo "### building $GLIBC now"; date echo "#################################################" cd $BUILD mkdir $GLIBC-$ARCH cd $GLIBC-$ARCH # The following step needs to find , so it has to happen # after a real build of the kernel. Or, as the glibc FAQ 1.8 suggests, # after `make include/linux/version.h'. CC=$TARGET-gcc $PRISTINE/$GLIBC/configure $TARGET --build=$HOST --prefix=$PREFIX/$TARGET --with-headers=$HEADERS --enable-add-ons=linuxthreads --program-prefix=$TARGET- make make install ############################################################################# # # Now we can go back and re-build gcc with glibc, g++, and threads support # ############################################################################# echo "#################################################" echo "### building $GCC second pass"; date echo "#################################################" cd $BUILD/$GCC-$ARCH $PRISTINE/$GCC/configure --target=$TARGET --prefix=$PREFIX --enable-languages=c,c++ --with-headers=$HEADERS --with-cpu=strongarm110 make clean make make install echo "#################################################" echo "### DONE! Congratulations!!!"; date echo "#################################################" ##### # EOT # David A. Desrosiers