#!/bin/sh

# This is my script for building a complete cross-compiler toolchain.
# It is based partly on Ray Kelm's script, which in turn was built on
# Mo Dejong's script for doing the same, but with some added fixes.
# The intent with this script is to build a cross-compiled version
# of the current MinGW environment.
#
# Updated by Sam Lantinga <slouken@libsdl.org>

# what flavor are we building?

TARGET=i586-mingw32msvc

# uncomment or add entries here

# where does it go? (your cross tools install directory)
#PREFIX=/usr/local/cross-tools

# if the prefix you are using needs root to access it please uncomment this
# (if you are using the above default prefix most likely you need this
#DO_SU=1

# your favorite downloader (pick one)

#DOWNLOADER="wget -c"
#DOWNLOADER="curl -#OLC -"
#DOWNLOADER="proz -rf"


# your platform specific optimisation flags. This is so that the compiler is optimised. This does not affect the win32 binaries in any way.
# CFLAGS="-O3 -march=pentium"

# your favorite mirror (pick one)

# austria
#MINGW_URL=ftp://gd.tuwien.ac.at/gnu/mingw
#MINGW_URL=http://gd.tuwien.ac.at/gnu/mingw

# Dublin, Ireland	Europe
#MINGW_URL=http://heanet.dl.sourceforge.net/sourceforge/mingw

#Chapel Hill, NC	North America
#MINGW_URL=http://unc.dl.sourceforge.net/sourceforge/mingw

# Minneapolis, MN	North America
#MINGW_URL=http://umn.dl.sourceforge.net/sourceforge/mingw

# Reston, VA	North America
#MINGW_URL=http://aleron.dl.sourceforge.net/sourceforge/mingw


# you probably don't need to change anything from here down

TOPDIR=`pwd`
SRCDIR="$TOPDIR/source"

# These are the files from the MinGW 1.1 release
GCC_VERSION=3.3.1-20030804-1
GCC=gcc-$GCC_VERSION
GCC_CORE=gcc-core-$GCC_VERSION
GCC_CORE_ARCHIVE=$GCC_CORE-src.tar.gz
GCC_GPP=gcc-g++-$GCC_VERSION
GCC_GPP_ARCHIVE=$GCC_GPP-src.tar.gz
GCC_PATCH=""
BINUTILS=binutils-2.13.90-20030111-1-src
BINUTILS_ARCHIVE=$BINUTILS.tar.gz
MINGW=mingw-runtime-3.2
MINGW_ARCHIVE=$MINGW.tar.gz
W32API=w32api-2.4
W32API_ARCHIVE=$W32API.tar.gz

# These are the files from the SDL website

SDL_URL=http://www.libsdl.org/extras/win32/common

# don't use the directx and opengl headers from SDL website, they are outdated and don't work with clanlib
# the opengl headers included in w32api-2.4 is better
# as for directx you need directx 8 for clanlib to work
#OPENGL_ARCHIVE=opengl-devel.tar.gz
#DIRECTX_ARCHIVE=directx-devel.tar.gz

# need install directory first on the path so gcc can find binutils

PATH="$PREFIX/bin:$PATH"

check_envars()
{
	echo "checking envars..."
	echo "If we bail out here, please edit this script to fix problems."
	if test -z $PREFIX; then
		echo "PREFIX not set, please set PREFIX to /usr/local/cross-tools or where-ever you want your cross tools"
		echo "Note that you will also need to set DO_SU=1 if your install path needs root access"
		exit 1
	fi
	if test -z $DOWNLOADER; then
		echo "DOWNLOADER not set, please set DOWNLOADER to your favorite download program like wget, curl..."
		exit 1
	fi
	if test -z $MINGW_URL; then
		echo "MINGW_URL not set, please set MINGW_URL to your favorite mirror"
	fi
	echo "done checking envars"
}

#
# download a file from a given url, only if it is not present
#

download_file()
{
	cd "$SRCDIR"
#	if test ! -f $1 ; then
		echo "Downloading $1"
		$DOWNLOADER "$2/$1"
		if test ! $? || test ! -f $1 ; then
			echo "Could not download $1"
			exit 1
		fi
#	else
#		echo "Found $1 in the srcdir $SRCDIR"
#	fi
  	cd "$TOPDIR"
}

download_files()
{
	mkdir -p "$SRCDIR"
	
	# Make sure wget is installed
	if test "x`which wget`" = "x" ; then
		echo "You need to install wget."
		exit 1
	fi
	download_file "$GCC_CORE_ARCHIVE" "$MINGW_URL"
	download_file "$GCC_GPP_ARCHIVE" "$MINGW_URL"
	download_file "$BINUTILS_ARCHIVE" "$MINGW_URL"
	download_file "$MINGW_ARCHIVE" "$MINGW_URL"
	download_file "$W32API_ARCHIVE" "$MINGW_URL"
#	download_file "$OPENGL_ARCHIVE" "$SDL_URL"
#	download_file "$DIRECTX_ARCHIVE" "$SDL_URL"
}

install_libs()
{
	echo "Installing cross libs and includes"
	cat >install_libs.sh<<INSTALL_LIBS
	mkdir -p "$PREFIX/$TARGET"
	cd "$PREFIX/$TARGET"
	gzip -dc "$SRCDIR/$MINGW_ARCHIVE" | tar xf -
	gzip -dc "$SRCDIR/$W32API_ARCHIVE" | tar xf -
#	gzip -dc "$SRCDIR/$OPENGL_ARCHIVE" | tar xf -
#	gzip -dc "$SRCDIR/$DIRECTX_ARCHIVE" | tar xf -
INSTALL_LIBS
	if test $DO_SU; then
		su -c 'sh install_libs.sh'
	else
		sh install_libs.sh
	fi
	rm -f install_libs.sh
	cd "$TOPDIR"
}

