#!/bin/sh
# Build an embedded development toolchain
# assume that archives are in source/archive directory (relative to this one)
# if RTEMS_BSP is not set, then RTEMS will not be extracted or built.
RTEMS_BSP=

# For a simple PC build
# TARGET=i386-elf
# RTEMS_BSP=pc386

# Coldfire Target
# TARGET=m68k-rtems
# RTEMS_BSP=bare

DIRECTORY=`pwd`
SOURCEDIR=$DIRECTORY/source
ARCHIVES=$SOURCEDIR/archive
PREFIX=$DIRECTORY/$TARGET
TIMEFILE=$DIRECTORY/totaltime.txt
# EXT=.exe
BUILDDIR=build-$TARGET

# Flags to unzip files in different formats
BZ2_FLAGS=-xjpf
GZ_FLAGS=-xzpf

# The last known configuration known to work
# BINUTILS_VER=050930 (2.16.1 does not work)
# GCC_VER=4.0.2
# NEWLIB_VER=1.13.0
#
# BINUTILS_VER=2.13.2.1
# GCC_VER=3.2.3
# NEWLIB_VER=1.11.0
#
BINUTILS_VER=050930
BINUTILS_ARCHIVE=$ARCHIVES/binutils-$BINUTILS_VER.tar.bz2
BINUTILS_TARFLAGS=$BZ2_FLAGS
GCC_VER=4.0.2
GCC_ARCHIVE=$ARCHIVES/gcc-$GCC_VER.tar.bz2
GCC_TARFLAGS=$BZ2_FLAGS
NEWLIB_VER=1.13.0
NEWLIB_ARCHIVE=$ARCHIVES/newlib-$NEWLIB_VER.tar.gz
NEWLIB_TARFLAGS=$GZ_FLAGS
RTEMS_VER=4.6.6
RTEMS_ARCHIVE=$ARCHIVES/rtems-$RTEMS_VER.tar.bz2
RTEMS_TARFLAGS=$BZ2_FLAGS


# Backup the last file
if [ -x $TIMEFILE ]; then
  mv $TIMEFILE $TIMEFILE.old
fi

echo Building Binutils and GCC for $TARGET
echo =============================================================
echo " " > $TIMEFILE
echo "----------------- Build Report -----------------" >> $TIMEFILE
date >> $TIMEFILE
echo -n "Building Cross compiler for $TARGET on " >> $TIMEFILE
uname -sm >> $TIMEFILE
echo "------------------------------------------------" >> $TIMEFILE
echo "DIRECTORY=$DIRECTORY" >> $TIMEFILE
echo "SOURCEDIR=$SOURCEDIR" >> $TIMEFILE
echo "ARCHIVES=$ARCHIVES" >> $TIMEFILE
echo "PREFIX=$PREFIX" >> $TIMEFILE
echo "TARGET=$TARGET" >> $TIMEFILE
echo "TIMEFILE=$TIMEFILE" >> $TIMEFILE
echo "------------------------------------------------" >> $TIMEFILE

# Builds are done in the source/build-$TARGET directory
cd $SOURCEDIR
if [ ! -x $BUILDDIR ]; then
  mkdir $BUILDDIR
fi

##############################################################################
#                           UNPACK AND PATCH                                 #
##############################################################################

# ---------------------- Unpack everything if needed
UNPACKING_TIME=`date`
if [ ! -x binutils-$BINUTILS_VER ]; then
  echo ==================== Unpacking binutils-$BINUTILS_VER ====================
  tar $BINUTILS_TARFLAGS $BINUTILS_ARCHIVE  
  cd binutils-$BINUTILS_VER
  # no patch
  cd ..
fi

if [ ! -x newlib-$NEWLIB_VER ]; then
  echo ==================== Unpacking newlib-$NEWLIB_VER ====================
  tar $NEWLIB_TARFLAGS $NEWLIB_ARCHIVE
  # ------------------------- PATCH newlib
  cd newlib-$NEWLIB_VER  
  cat ../archive/newlib-$NEWLIB_VER-rtems-20030605.diff | patch -p1
  cd ..
