#!/bin/bash

# cmake-SL v1.63 (c)2008-2012 Henri Beauchamp. Released under GPL license v2:
# http://www.gnu.org/licenses/gpl.txt

###############################################################################
######## THIS IS QUICK'N DIRTY ALPHA SOFTWARE. USE AT YOUR OWN RISKS ! ########
###############################################################################

###############################################################################
# BEWARE: this script is meant to compile a -personal- SL client. It is -NOT- #
#         suitable to build client versions meant for public release, because #
#         non-open source code is packaged by this script.                    #
###############################################################################

# This bash script is aimed at easying up the build process of a SL client
# with cmake.
# You may enable or disable the use of your system's library by editing
# the USE_SYSTEM_* variable ("yes" --> use the system library, "no" --> use
# LL's provided ones).
# The script also takes care of updating properly the viewer_manifest.py script
# accordingly, so that you (should) end up with a properly packaged client.

# To use this script, simply make it executable (chmod +x cmake-SL) and
# put it into /usr/local/bin (or any other directory in your PATH).
# Then, download the slviewer-src-*.tar.gz, slviewer-linux-libs-*.tar.gz,
# slviewer-artwork-*.zip and fmodapi*.tar.gz archives, and finally, invoke
# make-SL as follow:
#   cmake-SL path_to_archives  (example: make-SL ~/downloads)
# or simply:
#   cmake-SL
# when invoking from the directory where the archives are.
# The sources will be installed into the PATH_TO_SOURCES directory,
# and temporary files stored into the TEMP_DIR directory.
# The packaged build will be moved to your home directory.
#
# If you want to retry a compilation after fixing something manually and
# don't want cmake-SL to start all over again, overwriting everything,
# you may invoke it with the --retry option, like this:
#   cmake-SL --retry
#
# Finally, if you just want to prepare the sources without starting the
# compilation, use:
#   cmake-SL [path_to_archives] --prep
#
# This script has been tested by the author, on (very customized) Mandriva
# 2007.1, 2009.0, 2010.0 and 2010.2 distros.
# Tested with SL v1.21, v1.22 and v1.23 sources.
# Tested with Snowglobe v1.4.0 and v1.5.0 sources.
# Further optimized for the Cool VL Viewer v1.26 sources.

# Where the sources of the client will be held (defaults to "./linden"):
PATH_TO_SOURCES="/usr/src/SL"
# Where to store temporary files:
TEMP_DIR="/usr/tmp/$USER"
# Snowglobe stores installed files locks here:
INSTALL_LOCKS="$PATH_TO_SOURCES/indra/viewer-linux-i686-release/prepare"

USE_SYSTEM_GTK="no"
USE_SYSTEM_SDL="no"
USE_SYSTEM_SSL="no"
# Beware: libdb4 makes use of libapr, libapr makes use of libexpat and
# libxmlrc-epi makes use of libexpat... so you should keep USE_SYSTEM_APR,
# USE_SYSTEM_DB4, USE_SYSTEM_EXPAT and USE_SYSTEM_XMLRPC in sync.
USE_SYSTEM_APR="no"
USE_SYSTEM_EXPAT="no"
USE_SYSTEM_XMLRPC="no"
# Note: you may specify a version number (example: 4.6) instead of "yes"
# in USE_SYSTEM_DB4 (by default the cmake scripts will attempt to link
# against DB4.2 only and would fail when set to "yes" if this is not the
# version installed on your system.
USE_SYSTEM_DB4="no"
# You should keep the USE_SYSTEM_CARES setting in sync with the USE_SYSTEM_CURL
# setting further below...
USE_SYSTEM_CARES="no"
# If your system libcurl does not use c-ares (non-blocking DNS calls), better
# using LL's provided library...
USE_SYSTEM_CURL="no"
USE_SYSTEM_OGG="no"
USE_SYSTEM_ZLIB="no"
USE_SYSTEM_UUID="no"
USE_SYSTEM_VORBIS="no"
USE_SYSTEM_JPEGLIB="no"
USE_SYSTEM_PERFTOOLS="no"
USE_SYSTEM_ELFIO="no"
USE_SYSTEM_OPENGL="no"
# When compiling against anything newer than glibc v2.4, do use "yes" here:
USE_SYSTEM_LIBSTDC="yes"

