diff --git a/build.sh b/build.sh
index 7ad5a834343a28fcc7ccc571a92a3637f505a224..c3b66f4c6de9b5b6b62235afad072c777e59eba5 100755
--- a/build.sh
+++ b/build.sh
@@ -1,7 +1,7 @@
 #!/bin/bash
 
 ###########################################################################
-#   Copyright (C) 2008 by Oliver Bock                                     #
+#   Copyright (C) 2008-2009 by Oliver Bock                                #
 #   oliver.bock[AT]aei.mpg.de                                             #
 #                                                                         #
 #   This file is part of Einstein@Home.                                   #
@@ -20,9 +20,6 @@
 #                                                                         #
 ###########################################################################
 
-### TODOs #################################################################
-
-# more refactoring (every lib in dedicated function? per traget?)
 
 ### globals ###############################################################
 
@@ -30,9 +27,32 @@ ROOT=`pwd`
 PATH_ORG="$PATH"
 PATH_MINGW="$PATH"
 LOGFILE=$ROOT/build.log
+
 TARGET=0
+TARGET_LINUX=1
+TARGET_MAC_INTEL=2
+TARGET_MAC_PPC=4
+TARGET_WIN32=8
+TARGET_DOC=16
 
-### functions #############################################################
+BUILDSTATE=0
+BS_PREREQUISITES=1
+BS_PREPARE_TREE=2
+BS_BUILD_SDL=3
+BS_BUILD_FREETYPE=4
+BS_BUILD_LIBXML=6
+BS_BUILD_OGLFT=5
+BS_BUILD_BOINC=7
+BS_PREPARE_MINGW=8
+BS_BUILD_MINGW=9
+BS_BUILD_BINUTILS_MINGW=10
+BS_BUILD_SDL_MINGW=11
+BS_BUILD_FREETYPE_MINGW=12
+BS_BUILD_LIBXML_MINGW=13
+BS_BUILD_OGLFT_MINGW=14
+BS_BUILD_BOINC_MINGW=15
+
+### functions (tools) #############################################################
 
 failure()
 {
@@ -53,381 +73,595 @@ failure()
     exit 1
 }
 