extract_binutils()
{
	cd "$SRCDIR"
	rm -rf "$BINUTILS"
	echo "Extracting binutils"
	gzip -dc "$SRCDIR/$BINUTILS_ARCHIVE" | tar xf -
	cd "$TOPDIR"
}

configure_binutils()
{
	cd "$TOPDIR"
	rm -rf "binutils-$TARGET"
	mkdir "binutils-$TARGET"
	cd "binutils-$TARGET"
	echo "Configuring binutils"
	"$SRCDIR/$BINUTILS/configure" --prefix="$PREFIX" --target=$TARGET &> configure.log
	cd "$TOPDIR"
}

build_binutils()
{
	cd "$TOPDIR/binutils-$TARGET"
	echo "Building binutils"
	make &> make.log
	if test $? -ne 0; then
		echo "make failed - log available: binutils-$TARGET/make.log"
		exit 1
	fi
	cd "$TOPDIR"
}

install_binutils()
{
	cd "$TOPDIR/binutils-$TARGET"
	echo "Installing binutils"
	if test $DO_SU; then
		su -c 'make install &> make-install.log'
	else
		make install &> make-install.log
	fi
	if test $? -ne 0; then
		echo "install failed - log available: binutils-$TARGET/make-install.log"
		exit 1
	fi
	cd "$TOPDIR"
}

extract_gcc()
{
	cd "$SRCDIR"
	rm -rf "$GCC"
	echo "Extracting gcc"
	gzip -dc "$SRCDIR/$GCC_CORE_ARCHIVE" | tar xf -
	gzip -dc "$SRCDIR/$GCC_GPP_ARCHIVE" | tar xf -
	cd "$TOPDIR"
}

patch_gcc()
{
	if [ "$GCC_PATCH" != "" ]; then
		echo "Patching gcc"
		cd "$SRCDIR/$GCC"
		patch -p1 < "$SRCDIR/$GCC_PATCH"
		cd "$TOPDIR"
	fi
}

configure_gcc()
{
	cd "$TOPDIR"
	rm -rf "gcc-$TARGET"
	mkdir "gcc-$TARGET"
	cd "gcc-$TARGET"
	echo "Configuring gcc"
	"$SRCDIR/$GCC/configure" -v \
		--prefix="$PREFIX" --target=$TARGET \
		--with-headers="$PREFIX/$TARGET/include" \
		--with-gnu-as --with-gnu-ld \
		--without-newlib --disable-multilib &> configure.log
	cd "$TOPDIR"
}

build_gcc()
{
	cd "$TOPDIR/gcc-$TARGET"
	echo "Building gcc"
	make LANGUAGES="c c++" &> make.log
	if test $? -ne 0; then
		echo "make failed - log available: gcc-$TARGET/make.log"
		exit 1
	fi
	cd "$TOPDIR"
}

install_gcc()
{
	cd "$TOPDIR/gcc-$TARGET"
	echo "Installing gcc"
	if test $DO_SU; then
		su -c 'make LANGUAGES="c c++" install &> make-install.log'
	else
		make LANGUAGES="c c++" install &> make-install.log
	fi
	if test $? -ne 0; then
		echo "install failed - log available: gcc-$TARGET/make-install.log"
		exit 1
	fi
	cd "$TOPDIR"
}

final_tweaks()
{
	echo "Finalizing installation"
cat >final_tweaks.sh<<FINAL_TWEAKS
	# remove gcc build headers
	rm -rf "$PREFIX/$TARGET/sys-include"

  # Add extra binary links
	if [ ! -f "$PREFIX/$TARGET/bin/objdump" ]; then
		ln "$PREFIX/bin/$TARGET-objdump" "$PREFIX/$TARGET/bin/objdump"
	fi
	if [ ! -f "$PREFIX/$TARGET/bin/dllwrap" ]; then
		ln "$PREFIX/bin/$TARGET-dllwrap" "$PREFIX/$TARGET/bin/dllwrap"
	fi
	if [ ! -f "$PREFIX/$TARGET/bin/windres" ]; then
		ln "$PREFIX/bin/$TARGET-windres" "$PREFIX/$TARGET/bin/windres"
	fi

	# make cc and c++ symlinks to gcc and g++
	if [ ! -f "$PREFIX/$TARGET/bin/g++" ]; then
		ln "$PREFIX/bin/$TARGET-g++" "$PREFIX/$TARGET/bin/g++"
	fi
	if [ ! -f "$PREFIX/$TARGET/bin/cc" ]; then
		ln -s "gcc" "$PREFIX/$TARGET/bin/cc"
	fi
	if [ ! -f "$PREFIX/$TARGET/bin/c++" ]; then
		ln -s "g++" "$PREFIX/$TARGET/bin/c++"
	fi

	# strip all the binaries
	ls "$PREFIX"/bin/* "$PREFIX/$TARGET"/bin/* | egrep -v '.dll$' |
	while read file; do
		strip "$file"
	done
FINAL_TWEAKS
	if test $DO_SU; then
		su -c 'sh final_tweaks.sh'
	else
		sh final_tweaks.sh
	fi
	rm -f final_tweaks.sh
	echo "Installation complete!"
}

check_envars

download_files

install_libs

extract_binutils
configure_binutils
build_binutils
install_binutils

extract_gcc
patch_gcc
configure_gcc
build_gcc
install_gcc

final_tweaks


