#!/bin/sh

# Automates the steps described in
# $/Documents/Internal/SWDocs/Documents-Internal/linux/gcc_3_for_PPC405_HHL_2_0.html
# $/Documents/Internal/SWDocs/Documents-Internal/linux/gcc_3_for_PPC7xx_HHL_2_0.html
# $/Documents/Internal/SWDocs/Documents-Internal/linux/gcc_3_for_SH4_HHL_2_0.html
#
# Must be run as root.

if [ $# -lt 1 ]; then
    echo "Usage: $0 arch ..."
    echo "Purpose: Download gcc 3.0.2, build for the specified architecture(s) and install in the HardHat tree."
    echo "Architectures are sh4, ppc405, and ppc750."
    exit 1
fi

errexit () {
    set +x
    echo "$0: $1, aborting..."
    exit ${2:-1}
}

# check architecture validity
for arch; do
    case $arch in
	sh4|ppc405|ppc750) : ;;
	* ) errexit "Unsupported architecture $arch" ;;
    esac
done

getdl () {
    echo "Downloading $@"
    # Get files, continuing interrupted ones where they left off
    wget -nc --dot-style=mega "$@"
}

set -x -e

WORKDIR=`pwd`
SRC=`cd \`dirname $0\`; pwd`
PATH_ORIG=$PATH

# Download gcc3 tarballs
#getdl ftp://ftp.gnu.org/pub/gnu/gcc/gcc-3.0.2/gcc-core-3.0.2.tar.gz
#getdl ftp://ftp.gnu.org/pub/gnu/gcc/gcc-3.0.2/gcc-g++-3.0.2.tar.gz
getdl ftp://ftp.gnu.org/pub/gnu/gcc/gcc-3.0.2/gcc-3.0.2.tar.gz
# Patch for sh4 support
getdl ftp://ftp.m17n.org/pub/linux-sh/testing/gcc-sh-linux_3.0.2-3.diff.gz

for arch; do

    case $arch in
	sh4)
	    GNU_ARCH=sh4-linux
	    HHL_CROSS_ARCH=sh4el-hardhat-linux
	    GNU_TOOL_PREFIX=$GNU_ARCH-
	    HHL_TOOL_PREFIX=sh_sh4_le-
	    LSP_DIR=/opt/hardhat/devkit/sh/sh4_le
	    CONFIG_OPTS="--disable-c99 --disable-nls"
	    GCC_TARGET_CONFIGDIRS="libiberty libstdc++-v3"
	    ;;
	ppc405)
	    GNU_ARCH=powerpc-linux
	    HHL_CROSS_ARCH=powerpc-hardhat-linux
	    GNU_TOOL_PREFIX=$GNU_ARCH-
	    HHL_TOOL_PREFIX=ppc_405-
	    LSP_DIR=/opt/hardhat/devkit/ppc/405
	    CONFIG_OPTS="--with-cpu=403 --nfp"
	    GCC_TARGET_CONFIGDIRS="libiberty libstdc++-v3 boehm-gc zlib"
	    ;;
	ppc750)
	    GNU_ARCH=powerpc-linux
	    HHL_CROSS_ARCH=powerpc-hardhat-linux
	    GNU_TOOL_PREFIX=$GNU_ARCH-
	    HHL_TOOL_PREFIX=ppc_7xx-
	    LSP_DIR=/opt/hardhat/devkit/ppc/7xx
	    CONFIG_OPTS="--with-cpu=750"
	    GCC_TARGET_CONFIGDIRS="libiberty libstdc++-v3 boehm-gc zlib"
	    ;;
    esac
    # Muck around in the hardhat tree to let the gcc build process find what it
    # needs.  FIXME These steps must all be run as root.
    cd $LSP_DIR

    # Avoid exit if links exist by using a subshell
    (
	ln -s $HHL_CROSS_ARCH $GNU_ARCH
	cd bin
	for tool in ar as ld nm objcopy ranlib strip; do
	    ln -s ${HHL_TOOL_PREFIX}$tool ${GNU_TOOL_PREFIX}$tool
	done
    )

    find . -name crt?.o -exec cp {} $GNU_ARCH/lib \;

    # Extract the source into the same directory as their tarballs
    cd $WORKDIR
    rm -rf gcc-3.0.2
    tar zxf gcc-3.0.2.tar.gz
    #tar zxvf gcc-core-3.0.2.tar.gz
    #tar zxvf gcc-g++-3.0.2.tar.gz

    # Apply Patches
    cd gcc-3.0.2
    if [ $arch = sh4 ]; then
        # FIXME doesn't stop if patchfile not found
        zcat ../gcc-sh-linux_3.0.2-3.diff.gz | patch -p1
        test $? -ne 0 && errexit "Patch failed."
    fi
    # Remove the modules we don't need
    rm -rf libffi libjava libobjc gcc/java gcc/objc
    
    # Apply libstdc++ stringstream thread safety patch
    cd libstdc++-v3
    patch -p0 < $SRC/libstdc++-locale.patch
    cd ../..

    # Set PATH to include cross compiling tools
    PATH=$LSP_DIR/bin:$PATH_ORIG
    export PATH

    rm -rf gcc-build-$arch
    mkdir gcc-build-$arch
    cd gcc-build-$arch
    ../gcc-3.0.2/configure \
            --target=$GNU_ARCH \
            --prefix=$LSP_DIR \
            --with-headers=$LSP_DIR/target/usr/include \
            --enable-shared \
            --enable-long-long \
            --enable-threads=posix \
            --enable-langugages=c,c++ \
            $CONFIG_OPTS
    
    mv -f Makefile Makefile.orig
    sed -e 's/^TARGET_CONFIGDIRS.*$/TARGET_CONFIGDIRS = '"$GCC_TARGET_CONFIGDIRS/" Makefile.orig > Makefile

    make
    make install

    test $arch = sh4 && rm $LSP_DIR/target/usr/lib/libstdc++.* ||
        echo "Warning: no old libstdc++ files removed."
    if [ $arch = ppc405 ]; then
	cp -d $LSP_DIR/$GNU_ARCH/lib/nof/libs* $LSP_DIR/target/usr/lib
	cp -d $LSP_DIR/$GNU_ARCH/lib/libgcc_s_nof* $LSP_DIR/target/lib
    else
	cp -d $LSP_DIR/$GNU_ARCH/lib/libs* $LSP_DIR/target/usr/lib
	cp -d $LSP_DIR/$GNU_ARCH/lib/libgcc_s* $LSP_DIR/target/lib
    fi
    cp -R -d $LSP_DIR/include/g++-v3 $LSP_DIR/target/usr/include

done

