1#!/bin/bash 2# 3# Copyright (C) 2008-2009 by coresystems GmbH 4# written by Patrick Georgi <patrick.georgi@coresystems.de> and 5# Stefan Reinauer <stefan.reinauer@coresystems.de> 6# 7# This program is free software; you can redistribute it and/or modify 8# it under the terms of the GNU General Public License as published by 9# the Free Software Foundation; version 2 of the License. 10# 11# This program is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15# 16# You should have received a copy of the GNU General Public License 17# along with this program; if not, write to the Free Software 18# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 19# 20 21CROSSGCC_DATE="August 18th, 2009" 22CROSSGCC_VERSION="0.9" 23 24# default settings 25TARGETDIR=`pwd`/xgcc 26TARGETARCH=i386-elf 27DESTDIR= 28 29# version numbers 30GMP_VERSION=4.3.1 31MPFR_VERSION=2.4.1 32GCC_VERSION=4.4.1 33BINUTILS_VERSION=2.19.1 34GDB_VERSION=6.8 35 36# archive locations 37GMP_ARCHIVE="ftp://ftp.gmplib.org/pub/gmp-${GMP_VERSION}/gmp-${GMP_VERSION}.tar.bz2" 38MPFR_ARCHIVE="http://www.mpfr.org/mpfr-current/mpfr-${MPFR_VERSION}.tar.bz2" 39GCC_ARCHIVE="ftp://ftp.gwdg.de/pub/gnu/ftp/gnu/gcc/gcc-${GCC_VERSION}/gcc-core-${GCC_VERSION}.tar.bz2" 40BINUTILS_ARCHIVE="http://ftp.gnu.org/gnu/binutils/binutils-${BINUTILS_VERSION}.tar.bz2" 41GDB_ARCHIVE="http://ftp.gnu.org/gnu/gdb/gdb-${GDB_VERSION}.tar.bz2" 42 43GMP_DIR="gmp-${GMP_VERSION}" 44MPFR_DIR="mpfr-${MPFR_VERSION}" 45GCC_DIR="gcc-${GCC_VERSION}" 46BINUTILS_DIR="binutils-${BINUTILS_VERSION}" 47GDB_DIR="gdb-${GDB_VERSION}" 48 49SAVETEMPS=0 50 51red='\e[0;31m' 52RED='\e[1;31m' 53green='\e[0;32m' 54GREEN='\e[1;32m' 55blue='\e[0;34m' 56BLUE='\e[1;34m' 57cyan='\e[0;36m' 58CYAN='\e[1;36m' 59NC='\e[0m' # No Color 60 61searchgnu() 62{ 63 # $1 short name 64 # result: GNU version of that tool on stdout 65 # or no output if no GNU version was found 66 for i in "$1" "g$1" "gnu$1"; do 67 if test -x "`which $i 2>/dev/null`"; then 68 if test `$i --version 2>/dev/null |grep -c GNU` -gt 0; then 69 echo $i 70 return 71 fi 72 fi 73 done 74 printf "${RED}ERROR:${red} Missing toolchain: $1${NC}\n" >&2 75 exit 1 76} 77 78TAR=`searchgnu tar` 79PATCH=`searchgnu patch` 80MAKE=`searchgnu make` 81 82cleanup() 83{ 84 printf "Cleaning up temporary files... " 85 rm -rf build-* combined gcc-* gmp-* mpfr-* binutils-* gdb-* 86 printf "${green}ok${NC}\n" 87} 88 89myhelp() 90{ 91 printf "Usage: $0 [-V] [-c] [-p <platform>] [-d <target directory>] [-D <dest dir>]\n" 92 printf " $0 [-V|--version]\n" 93 printf " $0 [-h|--help]\n\n" 94 95 printf "Options:\n" 96 printf " [-V|--version] print version number and exit\n" 97 printf " [-h|--help] print this help and exit\n" 98 printf " [-c|--clean] remove temporary files before build\n" 99 printf " [-t|--savetemps] don't remove temporary files after build\n" 100 printf " [-p|--platform <platform>] target platform to build cross compiler for\n" 101 printf " (defaults to $TARGETARCH)\n" 102 printf " [-d|--directory <target dir>] target directory to install cross compiler to\n" 103 printf " (defaults to $TARGETDIR)\n\n" 104 printf " [-D|--destdir <dest dir>] destination directory to install cross compiler to\n" 105 printf " (for RPM builds, default unset)\n\n" 106} 107 108myversion() 109{ 110 # version tag is always printed, so just print the license here 111 112 cat << EOF 113Copyright (C) 2008-2009 by coresystems GmbH 114 115This program is free software; you can redistribute it and/or modify 116it under the terms of the GNU General Public License as published by 117the Free Software Foundation; version 2 of the License. 118 119This program is distributed in the hope that it will be useful, 120but WITHOUT ANY WARRANTY; without even the implied warranty of 121MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 122GNU General Public License for more details. 123 124EOF 125} 126 127printf "${blue}Welcome to the ${red}coresystems${blue} cross toolchain builder v$CROSSGCC_VERSION ($CROSSGCC_DATE)${NC}\n\n" 128 129# parse parameters.. try to find out whether we're running GNU getopt 130getoptbrand="`getopt -V`" 131if [ "${getoptbrand:0:6}" == "getopt" ]; then 132 # Detected GNU getopt that supports long options. 133 args=`getopt -l version,help,clean,directory:,platform:,destdir:,savetemps Vhcd:p:D:t -- "$@"` 134 eval set "$args" 135else 136 # Detected non-GNU getopt 137 args=`getopt Vhcd:p:D:t $*` 138 set -- $args 139fi 140 141if [ $? != 0 ]; then 142 myhelp 143 exit 1 144fi 145 146while true ; do 147 case "$1" in 148 -V|--version) shift; myversion; exit 0;; 149 -h|--help) shift; myhelp; exit 0;; 150 -c|--clean) shift; cleanup;; 151 -t|--savetemps) shift; SAVETEMPS=1;; 152 -d|--directory) shift; TARGETDIR="$1"; shift;; 153 -p|--platform) shift; TARGETARCH="$1"; shift;; 154 -D|--destdir) shift; DESTDIR="$1"; shift;; 155 --) shift; break;; 156 -*) printf "Invalid option\n\n"; myhelp; exit 1;; 157 *) break;; 158 esac 159done 160 161printf "Downloading tar balls ... \n" 162mkdir -p tarballs 163for ARCHIVE in $GMP_ARCHIVE $MPFR_ARCHIVE $GCC_ARCHIVE $BINUTILS_ARCHIVE $GDB_ARCHIVE; do 164 FILE=`basename $ARCHIVE` 165 printf " * $FILE " 166 test -f tarballs/$FILE && printf "(cached)" || ( 167 printf "(downloading)" 168 cd tarballs 169 wget -q $ARCHIVE 170 ) 171 test -f tarballs/$FILE || printf "Failed to download $FILE.\n" 172 test -f tarballs/$FILE || exit 1 173 printf "\n" 174done 175printf "Downloaded tar balls ... " 176printf "${green}ok${NC}\n" 177 178printf "Unpacking and patching ... \n" 179for PACKAGE in GMP MPFR GCC BINUTILS GDB; do 180 archive=$PACKAGE"_ARCHIVE" 181 archive=${!archive} 182 dir=$PACKAGE"_DIR" 183 test -d ${!dir} || ( 184 printf " * `basename $archive`\n" 185 FLAGS=zxf 186 test ${archive:${#archive}-2:2} = "gz" && FLAGS=zxf 187 test ${archive:${#archive}-3:3} = "bz2" && FLAGS=jxf 188 $TAR $FLAGS tarballs/`basename $archive` 189 for patch in patches/${!dir}"_*.patch"; do 190 test -r $patch || continue 191 printf " o `basename $patch`\n" 192 patch -s -N -p0 < `echo $patch` 193 done 194 ) 195done 196printf "Unpacked and patched ... " 197printf "${green}ok${NC}\n" 198 199mkdir -p build-gmp build-mpfr build-binutils build-gcc build-gdb 200if [ -f build-gmp/.success ]; then 201 printf "Skipping GMP as it is already built\n" 202else 203printf "Building GMP ${GMP_VERSION} ... " 204( 205 cd build-gmp 206 rm -f .failed 207 if [ `uname` = "Darwin" ]; then 208 # generally the OS X compiler can create x64 binaries. 209 # Per default it generated i386 binaries in 10.5 and x64 210 # binaries in 10.6 (even if the kernel is 32bit) 211 # For some weird reason, 10.5 autodetects an ABI=64 though 212 # so we're setting the ABI explicitly here. 213 OPTIONS="ABI=32" 214 touch .architecture_check.c 215 gcc .architecture_check.c -c -o .architecture_check.o 216 ARCH=`file .architecture_check.o |cut -f5 -d\ ` 217 test "$ARCH" = "x86_64" && OPTIONS="ABI=64" 218 rm .architecture_check.c .architecture_check.o 219 fi 220 221 ../${GMP_DIR}/configure --disable-shared --prefix=$TARGETDIR $OPTIONS \ 222 || touch .failed 223 $MAKE || touch .failed 224 $MAKE install DESTDIR=$DESTDIR || touch .failed 225 if [ ! -f .failed ]; then touch .success; fi 226) &> build-gmp/crossgcc-build.log 227test -r build-gmp/.failed && printf "${RED}failed${NC}\n" || printf "${green}ok${NC}\n" 228test -r build-gmp/.failed && exit 1 229fi 230 231#if [ "$DESTDIR" != "" -a ! -x $TARGETDIR ]; then 232# # create compat link 233# ln -s $DESTDIR$TARGETDIR $TARGETDIR 234#fi 235 236# Now set CFLAGS to match GMP CFLAGS. 237HOSTCFLAGS=`grep __GMP_CFLAGS $DESTDIR$TARGETDIR/include/gmp.h |cut -d\" -f2` 238 239if [ -f build-mpfr/.success ]; then 240 printf "Skipping MPFR as it is already built\n" 241else 242printf "Building MPFR ${MPFR_VERSION} ... " 243( 244 test `uname` = "Darwin" && CFLAGS="$CFLAGS -force_cpusubtype_ALL" 245 cd build-mpfr 246 rm -f .failed 247 ../${MPFR_DIR}/configure --disable-shared --prefix=$TARGETDIR \ 248 --infodir=$TARGETDIR/info \ 249 --with-gmp=$DESTDIR$TARGETDIR CFLAGS="$HOSTCFLAGS" || touch .failed 250 $MAKE || touch .failed 251 $MAKE install DESTDIR=$DESTDIR || touch .failed 252 253 # work around build problem of libgmp.la 254 if [ "$DESTDIR" != "" ]; then 255 perl -pi -e "s,$DESTDIR,," $DESTDIR$TARGETDIR/libgmp.la 256 fi 257 258 if [ ! -f .failed ]; then touch .success; fi 259) &> build-mpfr/crossgcc-build.log 260test -r build-mpfr/.failed && printf "${RED}failed${NC}\n" || printf "${green}ok${NC}\n" 261test -r build-mpfr/.failed && exit 1 262fi 263 264if [ -f build-binutils/.success ]; then 265 printf "Skipping binutils as it is already built\n" 266else 267printf "Building binutils ${BINUTILS_VERSION} ... " 268( 269 cd build-binutils 270 rm -f .failed 271 ../binutils-${BINUTILS_VERSION}/configure --prefix=$TARGETDIR --target=${TARGETARCH} \ 272 --disable-werror --disable-nls \ 273 CFLAGS="$HOSTCFLAGS" || touch .failed 274 $MAKE || touch .failed 275 $MAKE install DESTDIR=$DESTDIR || touch .failed 276 if [ ! -f .failed ]; then touch .success; fi 277) &> build-binutils/crossgcc-build.log 278test -r build-binutils/.failed && printf "${RED}failed${NC}\n" || printf "${green}ok${NC}\n" 279test -r build-binutils/.failed && exit 1 280fi 281 282if [ -f build-gcc/.success ]; then 283 printf "Skipping GCC as it is already built\n" 284else 285printf "Building GCC ${GCC_VERSION} ... " 286( 287 cd build-gcc 288 rm -f .failed 289 # GCC does not honour HOSTCFLAGS at all. CFLAGS are used for 290 # both target and host object files. This is pretty misdesigned. 291 # There's a work-around called CFLAGS_FOR_BUILD and CFLAGS_FOR_TARGET 292 # but it does not seem to work properly. At least the host library 293 # libiberty is not compiled with CFLAGS_FOR_BUILD. 294 CFLAGS_FOR_BUILD="$HOSTCFLAGS" ../gcc-${GCC_VERSION}/configure \ 295 --prefix=$TARGETDIR --libexecdir=$TARGETDIR/lib \ 296 --target=${TARGETARCH} --disable-werror \ 297 --disable-libssp --disable-bootstrap --disable-nls \ 298 --with-gmp=$DESTDIR$TARGETDIR --with-mpfr=$DESTDIR$TARGETDIR \ 299 || touch .failed 300 $MAKE CFLAGS_FOR_BUILD="$HOSTCFLAGS" || touch .failed 301 $MAKE install DESTDIR=$DESTDIR || touch .failed 302 if [ ! -f .failed ]; then touch .success; fi 303) &> build-gcc/crossgcc-build.log 304test -r build-gcc/.failed && printf "${RED}failed${NC}\n" || printf "${green}ok${NC}\n" 305test -r build-gcc/.failed && exit 1 306fi 307 308if [ -f build-gdb/.success ]; then 309 printf "Skipping GDB as it is already built\n" 310else 311printf "Building GDB ${GDB_VERSION} ... " 312( 313 cd build-gdb 314 export PATH=$PATH:$PREFIX/bin 315 rm -f .failed 316 ../gdb-${GDB_VERSION}/configure --prefix=$TARGETDIR --target=${TARGETARCH} \ 317 --disable-werror --disable-nls 318 $MAKE || touch .failed 319 $MAKE install DESTDIR=$DESTDIR || touch .failed 320 if [ ! -f .failed ]; then touch .success; fi 321) &> build-gdb/crossgcc-build.log 322test -r build-gdb/.failed && printf "${RED}failed${NC}\n" || printf "${green}ok${NC}\n" 323test -r build-gdb/.failed && exit 1 324fi 325 326if [ $SAVETEMPS -eq 0 ]; then 327 printf "Cleaning up... " 328 rm -rf ${GMP_DIR} build-gmp 329 rm -rf ${MPFR_DIR} build-mpfr 330 rm -rf ${BINUTILS_DIR} build-binutils 331 rm -rf ${GCC_DIR} build-gcc 332 rm -rf ${GDB_DIR} build-gdb 333 printf "${green}ok${NC}\n" 334else 335 printf "Leaving temporary files around... ${green}ok${NC}\n" 336fi 337 338printf "\n${green}You can now run your $TARGETARCH cross toolchain from $TARGETDIR.${NC}\n" 339 340 341

