#!/bin/sh

#========================================
# contact: 
#   Takayama Fumihiko <tekezo@tkym.org>
#
# changelog
#  * 2002 01/05 add -fno-exceptions
#  * 2001 10/23 refine build process
#  * 2001 09/19 1st release
#
#========================================
# checked hosts 
#  * I tested this script on FreeBSD, NetBSD. 
#  * This script works on Linux (thanks Syo~ji)
#  * This script seems failed on cygwin. 
#    If you succeed building cross-environment on cygwin, mail me please. 
#
# Todo
#  * use KOS instead newlib.


#========================================
# HOWTO build
#
# 1st
#   edit below variable
#
# 2nd
#   put file to 
#     ${distfiles}/binutils-${binutils_version}.tar.gz
#     ${distfiles}/gcc-${gcc_version}.tar.gz
#     ${distfiles}/newlib-${newlib_version}.tar.gz
#
# 3rd
#   you type 
#     $ sh build-dreamcast-cross.sh rebuild 
#
#   building cross compiler takes a long time. wait. 
#

src_dir=/home/const/cross/src
prefix=/home/const/cross/dreamcast
distfiles=/home/const/distfiles/cross
binutils_version=2.11.2
gcc_version=3.0.3
newlib_version=1.9.0

local_make=gmake


#========================================
# don't edit below
PATH=${prefix}/bin:$PATH

echo_variable () {
    echo "%%% variables -------------------------"
    echo "%%% srcdir: $src_dir"
    echo "%%% prefix: $prefix"
    echo "%%% distfiles: $distfiles"
    echo "%%% binutils_version: $binutils_version"
    echo "%%% gcc_version: $gcc_version"
    echo "%%% newlib_version: $newlib_version"
    echo "%%% -----------------------------------"
}


do_command () {
    echo "%%% $1"
    eval $1
}


initialize_environment () {
    do_command "mkdir -p $src_dir"
    do_command "mkdir -p $prefix"
}


extract_src () {
    do_command "tar zxf $distfiles/binutils-${binutils_version}.tar.gz -C $src_dir"
    do_command "tar zxf $distfiles/gcc-${gcc_version}.tar.gz -C $src_dir"
    do_command "tar zxf $distfiles/newlib-${newlib_version}.tar.gz -C $src_dir"
}


patch_src () {
    cat > $distfiles/gcc-patch <<EOF
diff -ur ../../src-tmp/gcc-3.0.3/libstdc++-v3/libsupc++/eh_aux_runtime.cc libstdc++-v3/libsupc++/eh_aux_runtime.cc
--- ../../src-tmp/gcc-3.0.3/libstdc++-v3/libsupc++/eh_aux_runtime.cc	Sun May 13 16:10:26 2001
+++ libstdc++-v3/libsupc++/eh_aux_runtime.cc	Sat Jan  5 20:33:17 2002
@@ -30,6 +30,7 @@
 
 #include "typeinfo"
 #include "exception"
+#include <cstdlib>
 #include <cstddef>
 #include "unwind-cxx.h"
 #include "exception_defines.h"
diff -ur ../../src-tmp/gcc-3.0.3/libstdc++-v3/libsupc++/eh_personality.cc libstdc++-v3/libsupc++/eh_personality.cc
--- ../../src-tmp/gcc-3.0.3/libstdc++-v3/libsupc++/eh_personality.cc	Sun May 13 16:10:26 2001
+++ libstdc++-v3/libsupc++/eh_personality.cc	Sat Jan  5 20:42:30 2002
@@ -401,6 +401,7 @@
 extern "C" void
 __cxa_call_unexpected (_Unwind_Exception *exc_obj)
 {
+#if 0
   __cxa_begin_catch (exc_obj);
 
   // This function is a handler for our exception argument.  If we exit
@@ -440,4 +441,5 @@
     // Otherwise, die.
     __terminate(xh->terminateHandler);
   }
+#endif
 }
diff -ur ../../src-tmp/gcc-3.0.3/libstdc++-v3/libsupc++/new_op.cc libstdc++-v3/libsupc++/new_op.cc
--- ../../src-tmp/gcc-3.0.3/libstdc++-v3/libsupc++/new_op.cc	Sun Feb 18 03:13:09 2001
+++ libstdc++-v3/libsupc++/new_op.cc	Sat Jan  5 20:43:18 2002
@@ -28,6 +28,7 @@
 // the GNU General Public License.
 
 #include "new"
