#!/bin/bash

############################################################################
#
# Script for generating a PowerPC cross compiler using crosstool.
#
# Copyright (C) 2009 Bart Van Assche <bvanassche@acm.org>.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation, version 2
# of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
############################################################################

#########################
# Function definitions  #
#########################

# Print an error message and exit.
abort() {
  echo "build failed: $@"
  exit 1
}

# Print command-line help.
usage() {
  cat <<EOF
Usage: $0 [-h] [-t crosstools-directory] [gcc-version glibc-version]
EOF
}

# Extract and run crosstool for the specified gcc and glibc versions.
generate_cross_compiler() {
  export GCC_DIR=gcc-$1
  export GLIBC_DIR=glibc-$2

  export GLIBCTHREADS_FILENAME=glibc-linuxthreads-$2
  # glibc-crypt is only needed for glibc 2.1.x and earlier glibc versions.
  unset GLIBCCRYPT_FILENAME
  if [ "${2#2.1.}" != "${2}" ]; then
    GLIBCCRYPT_FILENAME=glibc-crypt-2.1
  fi
  export GLIBCCRYPT_FILENAME
  unset GCC_CORE_DIR
  if [ "${1#4.}" != "${1}" -a "${2#2.[12].}" != "$2" ]; then
    # Use gcc 2.95.3 for compiling glibc 2.1.* and glibc 2.2.*.
    GCC_CORE_DIR=gcc-2.95.3
  else
    GCC_CORE_DIR=gcc-3.3.6
  fi
  export GCC_CORE_DIR

  export GCC_EXTRA_CONFIG="--disable-linux-futex --disable-mudflap --disable-nls"
  #GLIBC_ADDON_OPTIONS=

  # gcc 4.x aborts with a syntax error on glibc's inline functions if you do
  # not specify -fgnu89-inline.
  #if [ "${1#4.}" != "${1}" ]; then
  #  export TARGET_FLAGS="$TARGET_FLAGS -fgnu89-inline"
  #fi

  if ! /bin/rm -rf $RESULT_TOP/${GCC_DIR}-${GLIBC_DIR}; then
    abort "Need write permission in $RESULT_TOP/${GCC_DIR}-${GLIBC_DIR}"
  fi
  if ! /bin/mkdir -p $RESULT_TOP/$GCC_DIR-$GLIBC_DIR/$TARGET; then
    abort "Need write permission in $RESULT_TOP/${GCC_DIR}-${GLIBC_DIR}/$TARGET"
  fi

  /bin/rm -rf $CROSSTOOL_FOLDER
  if [ ! -e $TARBALLS_DIR/crosstool-${CROSSTOOL_VERSION}.tar.gz ]; then
    (
      if cd $TARBALLS_DIR; then
        wget -q -nc "http://kegel.com/crosstool/crosstool-${CROSSTOOL_VERSION}.tar.gz"
      fi
    )
  fi
  /bin/tar -zxf $TARBALLS_DIR/crosstool-${CROSSTOOL_VERSION}.tar.gz
  /bin/tar -C patches -cf - . | /bin/tar -C $CROSSTOOL_FOLDER/patches -xf -
  (
    cd $CROSSTOOL_FOLDER
    for f in ../crosstool-patches/*
    do
      patch -p1 -f < "$f" || exit $?
    done
    ./all.sh --notest
  )
  # /bin/rm -rf $CROSSTOOL_FOLDER
}


#########################
# Argument processing   #
#########################

if [ "$SHELL" = "/bin/tcsh" ]; then
  abort "tcsh is not supported."
fi

set -- $(/usr/bin/getopt ht: "$@")
while [ "${1#-}" != "${1}" ]; do
  case "$1" in
    -h) usage; exit 1;;
    -t) result_top="$2"; shift; shift;;
    --) shift;;
  esac
done

#########################
# Settings              #
#########################

set -e # Exit immediately if a simple command fails.
set -x # Enable echo mode.

# Variables that are ignored by crosstool.

CROSSTOOL_VERSION=0.43
CROSSTOOL_FOLDER=$PWD/crosstool-$CROSSTOOL_VERSION
KERNEL_VERSION=2.6.22
export LC_ALL=C


# Variables that are used by the crosstool script as input.

# Directory where cross-compilation tools will be installed.
export RESULT_TOP=${result_top:-$HOME/x86_64-ppc}
# Directory where the tool tar files can be found.
export TARBALLS_DIR=$HOME/software/downloads
# Target architecture: Pentium CPU, Linux OS.
export TARGET=powerpc-linux
# Compilation flags for target tools such as glibc.
export TARGET_CFLAGS="-O"
# Binutils version.
export BINUTILS_DIR=binutils-2.16.1
# Languages that must be supported by the gcc cross-compiler.
export GCC_LANGUAGES="c,c++"
# GDB version.
export GDB_DIR=gdb-6.8
# Linux kernel version.
export LINUX_DIR=linux-$KERNEL_VERSION
# Linux kernel config.
export KERNELCONFIG=$PWD/kernel-config/$KERNEL_VERSION/.config
# Make flags
export PARALLELMFLAGS="-s -j3"

##############################
# Cross-compiler generation. #
##############################

if ! /bin/mkdir -p $RESULT_TOP; then
  abort "You need write permission in $RESULT_TOP"
fi

if [ "$#" = 0 ]; then
  generate_cross_compiler 4.1.1  2.3.6
elif [ "$#" = 2 ]; then
  generate_cross_compiler "$1" "$2"
else
  usage
  abort "Wrong number of arguments."
fi