# You may use TUNE_FLAGS here, to add optimization options to the ones already
# set in linden/indra/cmake/00-Common.cmake.
TUNE_FLAGS=""
# Set this to "yes" to force vectorization use in the viewer code (only for
# processors with SSE or Altivec units, and only if you did enable them via
# the TUNE_FLAGS. NOTE: no more in use in Mesh viewers.
FORCE_VECTORIZE="no"

# When using a newer gcc than the version that LL uses to compile their viewer,
# you might have to set this to "yes"...
ALLOW_WARNINGS="no"

# Do not change manually: auto-detected later.
SNOWGLOBE="no"

########### functions definitions ###########

function check() {
    if [ "$1" != "no" ] ; then
        if [ -f $2 ] ; then
            echo "Using the system $3..."
            return 0
        else
            echo "WARNING: system $3 requested but not available..."
        fi
    fi
    return 1
}

function update_manifest() {
	SEARCHSTRING="path(\""$1
    grep -v $SEARCHSTRING $PATH_TO_SOURCES/indra/newview/viewer_manifest.py >$TEMP_DIR/viewer_manifest.py
    mv -f $TEMP_DIR/viewer_manifest.py $PATH_TO_SOURCES/indra/newview/viewer_manifest.py
    chmod +x $PATH_TO_SOURCES/indra/newview/viewer_manifest.py
}