+#include <cstdlib>
 #include <exception_defines.h>
 
 using std::new_handler;
EOF
    do_command "cd $src_dir/gcc-${gcc_version}"
    do_command "patch < $distfiles/gcc-patch"
}


remove_src () {
    do_command "rm -rf $src_dir/binutils-*"
    do_command "rm -rf $src_dir/gcc-*"
    do_command "rm -rf $src_dir/newlib-*"
}


distclean () {
    do_command "rm -rf $src_dir/sh-elf"
    do_command "rm -rf $src_dir/arm-elf"
    do_command "rm -rf $prefix/*"
}


# Usage: build_binutils target
build_binutils () {
    local configure_args=""
    local line=""
    
    do_command "rm -rf $src_dir/$1/binutils"
    do_command "mkdir -p $src_dir/$1/binutils"
    do_command "cd $src_dir/$1/binutils"
    
    configure_args="$configure_args --target=$1"
    configure_args="$configure_args --prefix=$prefix"
    configure_args="$configure_args -v"
    
    line="$line $src_dir/binutils-${binutils_version}/configure $configure_args"
    line="$line &&"
    line="$line ${local_make} all check install"
    do_command "$line"
}


# Usage: build_gcc target configure-args
build_gcc () {
    local configure_args=""
    local line=""
    
    do_command "mkdir -p $prefix/$1"
    do_command "cp -R $src_dir/newlib-${newlib_version}/newlib/libc/include $prefix/$1"
    
    do_command "rm -rf $src_dir/$1/gcc"
    do_command "mkdir -p $src_dir/$1/gcc"
    do_command "cd $src_dir/$1/gcc"
    
    configure_args="$configure_args --target=$1"
    configure_args="$configure_args --prefix=$prefix"
    configure_args="$configure_args --disable-threads"
    configure_args="$configure_args --with-newlib"
    configure_args="$configure_args --with-gnu-ld"
    configure_args="$configure_args --with-gnu-as"
    configure_args="$configure_args --enable-cxx-flags='-fno-exceptions'"
    configure_args="$configure_args $2"
    configure_args="$configure_args -v"
    
    line="$line $src_dir/gcc-${gcc_version}/configure $configure_args"
    line="$line &&"
    line="$line ${local_make} all check install ASFLAGS+='-little'"
    do_command "$line"
}


# Usage: build_newlib target
build_newlib () {
    local configure_args=""
    local line=""
    
    do_command "rm -rf $src_dir/$1/newlib"
    do_command "mkdir -p $src_dir/$1/newlib"
    do_command "cd $src_dir/$1/newlib"
    
    configure_args="$configure_args --target=$1"
    configure_args="$configure_args --prefix=$prefix"
    configure_args="$configure_args -v"
    
    line="$line $src_dir/newlib-${newlib_version}/configure $configure_args"
    line="$line &&"
    line="$line ${local_make} all check install ASFLAGS+='-little'"
    do_command "$line"
}


build_sh_elf () {
    build_binutils sh-elf && \
	build_gcc sh-elf '--with-cpu=sh4 --enable-languages=c,c++' && \
	build_newlib sh-elf
}


build_arm_elf () {
    build_binutils arm-elf && \
	build_gcc arm-elf '--enable-languages=c' && \
	build_newlib arm-elf
}


case "$1" in
    initialize) 
	initialize_environment
	;;
    extract)
	extract_src
	;;
    remove)
	remove_src
	;;
    distclean)
	distclean
	;;
    build-sh-elf)
	build_sh_elf
	;;
    build-arm-elf)
	build_arm_elf
	;;
    all)
	build_sh_elf && build_arm_elf
	;;
    rebuild)
	echo_variable && \
	    distclean && \
	    remove_src && \
	    initialize_environment && \
	    extract_src && \
	    patch_src && \
	    build_sh_elf && \
	    build_arm_elf
	;;
    *)
	echo "Usage: `basename $0` initialize|extract|distclean|remove|build-sh-elf|build-arm-elf|all|rebuild"
	exit 1
	;;
esac



