#!/bin/bash
#
# Prerequisites (debian): sudo apt-get install gcc make texinfo ed
# seems you'll need termcap-dev for gdb (optional, commented out below)
#
# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45174
# attachment 21387
# http://gcc.gnu.org/bugzilla/attachment.cgi?id=21387
#
# Written by Uwe Hermann <uwe@hermann-uwe.de>, released as public domain.
# Modified by Piotr Esden-Tempski <piotr@esden.net>, released as public domain.
# Modified by Roel Verdult <roel@libnfc.org>, released as public domain.
# - Removed manufacture (STM) specific libraries
# - Added parameters for install location
# - Optimized for building smallest firmware size
# - Added windows (MinGW) build compatibility
# Modified by Donald Schlicht, released as public domain.
# - Added optional third command argument for number of processors
# - Modified source download so script can be run multiple times
# - Modified linux GCCFLAGS to set CC variable correctly
# - Modified gcc compile configuration under linux
# Modified by Matti Kariluoma <matti@kariluo.ma>, released as public domain.
# - Added gcc-4.6.4, binutils-2.23.2, gdb-7.5
# - Commented out --enable-multilib for both configure gcc
# - - http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45174#c26
# - Changed enable-languages to "c" only for final gcc build
# - Added call to contrib/download_prerequisites
# - Added --disable-libssp or both configure gcc
# - commented out gdb section
# - moved INSTALL to a separate dir, changed name to 'work'
# - changed SOURCE to 'src'
# - changed DOWNLOAD out of home directory (wtf?), changed to 'pkg'
# - modified checks on dirs at beginning
# - added patch for gcc/config/arm/t-arm-elf
if [ $# -lt 2 ]; then
echo "Public GNU GCC ARM toolchain building script";
echo "usage: $0 <prefix> <arm-elf|arm-none-eabi> <optional number of cores>";
exit 0;
fi
# Version configuration
BINUTILS=binutils-2.21.1 # 2.20.1 # 2.18
GCC=gcc-4.6.4 # 4.5.1 # 4.2.2
NEWLIB=newlib-1.18.0 # 1.16.0
#GDB=gdb-7.5 # 7.1 # 6.8
DARWIN_OPT_PATH=/opt/local # Path in which MacPorts or Fink is installed
MINGW_PATH=/mingw # Path in which MacPorts or Fink is installed
# Command-line parameters
BASE=$1 # Base location for install
TARGET=$2 # TARGET = arm-elf | arm-none-eabi
PREFIX=${BASE}/${TARGET} # binary location of your toolchain (e.g. ${HOME})
INSTALL=${BASE}/work # creation location
DOWNLOAD=${BASE}/pkg # Location of downloaded tarballs
SOURCE=${INSTALL}/src # location of uncompressed source files
BUILD=${INSTALL}/build # location of compile files
# Added by DJS optional third parameter for cpu cores# Advanced options
PARALLEL="" # PARALLEL = "-j 5" for 4 CPU's
if [ $# -eq 3 ]; then
PARALLEL="-j $3";
fi
export PATH="${PREFIX}/bin:${PATH}"
# Modified by DJS to set linux GCCFLAGS
case "$(uname)" in
Linux)
echo "Found Linux OS."
GCCFLAGS= #"CC=gcc \
#--with-system-zlib"
NEWLIBFLAGS= # "CC=gcc"
GDBFLAGS=
;;
Darwin)
echo "Found Darwin OS."
GCCFLAGS="--with-gmp=${DARWIN_OPT_PATH} \
--with-mpfr=${DARWIN_OPT_PATH} \
-with-libiconv-prefix=${DARWIN_OPT_PATH}"
NEWLIBFLAGS="--enable-newlib-reent-small \"
GDBFLAGS="--disable-werror"
;;
MINGW*)
echo "Found Windows OS."
GCCFLAGS="--with-gmp=${MINGW_PATH} \
--with-mpfr=${MINGW_PATH} \
-with-libiconv-prefix=${MINGW_PATH}"
NEWLIBFLAGS="--enable-newlib-reent-small \"
GDBFLAGS="--disable-werror"
;;
*)
echo "Found unknown OS. Aborting!"
exit 1
;;
esac
echo "Creating installation directories..."
if [ ! -e ${BASE} ]; then
mkdir ${BASE} || exit
fi
# Modified DJS delete all old installation directories
if [ -e ${PREFIX} ]; then
rm -r -f ${PREFIX} || exit
fi
if [ -e ${INSTALL} ]; then
rm -r -f ${INSTALL} || exit
fi
mkdir ${PREFIX} || exit
mkdir ${INSTALL} || exit
if [ ! -e ${SOURCE} ]; then
mkdir ${SOURCE} || exit
fi
if [ ! -e ${BUILD} ]; then
mkdir ${BUILD} || exit
fi
echo "Downloading sources...."
# Modified by DJS, create a Downloads directory
if [ ! -e ${DOWNLOAD} ]; then
mkdir ${DOWNLOAD} || exit
fi
cd ${DOWNLOAD}
# Modified by DJS, download tarballs to Download directory if not already there
if [ ! -e ${BINUTILS}.tar.bz2 ]; then
echo "Downloading binutils sources...";
wget -c http://ftp.gnu.org/gnu/binutils/${BINUTILS}.tar.bz2 || exit
fi
if [ ! -e ${GCC}.tar.bz2 ]; then
echo "Downloading gcc sources...";
wget -c ftp://ftp.gnu.org/gnu/gcc/${GCC}/${GCC}.tar.bz2 || exit
fi
if [ ! -e ${NEWLIB}.tar.gz ]; then
echo "Downloading newlib sources...";
wget -c ftp://sources.redhat.com/pub/newlib/${NEWLIB}.tar.gz || exit
fi
#~ if [ ! -e ${GDB}.tar.bz2 ]; then
#~ echo "Downloading gdb sources...";
#~ wget -c ftp://ftp.gnu.org/gnu/gdb/${GDB}.tar.bz2;
#~ fi
cd ${SOURCE}
echo "******************************************************************"
echo "* Unpacking ${BINUTILS}"
echo "******************************************************************"
tar xfvj ${DOWNLOAD}/${BINUTILS}.tar.bz2 > ${INSTALL}/${BINUTILS}_tar.log || exit
cd ${BUILD}
mkdir ${BINUTILS} || exit
cd ${BINUTILS} # in ${BUILD}
echo "******************************************************************"
echo "* Configuring ${BINUTILS}"
echo "******************************************************************"
${SOURCE}/${BINUTILS}/configure --target=${TARGET} \
--prefix=${PREFIX} \
--enable-interwork \
--enable-multilib \
--with-gnu-as \
--with-gnu-ld \
--disable-werror \
--disable-nls > ${INSTALL}/${BINUTILS}_configure.log || exit
echo "******************************************************************"
echo "* Building ${BINUTILS}"
echo "******************************************************************"
make MAKEINFO=makeinfo ${PARALLEL} > ${INSTALL}/${BINUTILS}_make.log || exit
echo "******************************************************************"
echo "* Installing ${BINUTILS}"
echo "******************************************************************"
make install > ${INSTALL}/${BINUTILS}_install.log || exit
cd ${SOURCE}
echo "******************************************************************"
echo "* Unpacking ${GCC}"
echo "******************************************************************"
tar xfvj ${DOWNLOAD}/${GCC}.tar.bz2 > ${INSTALL}/${GCC}-boot_tar.log || exit
echo "******************************************************************"
echo "* Downloading prerequisites for ${GCC}"
echo "******************************************************************"
cd ${SOURCE}/${GCC}
contrib/download_prerequisites > ${INSTALL}/${GCC}-boot_preqs.log || exit
if [ "$TARGET" == "arm-elf" ]; then
echo "******************************************************************"
echo "* Patching ${GCC}"
echo "******************************************************************"
ed ${SOURCE}/${GCC}/gcc/config/arm/t-arm-elf << EOF > ${INSTALL}/${GCC}-boot_patch.log
/MULTILIB_OPTIONS/s/^M/# M/
/MULTILIB_DIRNAMES/s/^M/# M/
/mno-thumb-interwork/s/^# //
/normal interwork/s/^# //
wq
EOF
[ $? -eq 0 ] || exit
fi
cd ${BUILD}
mkdir ${GCC}-boot || exit
cd ${GCC}-boot
echo "******************************************************************"
echo "* Configuring ${GCC}-boot"
echo "******************************************************************"
${SOURCE}/${GCC}/configure --target=${TARGET} \
--prefix=${PREFIX} \
--enable-interwork \
--enable-languages="c" \
--with-newlib \
--without-headers \
--disable-shared \
--with-gnu-as \
--with-gnu-ld \
--disable-nls \
--disable-libssp \
${GCCFLAGS} > ${INSTALL}/${GCC}-boot_configure.log || exit
# --enable-multilib
echo "******************************************************************"
echo "* Building ${GCC}-boot"
echo "******************************************************************"
make ${PARALLEL} > ${INSTALL}/${GCC}-boot_make.log || exit
echo "******************************************************************"
echo "* Installing ${GCC}-boot"
echo "******************************************************************"
make install > ${INSTALL}/${GCC}-boot_install.log || exit
cd ${SOURCE}
echo "******************************************************************"
echo "* Unpacking ${NEWLIB}"
echo "******************************************************************"
tar xfvz ${DOWNLOAD}/${NEWLIB}.tar.gz > ${INSTALL}/${NEWLIB}_tar.log || exit
cd ${BUILD}
mkdir ${NEWLIB} || exit
cd ${NEWLIB}
echo "******************************************************************"
echo "* Configuring ${NEWLIB}"
echo "******************************************************************"
${SOURCE}/${NEWLIB}/configure --target=${TARGET} \
--prefix=${PREFIX} \
--enable-interwork \
--enable-multilib \
--with-gnu-as \
--with-gnu-ld \
--disable-nls \
--enable-target-optspace \
--enable-newlib-io-c99-formats \
--enable-newlib-io-long-long \
--disable-newlib-multithread \
--disable-newlib-supplied-syscalls \
CFLAGS="-DPREFER_SIZE_OVER_SPEED -DSMALL_MEMORY" \
${NEWLIBFLAGS} > ${INSTALL}/${NEWLIB}_configure.log || exit
echo "******************************************************************"
echo "* Building ${NEWLIB}"
echo "******************************************************************"
make ${PARALLEL} > ${INSTALL}/${NEWLIB}_make.log || exit
echo "******************************************************************"
echo "* Installing ${NEWLIB}"
echo "******************************************************************"
make install > ${INSTALL}/${NEWLIB}_install.log || exit
# Yes, you need to build gcc again!
cd ${SOURCE}
echo "******************************************************************"
echo "* Unpacking ${GCC}"
echo "******************************************************************"
tar xfvj ${DOWNLOAD}/${GCC}.tar.bz2 > ${INSTALL}/${GCC}-final_tar.log || exit
cd ${SOURCE}/${GCC}
if [ "$TARGET" == "arm-elf" ]; then
echo "******************************************************************"
echo "* Patching ${GCC}"
echo "******************************************************************"
ed ${SOURCE}/${GCC}/gcc/config/arm/t-arm-elf << EOF > ${INSTALL}/${GCC}-final_patch.log
/MULTILIB_OPTIONS/s/^M/# M/
/MULTILIB_DIRNAMES/s/^M/# M/
/mno-thumb-interwork/s/^# //
/normal interwork/s/^# //
wq
EOF
[ $? -eq 0 ] || exit
fi
cd ${BUILD}
mkdir ${GCC} || exit
cd ${GCC}
echo "******************************************************************"
echo "* Configuring ${GCC}"
echo "******************************************************************"
${SOURCE}/${GCC}/configure --target=${TARGET} \
--prefix=${PREFIX} \
--enable-interwork \
--enable-languages="c" \
--with-newlib \
--disable-shared \
--with-gnu-as \
--with-gnu-ld \
--disable-nls \
--disable-libssp \
${GCCFLAGS} > ${INSTALL}/${GCC}-final_configure.log || exit
# --enable-multilib \
# --enable-languages="c,c++,objc" \
echo "******************************************************************"
echo "* Building ${GCC}"
echo "******************************************************************"
make ${PARALLEL} > ${INSTALL}/${GCC}-final_make.log || exit
echo "******************************************************************"
echo "* Installing ${GCC}"
echo "******************************************************************"
make install > ${INSTALL}/${GCC}-final_install.log || exit
#~ cd ${SOURCE}
#~ echo "******************************************************************"
#~ echo "* Unpacking ${GDB}"
#~ echo "******************************************************************"
#~ tar xfvj ${DOWNLOAD}/${GDB}.tar.bz2 > ${INSTALL}/${GDB}_tar.log || exit
#~ cd ${BUILD}
#~ mkdir ${GDB} || exit
#~ cd ${GDB}
#~ echo "******************************************************************"
#~ echo "* Configuring ${GDB}"
#~ echo "******************************************************************"
#~ ${SOURCE}/${GDB}/configure --target=${TARGET} \
#~ --prefix=${PREFIX} \
#~ --enable-interwork \
#~ --enable-multilib \
#~ --with-libexpat \
#~ --disable-nls \
#~ ${GDBFLAGS} > ${INSTALL}/${GDB}_configure.log || exit
#~ echo "******************************************************************"
#~ echo "* Building ${GDB}"
#~ echo "******************************************************************"
#~ make ${PARALLEL} > ${INSTALL}/${GDB}_make.log || exit
#~ echo "******************************************************************"
#~ echo "* Installing ${GDB}"
#~ echo "******************************************************************"
#~ make install > ${INSTALL}/${GDB}_install.log || exit
echo "******************************************************************"
echo "* Finished"
echo "******************************************************************"