274 lines
7.4 KiB
Bash
274 lines
7.4 KiB
Bash
#!/usr/bin/env bash
|
|
|
|
OS=`uname`
|
|
HOSTARCH=`uname -m`
|
|
PARALLEL=
|
|
FETCH=0
|
|
QUIET=0
|
|
STRIP=0
|
|
GNU_MIRROR=https://mirrors.kernel.org/gnu
|
|
# Get absolute path, will spawn a subshell then exit so our pwd is retained
|
|
SCRIPTROOT=$(cd "$(dirname $0)" && pwd)
|
|
PATCHES=$SCRIPTROOT/patches/
|
|
|
|
# Cause errors in pipes to return failure when necessary
|
|
set -o pipefail
|
|
|
|
function err() {
|
|
echo "doit: error during build"
|
|
if [ "$QUIET" = "1" ]; then
|
|
echo "doit: dumping last 50 lines of build log..."
|
|
echo "doit: see $OUTDIR/build.log for the full details"
|
|
tail -50 $OUTDIR/build.log
|
|
fi
|
|
exit 1
|
|
}
|
|
|
|
trap err ERR
|
|
|
|
function help()
|
|
{
|
|
echo "Options"
|
|
echo " -a <arch list> architectures to build"
|
|
echo " example: -a 'arm' or -a 'arm i386 x86_64' for multiple"
|
|
echo " -c use compilation cache (ccache must be installed)"
|
|
echo " -f fetch source releases from upstream"
|
|
echo " -h|-? display this help message"
|
|
echo " -j<#> use <#> parallel workers to build"
|
|
echo " -o <dir> output directory"
|
|
echo " -q make the build quieter"
|
|
echo " -s strip the binaries"
|
|
exit 1
|
|
}
|
|
|
|
function log()
|
|
{
|
|
if [ "$QUIET" = "1" ]; then
|
|
"$@" >> $OUTDIR/build.log 2>&1
|
|
else
|
|
"$@" 2>&1 | tee -a $OUTDIR/build.log
|
|
fi
|
|
}
|
|
|
|
function extract-tool()
|
|
{
|
|
#echo "extract-tool " $1 $2 $3 $4
|
|
|
|
TARFILE=${1}-${2}.tar$3
|
|
TARGETDIR=${1}-${2}
|
|
HASH="$4"
|
|
PATCH="$5"
|
|
if [ -f ${TARGETDIR}/.extracted ]; then
|
|
log echo "$TARFILE already extracted into $TARGETDIR, skipping"
|
|
return 0
|
|
fi
|
|
if [ ! -f $ARCHIVES/$TARFILE ]; then
|
|
log echo "error, missing $TARFILE"
|
|
exit 1
|
|
fi
|
|
|
|
echo "checking $TARFILE integrity"
|
|
if [ "$(shasum -a 256 -b "$ARCHIVES/$TARFILE" | cut -f1 -d' ')" != "$HASH" ]; then
|
|
log echo "$TARFILE failed integrity check"
|
|
exit 1
|
|
fi
|
|
|
|
echo extracting $TARFILE
|
|
pushd $OUTDIR
|
|
rm -rf $TARGETDIR
|
|
tar xf $ARCHIVES/$TARFILE || exit 1
|
|
|
|
if [ -n "$PATCH" ]; then
|
|
log echo patching $1
|
|
log patch -d $TARGETDIR -p1 < "$PATCH" || exit 1
|
|
fi
|
|
|
|
touch $TARGETDIR/.extracted || exit 1
|
|
popd
|
|
}
|
|
|
|
MAKE=make
|
|
if [ "$OS" = "Linux" ]; then
|
|
COUNT=`grep processor /proc/cpuinfo | wc -l`
|
|
PARALLEL=-j`expr $COUNT + $COUNT`
|
|
fi
|
|
if [ "$OS" = "Darwin" ]; then
|
|
PARALLEL=-j`sysctl -n hw.ncpu`
|
|
export CXXFLAGS="-fbracket-depth=1024"
|
|
fi
|
|
if [ "$OS" = "FreeBSD" ]; then
|
|
PARALLEL=-j`sysctl -n hw.ncpu`
|
|
export CXXFLAGS="-fbracket-depth=1024"
|
|
MAKE=gmake
|
|
fi
|
|
|
|
if [ "$HOSTARCH" = "amd64" ]; then
|
|
HOSTARCH=x86_64
|
|
fi
|
|
|
|
if [ $# == "0" ]; then
|
|
help
|
|
fi
|
|
|
|
while getopts a:cfhj:o:qs? arg
|
|
do
|
|
case $arg in
|
|
a ) ARCHES=$OPTARG ;;
|
|
c ) CCACHE=1 ;;
|
|
j ) PARALLEL="-j$OPTARG" ;;
|
|
f ) FETCH=1 ;;
|
|
o ) OUTDIR=$OPTARG ;;
|
|
q ) QUIET=1 ;;
|
|
s ) STRIP=1 ;;
|
|
h ) help ;;
|
|
? ) help ;;
|
|
* ) echo "unrecognized option '$arg'" ; exit 1 ;;
|
|
esac
|
|
done
|
|
|
|
|
|
if [ -z "$ARCHES" ]; then
|
|
echo need to specify architectures to build
|
|
echo ie -a "arm sh"
|
|
exit 1
|
|
fi
|
|
|
|
if [ -z "$OUTDIR" ]; then
|
|
OUTDIR=`pwd`
|
|
fi
|
|
ARCHIVES=$OUTDIR/archives
|
|
|
|
if [ -z $(which makeinfo) ]; then
|
|
echo makeinfo not found. On debian/ubuntu this is provided by the texinfo package.
|
|
exit 1
|
|
fi
|
|
|
|
export CC="cc"
|
|
export CXX="c++"
|
|
|
|
if [ "$CCACHE" = "1" ]; then
|
|
export CC="ccache $CC"
|
|
export CXX="ccache $CXX"
|
|
fi
|
|
|
|
log date
|
|
log echo "ARCHES='$ARCHES' PARALLEL='$PARALLEL' FETCH='$FETCH' CCACHE='$CCACHE'"
|
|
# load GCCVER and BINVER
|
|
. toolvers
|
|
|
|
if [ "$FETCH" = "1" ]; then
|
|
if [ ! -f $ARCHIVES/binutils-$BINVER.tar.bz2 ]; then
|
|
echo fetching binutils-$BINVER
|
|
log wget -P $ARCHIVES -N $GNU_MIRROR/binutils/binutils-$BINVER.tar.bz2
|
|
fi
|
|
if [ ! -f $ARCHIVES/gcc-$GCCVER.tar.bz2 ]; then
|
|
echo fetching gcc-$GCCVER
|
|
log wget -P $ARCHIVES -N $GNU_MIRROR/gcc/gcc-$GCCVER/gcc-$GCCVER.tar.bz2
|
|
fi
|
|
if [ ! -f $ARCHIVES/gdb-$GDBVER.tar.xz ]; then
|
|
echo fetching gdb-$GDBVER
|
|
log wget -P $ARCHIVES -N $GNU_MIRROR/gdb/gdb-$GDBVER.tar.xz
|
|
fi
|
|
if [ ! -f $ARCHIVES/mpfr-$MPFRVER.tar.bz2 ]; then
|
|
echo fetching mpfr-$MPFRVER
|
|
log wget -P $ARCHIVES -N $GNU_MIRROR/mpfr/mpfr-$MPFRVER.tar.bz2
|
|
fi
|
|
if [ ! -f $ARCHIVES/mpc-$MPCVER.tar.gz ]; then
|
|
echo fetching mpc-$MPCVER
|
|
log wget -P $ARCHIVES -N $GNU_MIRROR/mpc/mpc-$MPCVER.tar.gz
|
|
fi
|
|
if [ ! -f $ARCHIVES/gmp-$GMPVER.tar.bz2 ]; then
|
|
echo fetching gmp-$GMPVER
|
|
log wget -P $ARCHIVES -N $GNU_MIRROR/gmp/gmp-$GMPVER.tar.bz2
|
|
fi
|
|
fi
|
|
|
|
if [ ! -f $OUTDIR/.extracted-stamp ]; then
|
|
extract-tool binutils $BINVER .bz2 $BINHASH
|
|
extract-tool gcc $GCCVER .bz2 $GCCHASH $PATCHES/gcc-patch.txt
|
|
extract-tool gdb $GDBVER .xz $GDBHASH $PATCHES/gdb-patch.txt
|
|
extract-tool gmp $GMPVER .bz2 $GMPHASH
|
|
extract-tool mpc $MPCVER .gz $MPCHASH
|
|
extract-tool mpfr $MPFRVER .bz2 $MPFRHASH
|
|
touch $OUTDIR/.extracted-stamp
|
|
fi
|
|
|
|
# link the last three libs into gcc
|
|
pushd $OUTDIR/gcc-$GCCVER
|
|
ln -sf ../gmp-$GMPVER gmp
|
|
ln -sf ../mpc-$MPCVER mpc
|
|
ln -sf ../mpfr-$MPFRVER mpfr
|
|
popd
|
|
|
|
for ARCH in $ARCHES; do
|
|
echo building for arch \"$ARCH\"
|
|
if [ "$ARCH" == "arm" ]; then
|
|
TARGET=arm-eabi
|
|
else
|
|
TARGET=$ARCH-elf
|
|
fi
|
|
|
|
INSTALLPATH=$OUTDIR/$TARGET-$GCCVER-$OS-$HOSTARCH
|
|
BINBUILDPATH=$OUTDIR/build-binutils-$BINVER-$ARCH-$OS-$HOSTARCH
|
|
GCCBUILDPATH=$OUTDIR/build-gcc-$GCCVER-$ARCH-$OS-$HOSTARCH
|
|
GDBBUILDPATH=$OUTDIR/build-gdb-$GDBVER-$ARCH-$OS-$HOSTARCH
|
|
export PATH=$INSTALLPATH/bin:$PATH
|
|
|
|
# Building Binutils
|
|
if [ ! -f $BINBUILDPATH/built.txt ]; then
|
|
echo building binutils
|
|
mkdir -p $BINBUILDPATH
|
|
pushd $BINBUILDPATH
|
|
log ../binutils-$BINVER/configure --target=$TARGET --prefix=$INSTALLPATH --with-sysroot --disable-nls --disable-werror
|
|
log $MAKE $PARALLEL
|
|
log $MAKE install
|
|
touch built.txt
|
|
popd
|
|
fi
|
|
|
|
# Building GCC
|
|
if [ ! -f $GCCBUILDPATH/built.txt ]; then
|
|
echo building gcc
|
|
ARCH_OPTIONS=
|
|
if [ $ARCH == "arm" ]; then
|
|
ARCH_OPTIONS="--with-cpu=arm926ej-s --with-fpu=vfp"
|
|
fi
|
|
|
|
mkdir -p $GCCBUILDPATH
|
|
pushd $GCCBUILDPATH
|
|
log ../gcc-$GCCVER/configure --target=$TARGET --prefix=$INSTALLPATH --enable-languages=c --disable-nls --without-headers $ARCH_OPTIONS
|
|
log $MAKE all-gcc $PARALLEL
|
|
log $MAKE all-target-libgcc $PARALLEL
|
|
log $MAKE install-gcc
|
|
log $MAKE install-target-libgcc
|
|
touch built.txt
|
|
popd
|
|
fi
|
|
|
|
if [ ! -f $GDBBUILDPATH/built.txt ]; then
|
|
case "$TARGET" in
|
|
aarch64-elf) EXTRA_TARGETS="--enable-targets=arm-eabi" ;;
|
|
*) EXTRA_TARGETS="" ;;
|
|
esac
|
|
|
|
echo building gdb
|
|
mkdir -p $GDBBUILDPATH
|
|
pushd $GDBBUILDPATH
|
|
log ../gdb-$GDBVER/configure --target=$TARGET --prefix=$INSTALLPATH --disable-werror $EXTRA_TARGETS
|
|
log make $PARALLEL
|
|
log make install
|
|
touch built.txt
|
|
popd
|
|
fi
|
|
|
|
# Optionally strip the binaries
|
|
if [ "${STRIP}" = "1" ]; then
|
|
find "${INSTALLPATH}/bin" -type f -exec strip {} \;
|
|
for filename in $(find "${INSTALLPATH}/libexec" -type f); do
|
|
(file "${filename}" | grep -q ELF) && strip "${filename}"
|
|
done
|
|
fi
|
|
done
|
|
|
|
echo all done
|