#!/bin/sh # Abort execution as soon as an error is encountered # That way the script do not let the user think the process completed correctly # and leave the opportunity to fix the problem and restart compilation where # it stopped set -e # this is where this script will store downloaded files and check for already # downloaded files dlwhere="${RBDEV_DOWNLOAD:-/tmp/rbdev-dl}" # will append the target string to the prefix dir mentioned here # Note that the user running this script must be able to do make install in # this given prefix directory. Also make sure that this given root dir # exists. prefix="${RBDEV_PREFIX:-/usr/local}" # This directory is used to extract all files and to build everything in. It # must not exist before this script is invoked (as a security measure). builddir="${RBDEV_BUILD:-/tmp/rbdev-build}" # This script needs to use GNU Make. On Linux systems, GNU Make is invoked # by running the "make" command, on most BSD systems, GNU Make is invoked # by running the "gmake" command. Set the "make" variable accordingly. if [ -f "`which gmake 2>/dev/null`" ]; then make="gmake" else make="make" fi if [ -z $GNU_MIRROR ] ; then GNU_MIRROR=http://mirrors.kernel.org/gnu fi # These are the tools this script requires and depends upon. reqtools="gcc bzip2 gzip make patch makeinfo automake libtool autoconf flex bison" ############################################################################## # Functions: findtool(){ file="$1" IFS=":" for path in $PATH do # echo "Checks for $file in $path" >&2 if test -f "$path/$file"; then echo "$path/$file" return fi done } input() { read response echo $response } #$1 file #$2 URL"root getfile() { if test -f $dlwhere/$1; then echo "ROCKBOXDEV: Skipping download of $2/$1: File already exists" return fi tool=`findtool curl` if test -z "$tool"; then tool=`findtool wget` if test -n "$tool"; then # wget download echo "ROCKBOXDEV: Downloading $2/$1 using wget" $tool -T 60 -O $dlwhere/$1 $2/$1 fi else # curl download echo "ROCKBOXDEV: Downloading $2/$1 using curl" $tool -Lo $dlwhere/$1 $2/$1 fi if [ $? -ne 0 ] ; then echo "ROCKBOXDEV: couldn't download the file!" echo "ROCKBOXDEV: check your internet connection" exit fi if test -z "$tool"; then echo "ROCKBOXDEV: No downloader tool found!" echo "ROCKBOXDEV: Please install curl or wget and re-run the script" exit fi } build() { toolname="$1" target="$2" version="$3" patch="$4" configure_params="$5" needs_libs="$6" patch_url="http://www.rockbox.org/gcc" case $toolname in gcc) file="gcc-core-$version.tar.bz2" url="$GNU_MIRROR/gcc/gcc-$version" ;; binutils) file="binutils-$version.tar.bz2" url="$GNU_MIRROR/binutils" ;; crosstool-ng) file="crosstool-ng-$version.tar.bz2" url="http://crosstool-ng.org/download/crosstool-ng" ;; *) echo "ROCKBOXDEV: Bad toolname $toolname" exit ;; esac # create build directory if test -d $builddir; then if test ! -w $builddir; then echo "ROCKBOXDEV: No write permission for $builddir" exit fi else mkdir -p $builddir fi # download source tarball if test ! -f "$dlwhere/$file"; then getfile "$file" "$url" fi # download patch for p in $patch; do if test ! -f "$dlwhere/$p"; then getfile "$p" "$patch_url" fi done cd $builddir echo "ROCKBOXDEV: extracting $file" tar xjf $dlwhere/$file # do we have a patch? for p in $patch; do echo "ROCKBOXDEV: applying patch $p" # apply the patch (cd $builddir/$toolname-$version && patch -p1 < "$dlwhere/$p") # check if the patch applied cleanly if [ $? -gt 0 ]; then echo "ROCKBOXDEV: failed to apply patch $p" exit fi done # kludge to avoid having to install GMP, MPFR and MPC, for new gcc if test -n "$needs_libs"; then cd "gcc-$version" if (echo $needs_libs | grep -q gmp && test ! -d gmp); then echo "ROCKBOXDEV: Getting GMP" if test ! -f $dlwhere/gmp-4.3.2.tar.bz2; then getfile "gmp-4.3.2.tar.bz2" "$GNU_MIRROR/gmp" fi tar xjf $dlwhere/gmp-4.3.2.tar.bz2 ln -s gmp-4.3.2 gmp fi if (echo $needs_libs | grep -q mpfr && test ! -d mpfr); then echo "ROCKBOXDEV: Getting MPFR" if test ! -f $dlwhere/mpfr-2.4.2.tar.bz2; then getfile "mpfr-2.4.2.tar.bz2" "$GNU_MIRROR/mpfr" fi tar xjf $dlwhere/mpfr-2.4.2.tar.bz2 ln -s mpfr-2.4.2 mpfr fi if (echo $needs_libs | grep -q mpc && test ! -d mpc); then echo "ROCKBOXDEV: Getting MPC" if test ! -f $dlwhere/mpc-0.8.1.tar.gz; then getfile "mpc-0.8.1.tar.gz" "http://www.multiprecision.org/mpc/download" fi tar xzf $dlwhere/mpc-0.8.1.tar.gz ln -s mpc-0.8.1 mpc fi cd $builddir fi echo "ROCKBOXDEV: mkdir build-$toolname" mkdir build-$toolname echo "ROCKBOXDEV: cd build-$toolname" cd build-$toolname echo "ROCKBOXDEV: $toolname/configure" case $toolname in crosstool-ng) # ct-ng doesnt support out-of-tree build and the src folder is named differently toolname="crosstool-ng" cp -r ../$toolname-$version/* ../$toolname-$version/.version . ./configure --prefix=$prefix $configure_params ;; *) CFLAGS='-U_FORTIFY_SOURCE -fgnu89-inline' ../$toolname-$version/configure --target=$target --prefix=$prefix --enable-languages=c --disable-libssp --disable-docs $configure_params ;; esac echo "ROCKBOXDEV: $toolname/make" $make echo "ROCKBOXDEV: $toolname/make install" $make install echo "ROCKBOXDEV: rm -rf build-$toolname $toolname-$version" cd .. rm -rf build-$toolname $toolname-$version } make_ctng() { if test -f "`which ct-ng 2>/dev/null`"; then ctng="ct-ng" else ctng="" fi if test ! -n "$ctng"; then if test ! -f "$prefix/bin/ct-ng"; then # look if we build it already build "crosstool-ng" "" "1.13.2" "crosstool-ng-1.13.2.diff" fi fi ctng=`PATH=$prefix/bin:$PATH which ct-ng` } build_ctng() { ctng_target="$1" extra="$2" tc_arch="$3" tc_host="$4" make_ctng dlurl="http://www.rockbox.org/gcc/$ctng_target" # download getfile "ct-ng-config" "$dlurl" test -n "$extra" && getfile "$extra" "$dlurl" # create build directory if test -d $builddir; then if test ! -w $builddir; then echo "ROCKBOXDEV: No write permission for $builddir" exit fi else mkdir -p $builddir fi # copy config and cd to $builddir mkdir $builddir/build-$ctng_target ctng_config="$builddir/build-$ctng_target/.config" cat "$dlwhere/ct-ng-config" | sed -e "s,\(CT_PREFIX_DIR=\).*,\1$prefix," > $ctng_config cd $builddir/build-$ctng_target $ctng "build" # install extras if test -e "$dlwhere/$extra"; then # verify the toolchain has sysroot support if test -n `cat $ctng_config | grep CT_USE_SYSROOT\=y`; then sysroot=`cat $ctng_config | grep CT_SYSROOT_NAME | sed -e 's,CT_SYSROOT_NAME\=\"\([a-zA-Z0-9]*\)\",\1,'` tar xf "$dlwhere/$extra" -C "$prefix/$tc_arch-$ctng_target-$tc_host/$sysroot" fi fi # cleanup cd $builddir rm -rf $builddir/build-$ctng_target } ############################################################################## # Code: # Verify required tools for t in $reqtools; do tool=`findtool $t` if test -z "$tool"; then echo "ROCKBOXDEV: \"$t\" is required for this script to work." echo "ROCKBOXDEV: Please install \"$t\" and re-run the script." exit fi done echo "Download directory : $dlwhere (set RBDEV_DOWNLOAD to change)" echo "Install prefix : $prefix (set RBDEV_PREFIX to change)" echo "Build dir : $builddir (set RBDEV_BUILD to change)" echo "Make options : $MAKEFLAGS (set MAKEFLAGS to change)" echo "" # Verify download directory if test -d "$dlwhere"; then if ! test -w "$dlwhere"; then echo "ROCKBOXDEV: No write permission for $dlwhere" exit fi else mkdir $dlwhere if test $? -ne 0; then echo "ROCKBOXDEV: Failed creating directory $dlwhere" exit fi fi # Verify the prefix dir if test ! -d $prefix; then mkdir -p $prefix if test $? -ne 0; then echo "ROCKBOXDEV: Failed creating directory $prefix" exit fi fi if test ! -w $prefix; then echo "ROCKBOXDEV: No write permission for $prefix" exit fi echo "Select target arch:" echo "s - sh (Archos models)" echo "m - m68k (iriver h1x0/h3x0, iaudio m3/m5/x5 and mpio hd200)" echo "a - arm (ipods, iriver H10, Sansa, D2, Gigabeat, etc)" echo "i - mips (Jz4740 and ATJ-based players)" echo "r - arm-app (Samsung ypr0)" echo "separate multiple targets with spaces" echo "(Example: \"s m a\" will build sh, m68k and arm)" echo "" selarch=`input` system=`uname -s` # add target dir to path to ensure the new binutils are used in gcc build PATH="$prefix/bin:${PATH}" for arch in $selarch do echo "" case $arch in [Ss]) # For binutils 2.16.1 builtin rules conflict on some systems with a # default rule for Objective C. Disable the builtin make rules. See # http://sourceware.org/ml/binutils/2005-12/msg00259.html export MAKEFLAGS="-r $MAKEFLAGS" build "binutils" "sh-elf" "2.16.1" "binutils-2.16.1-texinfo-fix.diff" "--disable-werror" build "gcc" "sh-elf" "4.0.3" "gcc-4.0.3-rockbox-1.diff" ;; [Ii]) build "binutils" "mipsel-elf" "2.17" "" "--disable-werror" patch="" if [ "$system" = "Interix" ]; then patch="gcc-4.1.2-interix.diff" fi build "gcc" "mipsel-elf" "4.1.2" "$patch" ;; [Mm]) build "binutils" "m68k-elf" "2.20.1" "binutils-2.20.1-texinfo-fix.diff" "--disable-werror" build "gcc" "m68k-elf" "4.5.2" "" "--with-arch=cf MAKEINFO=missing" "gmp mpfr mpc" ;; [Aa]) binopts="" gccopts="" case $system in Darwin) binopts="--disable-nls" gccopts="--disable-nls" ;; esac build "binutils" "arm-elf-eabi" "2.20.1" "binutils-2.20.1-ld-thumb-interwork-long-call.diff binutils-2.20.1-texinfo-fix.diff" "$binopts --disable-werror" build "gcc" "arm-elf-eabi" "4.4.4" "rockbox-multilibs-noexceptions-arm-elf-eabi-gcc-4.4.2_1.diff" "$gccopts MAKEINFO=missing" "gmp mpfr" ;; [Rr]) build_ctng "ypr0" "alsalib.tar.gz" "arm" "linux-gnueabi" ;; *) echo "ROCKBOXDEV: Unsupported architecture option: $arch" exit ;; esac done echo "" echo "ROCKBOXDEV: Done!" echo "" echo "ROCKBOXDEV: Make sure your PATH includes $prefix/bin" echo ""