fi

if [ ! -x gcc-$GCC_VER ]; then
  echo ==================== Unpacking gcc-$GCC_VER ====================
  tar $GCC_TARFLAGS $GCC_ARCHIVE
fi

# ------- Make the newlib link
if [ ! -x gcc-$GCC_VER/newlib ]; then
  cd gcc-$GCC_VER
  ln -s ../newlib-$NEWLIB_VER/newlib .  
  # ------------------------- PATCH gcc
  cat ../archive/gcc-3.2.3-rtems-20040108.diff | patch -p1    
  cd ..
fi

if [ $RTEMS_BSP == "" ]; then
  if [ ! -x rtems-$RTEMS_VER ]; then
    echo ==================== Unpacking rtems-$RTEMS_VER ====================
    tar $RTEMS_TARFLAGS $RTEMS_ARCHIVE  
    cd rtems-$RTEMS_VER
    # no patch
    cd ..
  fi
else
  echo ===================== Skipping RTEMS =============================
fi

##############################################################################
#                                BUILD TOOLS                                 #
##############################################################################
# ---------------------- Build binutils
echo ==================== BUILDING binutils-$BINUTILS_VER ====================
BINUTILS_TIME=`date`
cd $BUILDDIR
if [ ! -x binutils ]; then
  # Configure
  mkdir binutils  
  cd binutils
  ../../binutils-$BINUTILS_VER/configure --target=$TARGET --prefix=$PREFIX
  make
  make install
else
  # Already built
  cd binutils
fi
PATH=$PREFIX/bin:${PATH}
# Check that the assembler is installed correctly in $PREFIX/bin
if [ -x $PREFIX/bin/$TARGET-as$EXT ]
then
  echo "==================== BINUTILS complete ========================="
  ASSEMBLER=$PREFIX/bin/$TARGET-as$EXT
  LINKER=$PREFIX/bin/$TARGET-ld$EXT
  echo "ASSEMBLER=$ASSEMBLER" >> $TIMEFILE
  echo "LINKER=$LINKER" >> $TIMEFILE
else
  echo "Unable to find $PREFIX/bin/$TARGET-as$EXT"
  exit 1
fi
cd ../..

# ---------------------- Build the bootstrap GCC for building newlib
# We need to build a stripped down GCC configured for the target that
# we will use to build newlib. Once newlib is built, then GCC will be
# rebuilt and will use newlib as the default C library.

echo ================ BUILDING bootstrap gcc-$GCC_VER ====================
GCC1_TIME=`date`
cd $BUILDDIR
if [ ! -x gcc ]; then
  # Configure
  mkdir gcc  
  cd gcc
  ../../gcc-$GCC_VER/configure --with-newlib --without-headers --target=$TARGET --prefix=$PREFIX --with-as=$ASSEMBLER --with-ld=$LINKER
  make all-gcc && make install-gcc
else
# Already built
  cd gcc
fi
cd ../..


echo ==================== BUILDING Newlib-$NEWLIB_VER ====================
NEWLIB_TIME=`date`
cd $BUILDDIR
if [ ! -x newlib ]; then
  # Configure
  mkdir newlib  
  cd newlib
  ../../newlib-$NEWLIB_VER/configure --target=$TARGET --prefix=$PREFIX
  make && make install
else
  # Already built
  cd newlib
fi
cd ../..


echo ==================== BUILDING gcc-$GCC_VER ====================
GCC2_TIME=`date`
cd $BUILDDIR
# If the gcc compiler already exists, don't bother building it
if [ -x $PREFIX/bin/$TARGET-gcc$EXT ]
then
  cd gcc