+
+distclean()
+{
+    cd $ROOT || failure
+
+    echo "Purging build system..." | tee -a $LOGFILE
+
+    rm -rf 3rdparty || failure
+    rm -rf build || failure
+    rm -rf install || failure
+    rm -rf doc/html || failure
+    rm -f doc/*.tag || failure
+
+    rm -f .lastbuild || failure
+    rm -f .buildstate || failure
+}
+
+
+check_last_build()
+{
+    echo "Checking previous build target..." | tee -a $LOGFILE
+
+    LASTBUILD=`cat .lastbuild 2>/dev/null`
+
+    if [[ ( -f .lastbuild ) && ( "$LASTBUILD" != "$1" ) ]]; then
+        cd $ROOT || failure
+        echo "Build target changed! Purging build and install trees..." | tee -a $LOGFILE
+        rm -rf build >> $LOGFILE || failure
+        rm -rf install >> $LOGFILE || failure
+        prepare_tree || failure
+    fi
+
+    echo "$1" > .lastbuild || failure
+
+    return 0
+}
+
+
+check_build_state()
+{
+    echo "Checking for previous build checkpoints..." | tee -a $LOGFILE
+
+    if [ ! -f .buildstate ]; then
+        cd $ROOT || failure
+        echo "No previous build checkpoints found! Starting from scratch..." | tee -a $LOGFILE
+    else
+        BUILDSTATE=`cat $ROOT/.buildstate 2>/dev/null`
+        echo "Recovering previous build..."
+    fi
+
+    return 0
+}
+
+
+store_build_state()
+{
+    echo "Saving build checkpoint..." | tee -a $LOGFILE
+    echo "$1" > $ROOT/.buildstate || failure
+
+    return 0
+}
+
+
+### functions (features) #############################################################
+
 check_prerequisites()
 {
-	echo "Checking prerequisites..." | tee -a $LOGFILE
-	
-	# required toolchain
-	TOOLS="automake autoconf m4 cmake wget svn cvs tar patch gcc g++ ld libtool ar lex yacc pkg-config"
-
-	for tool in $TOOLS; do
-		if ! ( type $tool >/dev/null 2>&1 ); then
-			echo "Missing \"$tool\" which is a required tool!" | tee -a $LOGFILE
-			return 1
-		fi
-	done
+    if [ $BUILDSTATE -ge $BS_PREREQUISITES ]; then
+        return 0
+    fi
 
-	return 0
+    echo "Checking prerequisites..." | tee -a $LOGFILE
+
+    # required toolchain
+    TOOLS="automake autoconf m4 cmake wget svn cvs tar patch gcc g++ ld libtool ar lex yacc pkg-config"
+
+    for tool in $TOOLS; do
+        if ! ( type $tool >/dev/null 2>&1 ); then
+            echo "Missing \"$tool\" which is a required tool!" | tee -a $LOGFILE
+            return 1
+        fi
+    done
+
+    return 0
 }
 
 
-prepare_source_tree()
+prepare_tree()
 {
-	echo "Preparing source tree..." | tee -a $LOGFILE
-	mkdir -p 3rdparty/oglft >> $LOGFILE || failure
-	mkdir -p 3rdparty/boinc >> $LOGFILE || failure
+    if [ $BUILDSTATE -ge $BS_PREPARE_TREE ]; then
+        return 0
+    fi
 
-	return 0
+    echo "Preparing tree..." | tee -a $LOGFILE
+    mkdir -p 3rdparty >> $LOGFILE || failure
+    mkdir -p install/bin >> $LOGFILE || failure
+    mkdir -p install/include >> $LOGFILE || failure
+    mkdir -p install/lib >> $LOGFILE || failure
+
+    store_build_state $BS_PREPARE_TREE
+    return 0
 }
 
 
-prepare_build_tree()
+prepare_mingw()
 {
-	echo "Preparing build tree..." | tee -a $LOGFILE
-	mkdir -p build/sdl >> $LOGFILE || failure
-	mkdir -p build/freetype2 >> $LOGFILE || failure
-	mkdir -p build/libxml2 >> $LOGFILE || failure
-	mkdir -p build/oglft >> $LOGFILE || failure
-	mkdir -p build/boinc >> $LOGFILE || failure
-	mkdir -p build/framework >> $LOGFILE || failure
-	mkdir -p build/orc >> $LOGFILE || failure
-	mkdir -p build/starsphere >> $LOGFILE || failure
+    if [ $BUILDSTATE -ge $BS_PREPARE_MINGW ]; then
+        return 0
+    fi
 
-	return 0
+    cd $ROOT || failure
+
+    echo "Preparing MinGW source tree..." | tee -a $LOGFILE
+    mkdir -p 3rdparty/mingw/xscripts >> $LOGFILE || failure
+    cd 3rdparty/mingw/xscripts || failure
+
+    if [ -d CVS ]; then
+        echo "Updating MinGW build script..." | tee -a $LOGFILE
+        cvs update -C >> $LOGFILE 2>&1 || failure
+    else
+        cd .. || failure
+        echo "Retrieving MinGW build script (this may take a while)..." | tee -a $LOGFILE
+        cvs -z3 -d:pserver:anonymous@mingw.cvs.sourceforge.net:/cvsroot/mingw checkout -P xscripts >> $LOGFILE 2>&1 || failure
+    fi
+
+    echo "Preparing MinGW build script..." | tee -a $LOGFILE
+    cd $ROOT/3rdparty/mingw/xscripts || failure
+    # note: svn has no force/overwrite switch. the file might not be updated when patched
+    patch x86-mingw32-build.sh.conf < $ROOT/patches/x86-mingw32-build.sh.conf.patch >> $LOGFILE || failure
+    chmod +x x86-mingw32-build.sh >> $LOGFILE || failure
+
+    store_build_state $BS_PREPARE_MINGW
+    return 0
 }
 
 
-prepare_install_tree()
+prepare_sdl()
 {
-	echo "Preparing install tree..." | tee -a $LOGFILE
-	mkdir -p install/bin >> $LOGFILE || failure
-	mkdir -p install/include >> $LOGFILE || failure
-	mkdir -p install/lib >> $LOGFILE || failure
+    echo "Preparing SDL..." | tee -a $LOGFILE
+    mkdir -p $ROOT/3rdparty/sdl >> $LOGFILE || failure
+    mkdir -p $ROOT/build/sdl >> $LOGFILE || failure
+
+    cd $ROOT/3rdparty/sdl || failure
+    if [ -d .svn ]; then
+        echo "Updating SDL..." | tee -a $LOGFIL
+        # make sure local changes (patches) are reverted, hence also updated
+        svn revert -R . >> $LOGFILE 2>&1 || failure
+        svn update >> $LOGFILE 2>&1 || failure
+    else
+        echo "Retrieving SDL (this may take a while)..." | tee -a $LOGFILE
+        svn checkout http://svn.libsdl.org/branches/SDL-1.2 . >> $LOGFILE 2>&1 || failure
+    fi
 
-	return 0
+    return 0
 }
 
 
-prepare_generic()
+prepare_freetype()
 {
-	prepare_source_tree || failure
-	prepare_build_tree || failure
-	prepare_install_tree || failure
-
-	# prepare additional sources
-
-	cd $ROOT || failure
-	mkdir -p 3rdparty/sdl >> $LOGFILE 2>&1 || failure
-	cd $ROOT/3rdparty/sdl || failure
-	if [ -d .svn ]; then
-		echo "Updating SDL..." | tee -a $LOGFIL
-		# make sure local changes (patches) are reverted, hence also updated
-		svn revert -R . >> $LOGFILE 2>&1 || failure
-		svn update >> $LOGFILE 2>&1 || failure
-	else
-		echo "Retrieving SDL (this may take a while)..." | tee -a $LOGFILE
-		svn checkout http://svn.libsdl.org/branches/SDL-1.2 . >> $LOGFILE 2>&1 || failure
-	fi
-	
-	echo "Retrieving Freetype2 (this may take a while)..." | tee -a $LOGFILE
-	cd $ROOT/3rdparty || failure
-	wget http://mesh.dl.sourceforge.net/sourceforge/freetype/freetype-2.3.5.tar.bz2 >> $LOGFILE 2>&1 || failure
-	tar -xjf freetype-2.3.5.tar.bz2 >> $LOGFILE 2>&1 || failure
-	rm freetype-2.3.5.tar.bz2 >> $LOGFILE 2>&1 || failure
-	# substitute old source tree
-	rm -rf freetype2 >> $LOGFILE 2>&1 || failure
-	mv freetype-2.3.5 freetype2 >> $LOGFILE 2>&1 || failure
-
-	echo "Retrieving libxml2 (this may take a while)..." | tee -a $LOGFILE
-	cd $ROOT/3rdparty || failure
-	wget --passive-ftp ftp://xmlsoft.org/libxml2/libxml2-sources-2.6.32.tar.gz >> $LOGFILE 2>&1 || failure
-	tar -xzf libxml2-sources-2.6.32.tar.gz >> $LOGFILE 2>&1 || failure
-	rm libxml2-sources-2.6.32.tar.gz >> $LOGFILE 2>&1 || failure
-	# substitute old source tree
-	rm -rf libxml2 >> $LOGFILE 2>&1 || failure
-	mv libxml2-2.6.32 libxml2 >> $LOGFILE 2>&1 || failure
-	
-	cd $ROOT/3rdparty/oglft || failure
-	if [ -d .svn ]; then
-		echo "Updating OGLFT..." | tee -a $LOGFILE
-		# make sure local changes (patches) are reverted, hence also updated
-		svn revert -R . >> $LOGFILE  2>&1 || failure
-		svn update >> $LOGFILE  2>&1 || failure
-	else
-		echo "Retrieving OGLFT (this may take a while)..." | tee -a $LOGFILE
-		svn checkout http://oglft.svn.sourceforge.net/svnroot/oglft/trunk . >> $LOGFILE 2>&1 || failure
-	fi
-	
-	cd $ROOT/3rdparty/boinc || failure
-	if [ -d .svn ]; then
-		echo "Updating BOINC..." | tee -a $LOGFILE
-		# make sure local changes (patches) are reverted, hence also updated
-		svn revert -R . >> $LOGFILE  2>&1 || failure
-		svn update >> $LOGFILE  2>&1 || failure
-	else
-		echo "Retrieving BOINC (this may take a while)..." | tee -a $LOGFILE
-		svn checkout http://boinc.berkeley.edu/svn/branches/server_stable . >> $LOGFILE 2>&1 || failure
-	fi
+    echo "Preparing Freetype2..." | tee -a $LOGFILE
+    mkdir -p $ROOT/build/freetype2 >> $LOGFILE || failure
+
+    echo "Retrieving Freetype2 (this may take a while)..." | tee -a $LOGFILE
+    cd $ROOT/3rdparty || failure
+    wget http://mesh.dl.sourceforge.net/sourceforge/freetype/freetype-2.3.5.tar.bz2 >> $LOGFILE 2>&1 || failure
+    tar -xjf freetype-2.3.5.tar.bz2 >> $LOGFILE 2>&1 || failure
+    rm freetype-2.3.5.tar.bz2 >> $LOGFILE 2>&1 || failure
+    # substitute old source tree
+    rm -rf freetype2 >> $LOGFILE 2>&1 || failure
+    mv freetype-2.3.5 freetype2 >> $LOGFILE 2>&1 || failure
+
+    return 0
+}
 
-	return 0
+
+prepare_libxml()
+{
+    echo "Preparing libxml2..." | tee -a $LOGFILE
+    mkdir -p $ROOT/build/libxml2 >> $LOGFILE || failure
+
+    echo "Retrieving libxml2 (this may take a while)..." | tee -a $LOGFILE
+    cd $ROOT/3rdparty || failure
+    rm -f libxml2-sources-2.6.32.tar.gz >> $LOGFILE 2>&1 || failure
+    wget --passive-ftp ftp://xmlsoft.org/libxml2/libxml2-sources-2.6.32.tar.gz >> $LOGFILE 2>&1 || failure
+    tar -xzf libxml2-sources-2.6.32.tar.gz >> $LOGFILE 2>&1 || failure
+    rm libxml2-sources-2.6.32.tar.gz >> $LOGFILE 2>&1 || failure
+    # substitute old source tree
+    rm -rf libxml2 >> $LOGFILE 2>&1 || failure
+    mv libxml2-2.6.32 libxml2 >> $LOGFILE 2>&1 || failure
+
+    return 0
 }
 
 
-prepare_win32()
+prepare_oglft()
 {
-	cd $ROOT || failure
+    echo "Preparing OGLFT..." | tee -a $LOGFILE
+    mkdir -p $ROOT/3rdparty/oglft >> $LOGFILE || failure
+    mkdir -p $ROOT/build/oglft >> $LOGFILE || failure
+
+    cd $ROOT/3rdparty/oglft || failure
+    if [ -d .svn ]; then
+        echo "Updating OGLFT..." | tee -a $LOGFILE
+        # make sure local changes (patches) are reverted, hence also updated
+        svn revert -R . >> $LOGFILE  2>&1 || failure
+        svn update >> $LOGFILE  2>&1 || failure
+    else
+        echo "Retrieving OGLFT (this may take a while)..." | tee -a $LOGFILE
+        svn checkout http://oglft.svn.sourceforge.net/svnroot/oglft/trunk . >> $LOGFILE 2>&1 || failure
+    fi
+}
 
-	echo "Preparing MinGW source tree..." | tee -a $LOGFILE
-	mkdir -p 3rdparty/mingw/xscripts >> $LOGFILE || failure
-	cd 3rdparty/mingw/xscripts || failure
 
-	if [ -d CVS ]; then
-		echo "Updating MinGW build script..." | tee -a $LOGFILE
-		cvs update -C >> $LOGFILE 2>&1 || failure
-	else
-		cd .. || failure
-		echo "Retrieving MinGW build script (this may take a while)..." | tee -a $LOGFILE
-		cvs -z3 -d:pserver:anonymous@mingw.cvs.sourceforge.net:/cvsroot/mingw checkout -P xscripts >> $LOGFILE 2>&1 || failure
-	fi
-	
-	echo "Preparing MinGW build script..." | tee -a $LOGFILE
-	cd $ROOT/3rdparty/mingw/xscripts || failure
-	# note: svn has no force/overwrite switch. the file might not be updated when patched
-	patch x86-mingw32-build.sh.conf < $ROOT/patches/x86-mingw32-build.sh.conf.patch >> $LOGFILE || failure
-	chmod +x x86-mingw32-build.sh >> $LOGFILE || failure
+prepare_boinc()
+{
+    echo "Preparing BOINC..." | tee -a $LOGFILE
+    mkdir -p $ROOT/3rdparty/boinc >> $LOGFILE || failure
+    mkdir -p $ROOT/build/boinc >> $LOGFILE || failure
+
+    cd $ROOT/3rdparty/boinc || failure
+    if [ -d .svn ]; then
+        echo "Updating BOINC..." | tee -a $LOGFILE
+        # make sure local changes (patches) are reverted, hence also updated
+        svn revert -R . >> $LOGFILE  2>&1 || failure
+        svn update >> $LOGFILE  2>&1 || failure
+    else
+        echo "Retrieving BOINC (this may take a while)..." | tee -a $LOGFILE
+        svn checkout http://boinc.berkeley.edu/svn/branches/server_stable . >> $LOGFILE 2>&1 || failure
+    fi
 
-	return 0
+    return 0
 }
 
 
-build_generic()
+build_sdl()
 {
-	echo "Building SDL (this may take a while)..." | tee -a $LOGFILE
-	cd $ROOT/3rdparty/sdl || failure
-	chmod +x autogen.sh >> $LOGFILE 2>&1 || failure
-	./autogen.sh >> $LOGFILE 2>&1 || failure
-	chmod +x configure >> $LOGFILE 2>&1 || failure
-	cd $ROOT/build/sdl || failure
-	if [ "$1" == "$TARGET_MAC_INTEL" -o "$1" == "$TARGET_MAC_PPC" ]; then
-		$ROOT/3rdparty/sdl/configure --prefix=$ROOT/install --enable-shared=no --enable-static=yes --enable-screensaver=yes --enable-video-x11=no >> $LOGFILE 2>&1 || failure
-	else
-		$ROOT/3rdparty/sdl/configure --prefix=$ROOT/install --enable-shared=no --enable-static=yes --enable-screensaver=yes >> $LOGFILE 2>&1 || failure	
-	fi
-	make >> $LOGFILE 2>&1 || failure
-	make install >> $LOGFILE 2>&1 || failure
-	echo "Successfully built and installed SDL!" | tee -a $LOGFILE
-
-	echo "Building Freetype2 (this may take a while)..." | tee -a $LOGFILE
-	cd $ROOT/3rdparty/freetype2 || failure
-	chmod +x autogen.sh >> $LOGFILE 2>&1 || failure
-	./autogen.sh >> $LOGFILE 2>&1 || failure
-	chmod +x configure >> $LOGFILE 2>&1 || failure
-	cd $ROOT/build/freetype2 || failure
-	# note: freetype (or sdl?) probably doesn't need *no* configure when static -> ansi build, see readme!
-	$ROOT/3rdparty/freetype2/configure --prefix=$ROOT/install --enable-shared=no --enable-static=yes >> $LOGFILE 2>&1 || failure
-	make >> $LOGFILE 2>&1 || failure
-	make install >> $LOGFILE 2>&1 || failure
-	echo "Successfully built and installed Freetype2!" | tee -a $LOGFILE
-
-	echo "Building libxml2 (this may take a while)..." | tee -a $LOGFILE
-	cd $ROOT/3rdparty/libxml2 || failure
-	chmod +x configure >> $LOGFILE 2>&1 || failure
-	cd $ROOT/build/libxml2 || failure
-	$ROOT/3rdparty/libxml2/configure --prefix=$ROOT/install --enable-shared=no --enable-static=yes >> $LOGFILE 2>&1 || failure
-	make >> $LOGFILE 2>&1 || failure
-	make install >> $LOGFILE 2>&1 || failure
-	echo "Successfully built and installed libxml2!" | tee -a $LOGFILE
-
-	echo "Patching OGLFT..." | tee -a $LOGFILE
-	cd $ROOT/3rdparty/oglft || failure
-	# note: svn has no force/overwrite switch. patched files might not be updated
-	# patch: use fixed settings for freetype, deactivate FindFreetype
-	FREETYPE2_INCLUDE_DIR="$ROOT/install/include"
-	FREETYPE2_LIBRARIES="$ROOT/install/lib/libfreetype.a"
-	patch CMakeLists.txt < $ROOT/patches/CMakeLists.txt.oglft.patch >> $LOGFILE 2>&1 || failure
-	echo "Building OGLFT..." | tee -a $LOGFILE
-	cd $ROOT/build/oglft || failure
-	# TODO: do we wanna create universal binaries on mac? If so, add -DCMAKE_OSX_ARCHITECTURES=ppc;i386
-	cmake -DFREETYPE2_INCLUDE_DIR="$FREETYPE2_INCLUDE_DIR" -DFREETYPE2_LIBRARIES="$FREETYPE2_LIBRARIES" $ROOT/3rdparty/oglft >> $LOGFILE 2>&1 || failure
-	make >> $LOGFILE 2>&1 || failure
-	mkdir -p $ROOT/install/include/oglft >> $LOGFILE 2>&1 || failure
-	cp OGLFT.h $ROOT/install/include/oglft >> $LOGFILE 2>&1 || failure
-	cp liboglft/liboglft.a $ROOT/install/lib >> $LOGFILE 2>&1 || failure
-	echo "Successfully built and installed OGLFT!" | tee -a $LOGFILE
-
-	echo "Configuring BOINC..." | tee -a $LOGFILE
-	cd $ROOT/3rdparty/boinc || failure
-	chmod +x _autosetup >> $LOGFILE 2>&1 || failure
-	./_autosetup >> $LOGFILE 2>&1 || failure
-	chmod +x configure >> $LOGFILE 2>&1 || failure
-	cd $ROOT/build/boinc || failure
-	if [ "$1" == "$TARGET_MAC_INTEL" -o "$1" == "$TARGET_MAC_PPC" ]; then
-		export CPPFLAGS=-I/sw/include
-		$ROOT/3rdparty/boinc/configure --prefix=$ROOT/install --enable-shared=no --enable-static=yes --disable-server --disable-client --with-apple-opengl-framework --enable-install-headers --enable-libraries --disable-manager --disable-fcgi >> $LOGFILE 2>&1 || failure
-	elif [ -d "/usr/local/ssl" ]; then
-		echo "Using local SSL library..." | tee -a $LOGFILE
-		$ROOT/3rdparty/boinc/configure --prefix=$ROOT/install --enable-shared=no --enable-static=yes --disable-server --disable-client --enable-install-headers --enable-libraries --disable-manager --disable-fcgi CPPFLAGS=-I/usr/local/ssl/include LDFLAGS=-L/usr/local/ssl/lib >> $LOGFILE 2>&1 || failure
-	else
-		$ROOT/3rdparty/boinc/configure --prefix=$ROOT/install --enable-shared=no --enable-static=yes --disable-server --disable-client --enable-install-headers --enable-libraries --disable-manager --disable-fcgi >> $LOGFILE 2>&1 || failure
-	fi
-	echo "Building BOINC (this may take a while)..." | tee -a $LOGFILE
-	make >> $LOGFILE 2>&1 || failure
-	make install >> $LOGFILE 2>&1 || failure
-	echo "Successfully built and installed BOINC!" | tee -a $LOGFILE
+    if [ $BUILDSTATE -ge $BS_BUILD_SDL ]; then
+        return 0
+    fi
 
-	return 0
+    prepare_sdl || failure
+
+    echo "Building SDL (this may take a while)..." | tee -a $LOGFILE
+    cd $ROOT/3rdparty/sdl || failure
+    chmod +x autogen.sh >> $LOGFILE 2>&1 || failure
+    ./autogen.sh >> $LOGFILE 2>&1 || failure
+    chmod +x configure >> $LOGFILE 2>&1 || failure
+    cd $ROOT/build/sdl || failure
+    if [ "$1" == "$TARGET_MAC_INTEL" -o "$1" == "$TARGET_MAC_PPC" ]; then
+        $ROOT/3rdparty/sdl/configure --prefix=$ROOT/install --enable-shared=no --enable-static=yes --enable-screensaver=yes --enable-video-x11=no >> $LOGFILE 2>&1 || failure
+    else
+        $ROOT/3rdparty/sdl/configure --prefix=$ROOT/install --enable-shared=no --enable-static=yes --enable-screensaver=yes >> $LOGFILE 2>&1 || failure 
+    fi
+    make >> $LOGFILE 2>&1 || failure
+    make install >> $LOGFILE 2>&1 || failure
+    echo "Successfully built and installed SDL!" | tee -a $LOGFILE
+
+    store_build_state $BS_BUILD_SDL || failure
+    return 0
+}
+
+
+build_freetype()
+{
+    if [ $BUILDSTATE -ge $BS_BUILD_FREETYPE ]; then
+        return 0
+    fi
+
+    prepare_freetype || failure
+
+    echo "Building Freetype2 (this may take a while)..." | tee -a $LOGFILE
+    cd $ROOT/3rdparty/freetype2 || failure
+    chmod +x autogen.sh >> $LOGFILE 2>&1 || failure
+    ./autogen.sh >> $LOGFILE 2>&1 || failure
+    chmod +x configure >> $LOGFILE 2>&1 || failure
+    cd $ROOT/build/freetype2 || failure
+    # note: freetype (or sdl?) probably doesn't need *no* configure when static -> ansi build, see readme!
+    $ROOT/3rdparty/freetype2/configure --prefix=$ROOT/install --enable-shared=no --enable-static=yes >> $LOGFILE 2>&1 || failure
+    make >> $LOGFILE 2>&1 || failure
+    make install >> $LOGFILE 2>&1 || failure
+    echo "Successfully built and installed Freetype2!" | tee -a $LOGFILE
+
+    store_build_state $BS_BUILD_FREETYPE || failure
+    return 0
+}
+
+
+build_libxml()
+{
+    if [ $BUILDSTATE -ge $BS_BUILD_LIBXML ]; then
+        return 0
+    fi
+
+    prepare_libxml || failure
+
+    echo "Building libxml2 (this may take a while)..." | tee -a $LOGFILE
+    cd $ROOT/3rdparty/libxml2 || failure
+    chmod +x configure >> $LOGFILE 2>&1 || failure
+    cd $ROOT/build/libxml2 || failure
+    $ROOT/3rdparty/libxml2/configure --prefix=$ROOT/install --enable-shared=no --enable-static=yes >> $LOGFILE 2>&1 || failure
+    make >> $LOGFILE 2>&1 || failure
+    make install >> $LOGFILE 2>&1 || failure
+    echo "Successfully built and installed libxml2!" | tee -a $LOGFILE
+
+    store_build_state $BS_BUILD_LIBXML || failure
+    return 0
+}
+
+
+build_oglft()
+{
+    if [ $BUILDSTATE -ge $BS_BUILD_OGLFT ]; then
+        return 0
+    fi
+
+    prepare_oglft || failure
+
+    echo "Patching OGLFT..." | tee -a $LOGFILE
+    cd $ROOT/3rdparty/oglft || failure
+    # note: svn has no force/overwrite switch. patched files might not be updated
+    # patch: use fixed settings for freetype, deactivate FindFreetype
+    FREETYPE2_INCLUDE_DIR="$ROOT/install/include"
+    FREETYPE2_LIBRARIES="$ROOT/install/lib/libfreetype.a"
+    patch CMakeLists.txt < $ROOT/patches/CMakeLists.txt.oglft.patch >> $LOGFILE 2>&1 || failure
+    echo "Building OGLFT..." | tee -a $LOGFILE
+    cd $ROOT/build/oglft || failure
+    # TODO: do we wanna create universal binaries on mac? If so, add -DCMAKE_OSX_ARCHITECTURES=ppc;i386
+    cmake -DFREETYPE2_INCLUDE_DIR="$FREETYPE2_INCLUDE_DIR" -DFREETYPE2_LIBRARIES="$FREETYPE2_LIBRARIES" $ROOT/3rdparty/oglft >> $LOGFILE 2>&1 || failure
+    make >> $LOGFILE 2>&1 || failure
+    mkdir -p $ROOT/install/include/oglft >> $LOGFILE 2>&1 || failure
+    cp OGLFT.h $ROOT/install/include/oglft >> $LOGFILE 2>&1 || failure
+    cp liboglft/liboglft.a $ROOT/install/lib >> $LOGFILE 2>&1 || failure
+    echo "Successfully built and installed OGLFT!" | tee -a $LOGFILE
+
+    store_build_state $BS_BUILD_OGLFT || failure
+    return 0
+}
+
+
+build_boinc()
+{
+    if [ $BUILDSTATE -ge $BS_BUILD_BOINC ]; then
+        return 0
+    fi
+
+    prepare_boinc || failure
+
+    echo "Configuring BOINC..." | tee -a $LOGFILE
+    cd $ROOT/3rdparty/boinc || failure
+    chmod +x _autosetup >> $LOGFILE 2>&1 || failure
+    ./_autosetup >> $LOGFILE 2>&1 || failure
+    chmod +x configure >> $LOGFILE 2>&1 || failure
+    cd $ROOT/build/boinc || failure
+    if [ "$1" == "$TARGET_MAC_INTEL" -o "$1" == "$TARGET_MAC_PPC" ]; then
+        export CPPFLAGS=-I/sw/include
+        $ROOT/3rdparty/boinc/configure --prefix=$ROOT/install --enable-shared=no --enable-static=yes --disable-server --disable-client --with-apple-opengl-framework --enable-install-headers --enable-libraries --disable-manager --disable-fcgi >> $LOGFILE 2>&1 || failure
+    elif [ -d "/usr/local/ssl" ]; then
+        echo "Using local SSL library..." | tee -a $LOGFILE
+        $ROOT/3rdparty/boinc/configure --prefix=$ROOT/install --enable-shared=no --enable-static=yes --disable-server --disable-client --enable-install-headers --enable-libraries --disable-manager --disable-fcgi CPPFLAGS=-I/usr/local/ssl/include LDFLAGS=-L/usr/local/ssl/lib >> $LOGFILE 2>&1 || failure
+    else
+        $ROOT/3rdparty/boinc/configure --prefix=$ROOT/install --enable-shared=no --enable-static=yes --disable-server --disable-client --enable-install-headers --enable-libraries --disable-manager --disable-fcgi >> $LOGFILE 2>&1 || failure
+    fi
+    echo "Building BOINC (this may take a while)..." | tee -a $LOGFILE
+    make >> $LOGFILE 2>&1 || failure
+    make install >> $LOGFILE 2>&1 || failure
+    echo "Successfully built and installed BOINC!" | tee -a $LOGFILE
+
+    store_build_state $BS_BUILD_BOINC || failure
+    return 0
 }
 
 
 build_mingw()
 {
-	TARGET_HOST=i586-pc-mingw32
+    if [ $BUILDSTATE -ge $BS_BUILD_MINGW ]; then
+        return 0
+    fi
+    TARGET_HOST=i586-pc-mingw32
 
-	echo "Building MinGW (this will take quite a while)..." | tee -a $LOGFILE
-	# note: the script's current config for unattended setup expects it to be run from three levels below root!
-	cd $ROOT/3rdparty/mingw/xscripts || failure
-	./x86-mingw32-build.sh --unattended $TARGET_HOST >> $LOGFILE 2>&1 || failure
+    echo "Building MinGW (this will take quite a while)..." | tee -a $LOGFILE
+    # note: the script's current config for unattended setup expects it to be run from three levels below root!
+    cd $ROOT/3rdparty/mingw/xscripts || failure
+    ./x86-mingw32-build.sh --unattended $TARGET_HOST >> $LOGFILE 2>&1 || failure
 
-	return 0
+    store_build_state $BS_BUILD_MINGW
+    return 0
 }
 
 
-prepare_win32_environment()
+set_mingw()
 {
-	echo "Preparing MinGW cross-compile environment..." | tee -a $LOGFILE
-	PREFIX=$ROOT/install
-	TARGET_HOST=i586-pc-mingw32
-	BUILD_HOST=i386-linux
-	PATH_MINGW="$PREFIX/bin:$PREFIX/$TARGET_HOST/bin:$PATH"
-	PATH="$PATH_MINGW"
-	export PATH
+    # general config
+    PREFIX=$ROOT/install
+    TARGET_HOST=i586-pc-mingw32
+    BUILD_HOST=i386-linux
+    PATH_MINGW="$PREFIX/bin:$PREFIX/$TARGET_HOST/bin:$PATH"
+    PATH="$PATH_MINGW"
+    export PATH
 }
 
 
-build_generic_win32()
+build_sdl_mingw()
 {
-	echo "Patching SDL..." | tee -a $LOGFILE
-	cd $ROOT/3rdparty/sdl/src/video/wincommon || failure
-	# patch: amend window class name (required by BOINC v6 screensaver!)
-	patch < $ROOT/patches/SDL_sysevents.c.patch >> $LOGFILE 2>&1 || failure
-	echo "Building SDL (this may take a while)..." | tee -a $LOGFILE
-	cd $ROOT/3rdparty/sdl || failure
-	chmod +x autogen.sh >> $LOGFILE 2>&1 || failure
-	./autogen.sh >> $LOGFILE 2>&1 || failure
-	chmod +x configure >> $LOGFILE 2>&1 || failure
-	if [ -f "$PREFIX/$TARGET_HOST/bin/$TARGET_HOST-sdl-config" ]; then
-		SDL_CONFIG="$PREFIX/$TARGET_HOST/bin/$TARGET_HOST-sdl-config"
-		export SDL_CONFIG
-		echo "Cross-compile SDL_CONFIG: $SDL_CONFIG" >> $LOGFILE
-	fi
-	cd $ROOT/build/sdl || failure
-	$ROOT/3rdparty/sdl/configure --host=$TARGET_HOST --build=$BUILD_HOST --prefix=$PREFIX --enable-shared=no --enable-static=yes --enable-screensaver=yes >> $LOGFILE 2>&1 || failure
-	make >> $LOGFILE 2>&1 || failure
-	make install >> $LOGFILE 2>&1 || failure
-	echo "Successfully built and installed SDL!" | tee -a $LOGFILE
-
-	echo "Patching Freetype2..." | tee -a $LOGFILE
-	cd $ROOT/3rdparty/freetype2/builds || failure
-	# patch: deactivating invocation of apinames (would run win32 binary on linux host)
-	patch < $ROOT/patches/freetype2.exports.mk.patch >> $LOGFILE 2>&1 || failure
-	echo "Building Freetype2 (this may take a while)..." | tee -a $LOGFILE
-	cd $ROOT/3rdparty/freetype2 || failure
-	chmod +x autogen.sh >> $LOGFILE 2>&1 || failure
-	./autogen.sh >> $LOGFILE 2>&1 || failure
-	chmod +x configure >> $LOGFILE 2>&1 || failure
-	if [ -f "$PREFIX/$TARGET_HOST/bin/$TARGET_HOST-freetype-config" ]; then
-		FT_CONFIG="$PREFIX/$TARGET_HOST/bin/$TARGET_HOST-freetype-config"
-		export FT_CONFIG
-		echo "Cross-compile FT_CONFIG: $FT_CONFIG" >> $LOGFILE
-	fi
-	cd $ROOT/build/freetype2 || failure
-	# note: freetype (or sdl?) probably doesn't need *no* configure when static -> ansi build, see readme!
-	$ROOT/3rdparty/freetype2/configure --host=$TARGET_HOST --build=$BUILD_HOST --prefix=$PREFIX --enable-shared=no --enable-static=yes >> $LOGFILE 2>&1 || failure
-	make >> $LOGFILE 2>&1 || failure
-	make install >> $LOGFILE 2>&1 || failure
-	echo "Successfully built and installed Freetype2!" | tee -a $LOGFILE
-
-	echo "Building libxml2 (this may take a while)..." | tee -a $LOGFILE
-	cd $ROOT/3rdparty/libxml2 || failure
-	chmod +x configure >> $LOGFILE 2>&1 || failure
-	if [ -f "$PREFIX/$TARGET_HOST/bin/$TARGET_HOST-xml2-config" ]; then
-		LIBXML2_CONFIG="$PREFIX/$TARGET_HOST/bin/$TARGET_HOST-xml2-config"
-		export LIBXML2_CONFIG
-		echo "Cross-compile LIBXML2_CONFIG: $LIBXML2_CONFIG" >> $LOGFILE
-	fi
-	cd $ROOT/build/libxml2 || failure
-	$ROOT/3rdparty/libxml2/configure --host=$TARGET_HOST --build=$BUILD_HOST --prefix=$PREFIX --enable-shared=no --enable-static=yes >> $LOGFILE 2>&1 || failure
-	make >> $LOGFILE 2>&1 || failure
-	make install >> $LOGFILE 2>&1 || failure
-	echo "Successfully built and installed libxml2!" | tee -a $LOGFILE
-
-	echo "Patching OGLFT..." | tee -a $LOGFILE
-	cd $ROOT/3rdparty/oglft || failure
-	# note: svn has no force/overwrite switch. patched files might not be updated
-	# patch: use fixed settings for freetype, deactivate FindFreetype
-	FREETYPE2_INCLUDE_DIR="$ROOT/install/include"
-	FREETYPE2_LIBRARIES="$ROOT/install/lib/libfreetype.a"
-	patch CMakeLists.txt < $ROOT/patches/CMakeLists.txt.oglft.patch >> $LOGFILE 2>&1 || failure
-	cp $ROOT/patches/toolchain-linux-mingw.oglft.cmake $ROOT/build/oglft >> $LOGFILE 2>&1 || failure
-	export OGLFT_INSTALL=$ROOT/install
-	echo "Building OGLFT..." | tee -a $LOGFILE
-	cd $ROOT/build/oglft || failure
-	cmake -DCMAKE_TOOLCHAIN_FILE="toolchain-linux-mingw.oglft.cmake" -DFREETYPE2_INCLUDE_DIR="$FREETYPE2_INCLUDE_DIR" -DFREETYPE2_LIBRARIES="$FREETYPE2_LIBRARIES" $ROOT/3rdparty/oglft >> $LOGFILE 2>&1 || failure
-	make >> $LOGFILE 2>&1 || failure
-	mkdir -p $ROOT/install/include/oglft >> $LOGFILE 2>&1 || failure
-	cp OGLFT.h $ROOT/install/include/oglft >> $LOGFILE 2>&1 || failure
-	cp liboglft/liboglft.a $ROOT/install/lib >> $LOGFILE 2>&1 || failure
-	echo "Successfully built and installed OGLFT!" | tee -a $LOGFILE
-
-	echo "Patching BOINC..." | tee -a $LOGFILE
-	cd $ROOT/3rdparty/boinc/lib || failure
-	# patch: fix a couple of BOINC vs. MinGW issues
-	patch boinc_win.h < $ROOT/patches/boinc.boinc_win.h.minggw.patch >> $LOGFILE 2>&1 || failure
-	patch filesys.cpp < $ROOT/patches/boinc.filesys.cpp.mingw.patch >> $LOGFILE 2>&1 || failure
-	echo "Building BOINC (this may take a while)..." | tee -a $LOGFILE
-	cd $ROOT/3rdparty/boinc || failure
-	chmod +x _autosetup >> $LOGFILE 2>&1 || failure
-	./_autosetup >> $LOGFILE 2>&1 || failure
-	chmod +x configure >> $LOGFILE 2>&1 || failure
-	cd $ROOT/build/boinc || failure
-	# note: configure is still required but we don't use the generated Makefile
-	$ROOT/3rdparty/boinc/configure --host=$TARGET_HOST --build=$BUILD_HOST --prefix=$ROOT/install --includedir=$ROOT/install/include --oldincludedir=$ROOT/install/include --enable-shared=no --enable-static=yes --disable-server --disable-client --enable-install-headers --enable-libraries --disable-manager --disable-fcgi >> $LOGFILE 2>&1 || failure
-	cd $ROOT/build/boinc/api || failure
-	cp $ROOT/3rdparty/boinc/api/Makefile.mingw . >> $LOGFILE 2>&1 || failure
-	# patch: add graphics2 and customize build path (see below)
-	patch Makefile.mingw < $ROOT/patches/boinc.Makefile.mingw.patch >> $LOGFILE 2>&1 || failure
-	export BOINC_SRC=$ROOT/3rdparty/boinc || failure
-	cd $ROOT/build/boinc || failure
-	# required for out-of-tree build
-	cp config.h $ROOT/3rdparty/boinc >> $LOGFILE 2>&1 || failure
-	make -f api/Makefile.mingw >> $LOGFILE 2>&1 || failure
-	cp $ROOT/build/boinc/libboinc.a $ROOT/install/lib >> $LOGFILE 2>&1 || failure
-	mkdir -p $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
-	cp $ROOT/build/boinc/config.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
-	cp $ROOT/build/boinc/version.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
-	cp $ROOT/3rdparty/boinc/api/boinc_api.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
-	cp $ROOT/3rdparty/boinc/api/graphics2.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
-	cp $ROOT/3rdparty/boinc/lib/app_ipc.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
-	cp $ROOT/3rdparty/boinc/lib/boinc_win.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
-	cp $ROOT/3rdparty/boinc/lib/common_defs.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
-	cp $ROOT/3rdparty/boinc/lib/diagnostics.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
-	cp $ROOT/3rdparty/boinc/lib/diagnostics_win.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
-	cp $ROOT/3rdparty/boinc/lib/filesys.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
-	cp $ROOT/3rdparty/boinc/lib/hostinfo.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
-	cp $ROOT/3rdparty/boinc/lib/proxy_info.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
-	cp $ROOT/3rdparty/boinc/lib/prefs.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
-	cp $ROOT/3rdparty/boinc/lib/miofile.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
-	cp $ROOT/3rdparty/boinc/lib/mfile.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
-	cp $ROOT/3rdparty/boinc/lib/parse.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
-	cp $ROOT/3rdparty/boinc/lib/util.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
-	echo "Successfully built and installed BOINC!" | tee -a $LOGFILE
+    if [ $BUILDSTATE -ge $BS_BUILD_SDL_MINGW ]; then
+        return 0
+    fi
+
+    prepare_sdl || failure
+
+    echo "Patching SDL..." | tee -a $LOGFILE
+    cd $ROOT/3rdparty/sdl/src/video/wincommon || failure
+    # patch: amend window class name (required by BOINC v6 screensaver!)
+    patch < $ROOT/patches/SDL_sysevents.c.patch >> $LOGFILE 2>&1 || failure
+    echo "Building SDL (this may take a while)..." | tee -a $LOGFILE
+    cd $ROOT/3rdparty/sdl || failure
+    chmod +x autogen.sh >> $LOGFILE 2>&1 || failure
+    ./autogen.sh >> $LOGFILE 2>&1 || failure
+    chmod +x configure >> $LOGFILE 2>&1 || failure
+    if [ -f "$PREFIX/$TARGET_HOST/bin/$TARGET_HOST-sdl-config" ]; then
+        SDL_CONFIG="$PREFIX/$TARGET_HOST/bin/$TARGET_HOST-sdl-config"
+        export SDL_CONFIG
+        echo "Cross-compile SDL_CONFIG: $SDL_CONFIG" >> $LOGFILE
+    fi
+    cd $ROOT/build/sdl || failure
+    $ROOT/3rdparty/sdl/configure --host=$TARGET_HOST --build=$BUILD_HOST --prefix=$PREFIX --enable-shared=no --enable-static=yes --enable-screensaver=yes >> $LOGFILE 2>&1 || failure
+    make >> $LOGFILE 2>&1 || failure
+    make install >> $LOGFILE 2>&1 || failure
+    echo "Successfully built and installed SDL!" | tee -a $LOGFILE
+
+    store_build_state $BS_BUILD_SDL_MINGW || failure
+    return 0
+}
+
+
+build_freetype_mingw()
+{
+    if [ $BUILDSTATE -ge $BS_BUILD_FREETYPE_MINGW ]; then
+        return 0
+    fi
+
+    prepare_freetype || failure
+
+    echo "Patching Freetype2..." | tee -a $LOGFILE
+    cd $ROOT/3rdparty/freetype2/builds || failure
+    # patch: deactivating invocation of apinames (would run win32 binary on linux host)
+    patch < $ROOT/patches/freetype2.exports.mk.patch >> $LOGFILE 2>&1 || failure
+    echo "Building Freetype2 (this may take a while)..." | tee -a $LOGFILE
+    cd $ROOT/3rdparty/freetype2 || failure
+    chmod +x autogen.sh >> $LOGFILE 2>&1 || failure
+    ./autogen.sh >> $LOGFILE 2>&1 || failure
+    chmod +x configure >> $LOGFILE 2>&1 || failure
+    if [ -f "$PREFIX/$TARGET_HOST/bin/$TARGET_HOST-freetype-config" ]; then
+        FT_CONFIG="$PREFIX/$TARGET_HOST/bin/$TARGET_HOST-freetype-config"
+        export FT_CONFIG
+        echo "Cross-compile FT_CONFIG: $FT_CONFIG" >> $LOGFILE
+    fi
+    cd $ROOT/build/freetype2 || failure
+    # note: freetype (or sdl?) probably doesn't need *no* configure when static -> ansi build, see readme!
+    $ROOT/3rdparty/freetype2/configure --host=$TARGET_HOST --build=$BUILD_HOST --prefix=$PREFIX --enable-shared=no --enable-static=yes >> $LOGFILE 2>&1 || failure
+    make >> $LOGFILE 2>&1 || failure
+    make install >> $LOGFILE 2>&1 || failure
+    echo "Successfully built and installed Freetype2!" | tee -a $LOGFILE
+
+    store_build_state $BS_BUILD_FREETYPE_MINGW || failure
+    return 0
+}
+
+
+build_libxml_mingw()
+{
+    if [ $BUILDSTATE -ge $BS_BUILD_LIBXML_MINGW ]; then
+        return 0
+    fi
+
+    prepare_libxml || failure
+
+    echo "Building libxml2 (this may take a while)..." | tee -a $LOGFILE
+    cd $ROOT/3rdparty/libxml2 || failure
+    chmod +x configure >> $LOGFILE 2>&1 || failure
+    if [ -f "$PREFIX/$TARGET_HOST/bin/$TARGET_HOST-xml2-config" ]; then
+        LIBXML2_CONFIG="$PREFIX/$TARGET_HOST/bin/$TARGET_HOST-xml2-config"
+        export LIBXML2_CONFIG
+        echo "Cross-compile LIBXML2_CONFIG: $LIBXML2_CONFIG" >> $LOGFILE
+    fi
+    cd $ROOT/build/libxml2 || failure
+    $ROOT/3rdparty/libxml2/configure --host=$TARGET_HOST --build=$BUILD_HOST --prefix=$PREFIX --enable-shared=no --enable-static=yes >> $LOGFILE 2>&1 || failure
+    make >> $LOGFILE 2>&1 || failure
+    make install >> $LOGFILE 2>&1 || failure
+    echo "Successfully built and installed libxml2!" | tee -a $LOGFILE
+
+    store_build_state $BS_BUILD_LIBXML_MINGW || failure
+    return 0
+}
+
+
+build_oglft_mingw()
+{
+    if [ $BUILDSTATE -ge $BS_BUILD_OGLFT_MINGW ]; then
+        return 0
+    fi
+
+    prepare_oglft || failure
+
+    echo "Patching OGLFT..." | tee -a $LOGFILE
+    cd $ROOT/3rdparty/oglft || failure
+    # note: svn has no force/overwrite switch. patched files might not be updated
+    # patch: use fixed settings for freetype, deactivate FindFreetype
+    FREETYPE2_INCLUDE_DIR="$ROOT/install/include"
+    FREETYPE2_LIBRARIES="$ROOT/install/lib/libfreetype.a"
+    patch CMakeLists.txt < $ROOT/patches/CMakeLists.txt.oglft.patch >> $LOGFILE 2>&1 || failure
+    cp $ROOT/patches/toolchain-linux-mingw.oglft.cmake $ROOT/build/oglft >> $LOGFILE 2>&1 || failure
+    export OGLFT_INSTALL=$ROOT/install
+    echo "Building OGLFT..." | tee -a $LOGFILE
+    cd $ROOT/build/oglft || failure
+    cmake -DCMAKE_TOOLCHAIN_FILE="toolchain-linux-mingw.oglft.cmake" -DFREETYPE2_INCLUDE_DIR="$FREETYPE2_INCLUDE_DIR" -DFREETYPE2_LIBRARIES="$FREETYPE2_LIBRARIES" $ROOT/3rdparty/oglft >> $LOGFILE 2>&1 || failure
+    make >> $LOGFILE 2>&1 || failure
+    mkdir -p $ROOT/install/include/oglft >> $LOGFILE 2>&1 || failure
+    cp OGLFT.h $ROOT/install/include/oglft >> $LOGFILE 2>&1 || failure
+    cp liboglft/liboglft.a $ROOT/install/lib >> $LOGFILE 2>&1 || failure
+    echo "Successfully built and installed OGLFT!" | tee -a $LOGFILE
+
+    store_build_state $BS_BUILD_OGLFT_MINGW || failure
+    return 0
+}
+
+build_boinc_win32()
+{
+    if [ $BUILDSTATE -ge $BS_BUILD_BOINC_MINGW ]; then
+        return 0
+    fi
+
+    prepare_boinc || failure
+
+    echo "Patching BOINC..." | tee -a $LOGFILE
+    cd $ROOT/3rdparty/boinc/lib || failure
+    # patch: fix a couple of BOINC vs. MinGW issues
+    patch boinc_win.h < $ROOT/patches/boinc.boinc_win.h.minggw.patch >> $LOGFILE 2>&1 || failure
+    patch filesys.cpp < $ROOT/patches/boinc.filesys.cpp.mingw.patch >> $LOGFILE 2>&1 || failure
+    echo "Building BOINC (this may take a while)..." | tee -a $LOGFILE
+    cd $ROOT/3rdparty/boinc || failure
+    chmod +x _autosetup >> $LOGFILE 2>&1 || failure
+    ./_autosetup >> $LOGFILE 2>&1 || failure
+    chmod +x configure >> $LOGFILE 2>&1 || failure
+    cd $ROOT/build/boinc || failure
+    # note: configure is still required but we don't use the generated Makefile
+    $ROOT/3rdparty/boinc/configure --host=$TARGET_HOST --build=$BUILD_HOST --prefix=$ROOT/install --includedir=$ROOT/install/include --oldincludedir=$ROOT/install/include --enable-shared=no --enable-static=yes --disable-server --disable-client --enable-install-headers --enable-libraries --disable-manager --disable-fcgi >> $LOGFILE 2>&1 || failure
+    cd $ROOT/build/boinc/api || failure
+    cp $ROOT/3rdparty/boinc/api/Makefile.mingw . >> $LOGFILE 2>&1 || failure
+    # patch: add graphics2 and customize build path (see below)
+    patch Makefile.mingw < $ROOT/patches/boinc.Makefile.mingw.patch >> $LOGFILE 2>&1 || failure
+    export BOINC_SRC=$ROOT/3rdparty/boinc || failure
+    cd $ROOT/build/boinc || failure
+    # required for out-of-tree build
+    cp config.h $ROOT/3rdparty/boinc >> $LOGFILE 2>&1 || failure
+    make -f api/Makefile.mingw >> $LOGFILE 2>&1 || failure
+    cp $ROOT/build/boinc/libboinc.a $ROOT/install/lib >> $LOGFILE 2>&1 || failure
+    mkdir -p $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
+    cp $ROOT/build/boinc/config.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
+    cp $ROOT/build/boinc/version.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
+    cp $ROOT/3rdparty/boinc/api/boinc_api.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
+    cp $ROOT/3rdparty/boinc/api/graphics2.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
+    cp $ROOT/3rdparty/boinc/lib/app_ipc.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
+    cp $ROOT/3rdparty/boinc/lib/boinc_win.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
+    cp $ROOT/3rdparty/boinc/lib/common_defs.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
+    cp $ROOT/3rdparty/boinc/lib/diagnostics.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
+    cp $ROOT/3rdparty/boinc/lib/diagnostics_win.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
+    cp $ROOT/3rdparty/boinc/lib/filesys.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
+    cp $ROOT/3rdparty/boinc/lib/hostinfo.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
+    cp $ROOT/3rdparty/boinc/lib/proxy_info.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
+    cp $ROOT/3rdparty/boinc/lib/prefs.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
+    cp $ROOT/3rdparty/boinc/lib/miofile.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
+    cp $ROOT/3rdparty/boinc/lib/mfile.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
+    cp $ROOT/3rdparty/boinc/lib/parse.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
+    cp $ROOT/3rdparty/boinc/lib/util.h $ROOT/install/include/boinc >> $LOGFILE 2>&1 || failure
+    echo "Successfully built and installed BOINC!" | tee -a $LOGFILE
+
+    store_build_state $BS_BUILD_BOINC_MINGW || failure
+    return 0
 }
 
 
 build_starsphere()
 {
-	# make sure ORC is always compiled for host platform (it's exexuted during starsphere build!)
-	export PATH=$PATH_ORG
+    # make sure ORC is always compiled for host platform (it's exexuted during starsphere build!)
+    echo "Preparing Starsphere..." | tee -a $LOGFILE
+    mkdir -p $ROOT/build/orc >> $LOGFILE || failure
+    mkdir -p $ROOT/build/framework >> $LOGFILE || failure
+    mkdir -p $ROOT/build/starsphere >> $LOGFILE || failure
+    export PATH=$PATH_ORG
 
 	echo "Building Starsphere [ORC]..." | tee -a $LOGFILE
 	export ORC_SRC=$ROOT/src/orc || failure
@@ -480,67 +714,47 @@ build_starsphere()
 
 build_linux()
 {
-	echo "Important for an official build: let CC and CXX point to gcc/g++ 4.0.3!"
-	build_generic || failure
-	build_starsphere || failure
-
-	return 0
+    echo "Important for an official build: let CC and CXX point to gcc/g++ 4.0.3!"
+    build_sdl || failure
+    build_freetype || failure
+    build_libxml || failure
+    build_oglft || failure
+    build_boinc || failure
+    build_starsphere $1 $2 || failure
+
+    return 0
 }
 
 
 build_mac()
 {
-	build_generic $1 || failure
-	build_starsphere $1 || failure
-
-	return 0
+    build_sdl $1 || failure
+    build_freetype || failure
+    build_libxml || failure
+    build_oglft || failure
+    build_boinc $1 || failure
+    build_starsphere $1 || failure
+
+    return 0
 }
 
 
 build_win32()
 {
-	prepare_win32 || failure
-	build_mingw || failure
-	prepare_win32_environment || failure
-	build_generic_win32 || failure
-	build_starsphere $TARGET_WIN32 || failure
-
-	return 0
-}
-
-
-distclean()
-{
-	cd $ROOT || failure
-
-	echo "Purging build system..." | tee -a $LOGFILE
-
-	rm -rf 3rdparty || failure
-	rm -rf build || failure
-	rm -rf install || failure
-	rm -rf doc/html || failure
-	rm -f doc/*.tag || failure
-
-	rm -f .lastbuild || failure
-}
-
-
-check_last_build()
-{
-	echo "Checking previous build target..." | tee -a $LOGFILE
-
-	LASTBUILD=`cat .lastbuild 2>/dev/null`
-
-	if [[ ( -f .lastbuild ) && ( "$LASTBUILD" != "$1" ) ]]; then
-		cd $ROOT || failure
-		echo "Build target changed! Purging build and install trees..." | tee -a $LOGFILE
-		rm -rf build >> $LOGFILE || failure
-		rm -rf install >> $LOGFILE || failure
-	fi
-
-	echo "$1" > .lastbuild || failure
-
-	return 0
+    export CFLAGS="-mms-bitfields $CFLAGS"
+    export CXXFLAGS="-mms-bitfields $CXXFLAGS"
+
+    prepare_mingw || failure
+    build_mingw || failure
+    set_mingw || failure
+    build_sdl_mingw || failure
+    build_freetype_mingw || failure
+    build_libxml_mingw || failure
+    build_oglft_mingw || failure
+    build_boinc_mingw || failur
+    build_starsphere $TARGET_WIN32 || failure
+
+    return 0
 }
 
 
@@ -567,12 +781,6 @@ print_usage()
 
 ### main control ##########################################################
 
-TARGET_LINUX=1
-TARGET_MAC_INTEL=2
-TARGET_MAC_PPC=4
-TARGET_WIN32=8
-TARGET_DOC=16
-
 echo "************************************" | tee -a $LOGFILE
 echo "Starting new build!" | tee -a $LOGFILE
 echo "`date`" | tee -a $LOGFILE
@@ -590,21 +798,25 @@ case "$1" in
 		TARGET=$TARGET_LINUX
 		check_last_build "$1" || failure
 		echo "Building linux version:" | tee -a $LOGFILE
+        check_build_state || failure
 		;;
 	"--mac-intel")
 		TARGET=$TARGET_MAC_INTEL
 		check_last_build "$1" || failure
 		echo "Building mac (Intel) version:" | tee -a $LOGFILE
+        check_build_state || failure
 		;;
 	"--mac-ppc")
 		TARGET=$TARGET_MAC_PPC
 		check_last_build "$1" || failure
 		echo "Building mac (PPC) version:" | tee -a $LOGFILE
+        check_build_state || failure
 		;;
 	"--win32")
 		TARGET=$TARGET_WIN32
 		check_last_build "$1" || failure
 		echo "Building win32 version:" | tee -a $LOGFILE
+        check_build_state || failure
 		;;
 	"--doc")
 		TARGET=$TARGET_DOC
@@ -631,7 +843,7 @@ esac
 case $TARGET in
 	$TARGET_LINUX)
 		check_prerequisites || failure
-		prepare_generic || failure
+		prepare_tree || failure
 		build_linux || failure
 		;;
 	$TARGET_MAC_INTEL)
@@ -649,19 +861,19 @@ case $TARGET in
 			failure
 		fi
 		check_prerequisites || failure
-		prepare_generic || failure
+		prepare_tree || failure
 		build_mac $TARGET_MAC_INTEL || failure
 		;;
 	$TARGET_MAC_PPC)
 		export CFLAGS=-mcpu=G3 || failure
 		export CXXFLAGS=-mcpu=G3 || failure
 		check_prerequisites || failure
-		prepare_generic || failure
+		prepare_tree || failure
 		build_mac $TARGET_MAC_PPC || failure
 		;;
 	$TARGET_WIN32)
 		check_prerequisites || failure
-		prepare_generic || failure
+		prepare_tree || failure
 		build_win32 || failure
 		;;
 	$TARGET_DOC)