function compile() {
    cd $PATH_TO_SOURCES/indra
    echo "Compiling the client into $TEMP_DIR..."
    ./develop.py --type=Release build
    if (($? == 0)) ; then
        mv -f $PATH_TO_SOURCES/indra/viewer-linux-i686*/newview/*.tar.bz2 $HOME/
	else
		exit 1
    fi
}

########### end of functions ###########

if [ "$TEMP_DIR" == "" ] ; then
    export TEMP_DIR="/usr/tmp/$USER"
fi
mkdir -p $TEMP_DIR

# Check to see if we simply want to retry a compilation:
if [ "$1" == "--retry" ] ; then
    compile
    exit $?
fi

cd $TEMP_DIR

# Make sure we don't unpack over an old source tree:
if [ -d linden ] ; then
    rm -rf linden/
fi

if [ -d $PATH_TO_SOURCES ] && [ "$PATH_TO_SOURCES" != "" ] && [ "$PATH_TO_SOURCES" != "/" ] && [ "$PATH_TO_SOURCES" != "." ] && [ "$PATH_TO_SOURCES" != ".." ] && [ "$PATH_TO_SOURCES" != "$HOME" ] ; then
    rm -rf $PATH_TO_SOURCES/
fi

# Use the parameter (if any) as the path to the archives:

PATH_TO_ARCHIVES=`pwd`
if [ "$1" != "" ] && [ "$1" != "--prep" ] ; then
    if [ -d $1 ] ; then
        PATH_TO_ARCHIVES=$1
        shift
    fi
fi

# Let's first unpack everything:
if ! [ -f $PATH_TO_ARCHIVES/slviewer-src-*.tar.gz ] ; then
    echo "You need slviewer-src !"
    exit 1
fi
if ! [ -f $PATH_TO_ARCHIVES/slviewer-*-libs-*.tar.gz ] ; then
   echo "You need slviewer-*-libs !"
    exit 1
fi
if ! [ -f $PATH_TO_ARCHIVES/slviewer-artwork-*.zip ] ; then
    echo "You need slviewer-artwork !"
    exit 1
fi
if ! [ -f $PATH_TO_ARCHIVES/fmodapi*.tar.gz ] ; then
    echo "You need fmodapi !"
    exit 1
fi
echo "Extracting the files from the archives..."
tar --no-same-owner -xzf $PATH_TO_ARCHIVES/slviewer-src-*.tar.gz
tar --no-same-owner -xzf $PATH_TO_ARCHIVES/slviewer-*-libs-*.tar.gz
unzip -oq $PATH_TO_ARCHIVES/slviewer-artwork-*.zip
# You may add lib or artwork patches named in the form:
# slviewer-whatever-patch.zip
# Example: slviewer-v11900-statusbar-artwork-patch.zip
ARTWORK_PATCHES=`/bin/ls $PATH_TO_ARCHIVES/slviewer-*-patch.zip`
if [ "$ARTWORK_PATCHES" != "" ] ; then
    for f in $ARTWORK_PATCHES; do
        echo "Extracting lib/artwork patch $f..."
        unzip -oq $f
    done
fi

# Detect whether the sources use the old libraries tree or the new one.
LIBRARIES="lib/release"
LIBRARIES_INCLUDES="include"
INCLUDES="include"
if grep lib_release_client linden/indra/cmake/* &>/dev/null ; then
    LIBRARIES="libraries/i686-linux/lib_release_client"
    LIBRARIES_INCLUDES="libraries/i686-linux/include"
    INCLUDES="libraries/include"
    echo "Using the old library tree system."
else
    echo "Using the new library tree system."
fi
mkdir -p linden/$INCLUDES
mkdir -p linden/$LIBRARIES_INCLUDES
mkdir -p linden/$LIBRARIES

# fmodapi:
echo "Copying fmodapi files..."
tar --no-same-owner -xzf $PATH_TO_ARCHIVES/fmodapi*.tar.gz
cp -a fmodapi*/api/inc/* linden/$INCLUDES/
cp -a fmodapi*/api/libfmod-*.so linden/$LIBRARIES/
rm -rf fmodapi*/

# Move the sources to where we want to hold them:
if [ "$PATH_TO_SOURCES" != "linden" ] && [ "$PATH_TO_SOURCES" != "" ] ; then
    echo "Moving the sources to $PATH_TO_SOURCES..."
    mv -f linden $PATH_TO_SOURCES
fi

# Let's own the files:
chown -R $USER: $PATH_TO_SOURCES/

# Check for patches to apply. The names of the patches must be in the form
# slviewer-*.patch* (Example: slviewer-v117-EmbbededNotecard.patch.bz2).
# They must be applicable from inside the source directory with the -p1
# option, i.e. they have been built from outside the source directory
# with a diff command such as:
# diff -urN linden/ linden-patched/ >slviewer-whatever.patch
# And they may be gzipped or bzipped.
PATCHES=`/bin/ls $PATH_TO_ARCHIVES/slviewer-*.patch* 2>/dev/null`
if [ "$PATCHES" != "" ] ; then
    echo "Applying patches..."
    cd $PATH_TO_SOURCES
    for i in $PATCHES; do
        echo "Patch: $i"
        if echo $i | grep ".gz" &>/dev/null ; then
            gunzip -c $i | patch -p1 -s
        elif echo $i | grep ".bz2" &>/dev/null ; then
            bzcat $i | patch -p1 -s
        else
            patch -p1 -s <$i
        fi
    done
    find . -name "*.orig" | xargs rm -f
fi

cd $PATH_TO_SOURCES/indra

# Detect Snowglobe:
if grep "Snowglobe" newview/viewer_manifest.py &>/dev/null ; then
	SNOWGLOBE="yes"
	echo "Snowglobe build system detected."
	mkdir -p $INSTALL_LOCKS
fi

# Do a clean build
./develop.py clean

# Force the vectorization use if we chose so.
if [ "$FORCE_VECTORIZE" == "yes" ] ; then
    TUNE_FLAGS="$TUNE_FLAGS -DLL_VECTORIZE=1"
fi
if [ "$ALLOW_WARNINGS" == "yes" ] ; then
    FATAL_WARNINGS="-DGCC_DISABLE_FATAL_WARNINGS:BOOL=TRUE"
else
    FATAL_WARNINGS=""
fi

# Configure the sources and download the LL provided libraries:
if [ "$TUNE_FLAGS" == "" ] ; then
	./develop.py --type=Release  configure "$FATAL_WARNINGS"
else
	./develop.py --type=Release  configure "$FATAL_WARNINGS" \
        -DCMAKE_C_FLAGS:STRING="$TUNE_FLAGS" -DCMAKE_CXX_FLAGS:STRING="$TUNE_FLAGS" \
        -DCMAKE_C_FLAGS_RELEASE:STRING="$TUNE_FLAGS" -DCMAKE_CXX_FLAGS_RELEASE:STRING="$TUNE_FLAGS"
fi

# Let's use the system GTK+ if available:
if check $USE_SYSTEM_GTK /usr/include/atk-1.0/atk/atk.h "GTK+" ; then
    cd $PATH_TO_SOURCES/$LIBRARIES
    rm -f libgtk* libgdk* libglib* libgmodule* libgobject* libgthread* libpango* libatk*
    cd $PATH_TO_SOURCES/$LIBRARIES_INCLUDES
    rm -rf atk-1.0/ gtk-2.0/ glib-2.0/ pango-1.0/
    cp -a /usr/include/atk-1.0 .
    cp -a /usr/include/gtk-2.0 .
    cp -a /usr/lib/gtk-2.0/include/* gtk-2.0/
    cp -a /usr/include/glib-2.0 .
    cp -a /usr/lib/glib-2.0/include/* glib-2.0/
    cp -a /usr/include/pango-1.0 .
    if [ -d /usr/include/cairo ] ; then
        cp -a /usr/include/cairo/* .
    fi
	if [ $SNOWGLOBE == "yes" ] ; then
		echo "Obtained 'gtk-atk-pango-glib'" >$INSTALL_LOCKS/gtk-atk-pango-glib_installed
	fi
fi

# Let's use the system zlib if available:
if check $USE_SYSTEM_ZLIB /usr/include/zlib.h "zlib" ; then
    cd $PATH_TO_SOURCES/$INCLUDES
    rm -rf zlib/
    mkdir -p zlib
    cp -a /usr/include/zlib*.h zlib/
    rm -f $PATH_TO_SOURCES/$LIBRARIES/libz.so*
	if [ $SNOWGLOBE == "yes" ] ; then
		echo "Obtained 'zlib'" >$INSTALL_LOCKS/zlib_installed
	fi
fi

# Let's use the system jpeglib if available:
if check $USE_SYSTEM_JPEGLIB /usr/include/jpeglib.h "jpeglib" ; then
    cd $PATH_TO_SOURCES/$INCLUDES
    rm -rf jpeglib/
    mkdir -p jpeglib
    cp -a /usr/include/j*.h jpeglib/
    touch jpeglib/jinclude.h
    rm -f $PATH_TO_SOURCES/$LIBRARIES/libjpeg.a
	if [ $SNOWGLOBE == "yes" ] ; then
		echo "Obtained 'jpeglib'" >$INSTALL_LOCKS/jpeglib_installed
	fi
fi

# Let's use the system ogg if available:
if check $USE_SYSTEM_OGG /usr/include/ogg/ogg.h "ogg" ; then
    rm -rf $PATH_TO_SOURCES/$INCLUDES/ogg/
    rm -f $PATH_TO_SOURCES/$LIBRARIES/libogg*
	if [ $SNOWGLOBE == "yes" ] ; then
		echo "Obtained 'ogg-vorbis'" >$INSTALL_LOCKS/ogg-vorbis_installed
	fi
fi

# Let's use the system vorbis if available:
if check $USE_SYSTEM_VORBIS /usr/include/vorbis/vorbisenc.h "vorbis" ; then
    rm -rf $PATH_TO_SOURCES/$INCLUDES/vorbis/
    rm -f $PATH_TO_SOURCES/$LIBRARIES/libvorbis*
	if [ $SNOWGLOBE == "yes" ] ; then
		echo "Obtained 'ogg-vorbis'" >$INSTALL_LOCKS/ogg-vorbis_installed
	fi
fi

if [ -f $INSTALL_LOCKS/ogg-vorbis_installed ] ; then
    if [ "$USE_SYSTEM_OGG" != "yes" ] || [ "$USE_SYSTEM_VORBIS" != "yes" ] ; then
		echo "WARNING: system OGG and VORBIS libraries should be used together !"
	fi
fi

# Let's use the system SDL if available:
if check $USE_SYSTEM_SDL /usr/include/SDL/SDL.h "SDL" ; then
    rm -rf $PATH_TO_SOURCES/$LIBRARIES_INCLUDES/SDL/
	rm -f $PATH_TO_SOURCES/$LIBRARIES/libSDL*
    update_manifest libSDL
	if [ $SNOWGLOBE == "yes" ] ; then
		echo "Obtained 'SDL'" >$INSTALL_LOCKS/SDL_installed
	fi
fi

# Let's use the system openssl if available:
if check $USE_SYSTEM_SSL /usr/include/openssl/opensslconf.h "openssl" ; then
    rm -rf $PATH_TO_SOURCES/$LIBRARIES_INCLUDES/openssl/
    cd $PATH_TO_SOURCES/$LIBRARIES
    rm -f libssl.* libcrypto.*
    update_manifest libssl
    update_manifest libcrypto
	if [ $SNOWGLOBE == "yes" ] ; then
		echo "Obtained 'openSSL'" >$INSTALL_LOCKS/openSSL_installed
	fi
fi

# Let's use the system apr if available:
if check $USE_SYSTEM_APR /usr/include/apr*/apr_base64.h "apr" ; then
    cd $PATH_TO_SOURCES/$LIBRARIES_INCLUDES
    rm -rf apr-1/*
    mkdir -p apr-1
    cp -a /usr/include/apr*/* apr-1/
    rm -f $PATH_TO_SOURCES/$LIBRARIES/libapr*
    update_manifest libapr
	if [ $SNOWGLOBE == "yes" ] ; then
		echo "Obtained 'apr_suite'" >$INSTALL_LOCKS/apr_suite_installed
	fi
fi

# Let's use the system db4 if available:
if check $USE_SYSTEM_DB4 /usr/include/db4/db.h "db4" ; then
    rm -f $PATH_TO_SOURCES/$LIBRARIES/libdb*.so
    update_manifest libdb
    if [ $USE_SYSTEM_DB4 != "yes" ] ; then
        if ! grep $USE_SYSTEM_DB4 $PATH_TO_SOURCES/indra/cmake/BerkeleyDB.cmake ; then
            # If we gave a version number instead of "yes", patch the
            # BerkeleyDB.cmake file to use that DB4 version instead of 4.2 and 5.1.
            sed -e "s/4.2/$USE_SYSTEM_DB4/" $PATH_TO_SOURCES/indra/cmake/BerkeleyDB.cmake >$TEMP_DIR/BerkeleyDB.cmake
            mv -f $TEMP_DIR/BerkeleyDB.cmake $PATH_TO_SOURCES/indra/cmake/BerkeleyDB.cmake
            sed -e "s/5.1/$USE_SYSTEM_DB4/" $PATH_TO_SOURCES/indra/cmake/BerkeleyDB.cmake >$TEMP_DIR/BerkeleyDB.cmake
            mv -f $TEMP_DIR/BerkeleyDB.cmake $PATH_TO_SOURCES/indra/cmake/BerkeleyDB.cmake
        fi
    fi
fi

if [ -f $INSTALL_LOCKS/apr_suite_installed ] && [ "$USE_SYSTEM_DB4" != "yes" ] ; then
	echo "WARNING: system DB4 and APR libraries should be used together !"
fi

# Let's use the system expat if available:
if check $USE_SYSTEM_EXPAT /usr/include/expat.h "expat" ; then
    cd $PATH_TO_SOURCES/$INCLUDES
    rm -rf expat/
    mkdir -p expat
    cp -a /usr/include/expat*.h expat/
    rm -f $PATH_TO_SOURCES/$LIBRARIES/libexpat*
    update_manifest libexpat
	if [ $SNOWGLOBE == "yes" ] ; then
		echo "Obtained 'expat'" >$INSTALL_LOCKS/expat_installed
	fi
fi

# Let's use the system xmlrpc-epi if available:
if [ -d /usr/include/xmlrpc-epi ] ; then
	XMLRPCDIR=/usr/include/xmlrpc-epi
else
	XMLRPCDIR=/usr/include
fi
if check $USE_SYSTEM_XMLRPC $XMLRPCDIR/xmlrpc.h "xmlrpc-epi" ; then
    cd $PATH_TO_SOURCES/$INCLUDES
    rm -rf xmlrpc-epi/
    mkdir -p xmlrpc-epi
	if [ -d /usr/include/xmlrpc-epi ] ; then
    	cp -a $XMLRPCDIR/*.h xmlrpc-epi/
	else
	    cp -a /usr/include/xmlrpc*.h xmlrpc-epi/
	fi
    cd $PATH_TO_SOURCES/$LIBRARIES
    rm -f $PATH_TO_SOURCES/$LIBRARIES/libxmlrpc.a
	if [ $SNOWGLOBE == "yes" ] ; then
		echo "Obtained 'xmlrpc-epi'" >$INSTALL_LOCKS/xmlrpc-epi_installed
	fi
fi

# Let's use the system c-ares if available:
if check $USE_SYSTEM_CARES /usr/lib/libcares.a "c-ares" ; then
    cd $PATH_TO_SOURCES/$INCLUDES
    rm -rf ares/
    mkdir -p ares
    cp -a /usr/include/ares* ares/
    cd $PATH_TO_SOURCES/$LIBRARIES
    rm -f libcares.*
    cp -a /usr/lib/libcares.a .
	if [ $SNOWGLOBE == "yes" ] ; then
		echo "Obtained 'ares'" >$INSTALL_LOCKS/ares_installed
	fi
fi

# Let's use the system curl if available:
if check $USE_SYSTEM_CURL /usr/include/curl/curl.h "curl" ; then
    rm -rf $PATH_TO_SOURCES/$INCLUDES/curl/
    rm -f $PATH_TO_SOURCES/$LIBRARIES/libcurl.*
	if [ $SNOWGLOBE == "yes" ] ; then
		echo "Obtained 'curl'" >$INSTALL_LOCKS/curl_installed
	fi
fi

# Let's use the system uuid if available:
if check $USE_SYSTEM_UUID /usr/include/uuid/uuid.h "libuuid" ; then
    rm -f $PATH_TO_SOURCES/$LIBRARIES/libuuid.*
    update_manifest libuuid
	if [ $SNOWGLOBE == "yes" ] ; then
		echo "Obtained 'libuuid'" >$INSTALL_LOCKS/libuuid_installed
	fi
fi

# Let's use the system google-perftools if available:
if check $USE_SYSTEM_PERFTOOLS /usr/include/google/malloc_hook.h "google-perftools" ; then
	if [ -f /usr/lib/libstacktrace.so ] ; then
        cd $PATH_TO_SOURCES/$LIBRARIES_INCLUDES
    	rm -rf google/
    	cp -a /usr/include/google .
        cd $PATH_TO_SOURCES/$LIBRARIES
	    rm -f libtcmalloc.* libstacktrace.*
 	    cp -a /usr/lib/libstacktrace.* /usr/lib/libtcmalloc.so* .
	    update_manifest libtcmalloc
    	update_manifest libstacktrace
		if [ $SNOWGLOBE == "yes" ] ; then
			echo "Obtained 'google'" >$INSTALL_LOCKS/google_installed
		fi
	else
		echo "WARNING: bad google-perftools version (libstacktrace not available), skipping."
	fi
fi

# Let's use the system libELFIO if available:
if check $USE_SYSTEM_ELFIO /usr/include/ELFIO.h "libELFIO" ; then
    cd $PATH_TO_SOURCES/$LIBRARIES_INCLUDES
    rm -rf ELFIO/
    mkdir -p ELFIO
    cp -af /usr/include/ELF* ELFIO/
    cd $PATH_TO_SOURCES/$LIBRARIES
    rm -f libELFIO.*
    cp -af /usr/lib/libELFIO.so .
    update_manifest libELFIO
	if [ $SNOWGLOBE == "yes" ] ; then
		echo "Obtained 'elfio'" >$INSTALL_LOCKS/elfio_installed
	fi
fi

# Let's use the system OpenGL if available:
if check $USE_SYSTEM_OPENGL /usr/lib/libGLU.so "OpenGL" ; then
    cd $PATH_TO_SOURCES/$LIBRARIES_INCLUDES
    rm -rf GL/
    mkdir -p GL
    cp -af /usr/include/GL/* GL/
    cd $PATH_TO_SOURCES/$LIBRARIES
    rm -f libGLU.*
    cp -af /usr/lib/libGLU.so* .
	if [ $SNOWGLOBE == "yes" ] ; then
		echo "Obtained 'GL'" >$INSTALL_LOCKS/GL_installed
	fi
fi

# Let's use the system libstdc++ if available:
if check $USE_SYSTEM_LIBSTDC /usr/lib/libstdc++.so.6 "libstdc++" ; then
    rm -f $PATH_TO_SOURCES/$LIBRARIES/libstdc++.*
    update_manifest libstdc
fi

# Check to see if we simply want to unpack the sources:
if [ "$1" == "--prep" ] ; then
    echo "Prepared sources available in: $PATH_TO_SOURCES"
    exit 0
fi

compile


syntax highlighted by Code2HTML, v. 0.9.1