else
  cd gcc
  ../../gcc-$GCC_VER/configure --with-newlib --enable-threads --target=$TARGET --prefix=$PREFIX --with-as=$ASSEMBLER --with-ld=$LINKER
  make all-gcc && make install-gcc
fi
# Check that the compiler is installed correctly in $PREFIX/bin
if [ -x $PREFIX/bin/$TARGET-gcc$EXT ]
then
  echo "==================== GCC build complete ========================"
  COMPILER=$PREFIX/bin/$TARGET-gcc$EXT
  echo "COMPILER=$COMPILER" >> $TIMEFILE
else
  echo "==================== ERROR building GCC ========================"
  echo "COMPILER=" >> $TIMEFILE
  exit 1
fi
cd ../..


echo " " >> $TIMEFILE
echo "------------------------------------------------" >> $TIMEFILE

##############################################################################
#                                 TEST TOOLS                                 #
##############################################################################

# Test the toolchain by creating a small file and compiling it.
echo " "
echo "------------------------- TESTING THE TOOLS -------------------------"
echo " "
if [ ! -x $BUILDDIR/test ]; then
  mkdir $BUILDDIR/test
fi
cd $BUILDDIR/test
echo " " > test.c
echo "#include <stdio.h>" >> test.c
echo " " >> test.c
echo "void _start(void) { foo(5); };" >> test.c
echo " " >> test.c
echo "int foo( int x )" >> test.c
echo "{" >> test.c
echo "    return x+1;" >> test.c
echo "}" >> test.c
# $PREFIX/bin should be in the path to allow this to execute
# - Just compile for now.
echo ASSEMBLER=$ASSEMBLER > output.txt
echo LINKER=$LINKER  >> output.txt
echo COMPILER=$COMPILER  >> output.txt
# echo INCLUDE=$INCLUDE  >> output.txt
echo "------------------------------------------------------" >> output.txt
$COMPILER -o test.o test.c >> output.txt
if [ ! -x test.o ]; then
  # Error! unable to build test code.
  echo "------------ Test Build Failed -----------------" >> $TIMEFILE
  echo >> $TIMEFILE
  cat output.txt  >> $TIMEFILE
  rm test.c output.txt
  echo >> $TIMEFILE
  exit 2
else
  echo "------------ Test Build Successful -------------" >> $TIMEFILE
  rm test.o test.c output.txt
fi
cd ../..

##############################################################################
#                                BUILD RTEMS                                 #
##############################################################################

if [ $RTEMS_BSP == "" ]; then
  # ---------------------- Build RTEMS
  echo ==================== BUILDING RTEMS-$RTEMS_VER ====================
  cd $BUILDDIR
  if [ ! -x rtems ]; then
    PATH=$PREFIX/bin:${PATH}   
    # Configure
    mkdir rtems  
    cd rtems
    ../../rtems-$RTEMS_VER/configure --target=$TARGET --disable-posix --disable-networking --disable-cxx \
    --enable-rtemsbsp=$RTEMS_BSP --prefix=$PREFIX/bin   
    make all install
  else
    # Already built
    cd rtems
  fi
  cd ../..
else
  echo ================== SKIPPING RTEMS ==============================
fi


##############################################################################
#                                COMPLETE                                    #
##############################################################################

echo "------------------------------------------------" >> $TIMEFILE
echo " " >> $TIMEFILE
echo Start times >> $TIMEFILE
echo "Unpack..........$UNPACKING_TIME" >> $TIMEFILE
echo "Binutils........$BINUTILS_TIME" >> $TIMEFILE
echo "Pre-GCC.........$GCC1_TIME" >> $TIMEFILE
echo "Newlib..........$NEWLIB_TIME" >> $TIMEFILE
echo "GCC.............$GCC2_TIME" >> $TIMEFILE
echo -n "Finished........" >> $TIMEFILE
date >> $TIMEFILE
cat $TIMEFILE
echo buildit.sh ended

