#!/bin/sh

# acprep, version 3.0
#
# This script configures my ledger source tree on my Mac OS/X machine.  This
# is not necessary, however, since I keep all the files necessary for building
# checked in to the source tree.  Users can just type './configure && make'.
# This script simply sets up the compiler and linker flags for all the various
# build permutations I use for testing and profiling.

COMMIT=$(git describe --all --long | sed 's/heads\///')
echo "m4_define([VERSION_NUMBER], [$COMMIT])" > version.m4

sh autogen.sh


SWITCHES="--disable-shared"

if [ -z "$PYTHON_HOME" ]; then
    PYTHON_HOME="/usr"
fi
if [ -z "$PYTHON_VERSION" ]; then
    PYTHON_VERSION="2.5"
fi

BOOST_SUFFIX=""

INCDIRS="-isystem /usr/local/include"
INCDIRS="$INCDIRS -isystem /opt/local/include"
INCDIRS="$INCDIRS -isystem /opt/local/include/libofx"
INCDIRS="$INCDIRS -isystem /usr/local/include/boost-1_35"
INCDIRS="$INCDIRS -isystem $PYTHON_HOME/include/python$PYTHON_VERSION"

CXXFLAGS=""
ARCHFLAGS=""
LDARCHFLAGS=""
LDFLAGS=""
LIBDIRS="-L/usr/local/lib -L/opt/local/lib"
LIBDIRS="$LIBDIRS -L$PYTHON_HOME/lib/python$PYTHON_VERSION/config"

SYSTEM=$(uname -s)

if [ $SYSTEM = Linux ]; then
    CXXFLAGS="-pthread"
elif [ $SYSTEM = Solaris ]; then
    CXXFLAGS="-pthreads"
elif [ $SYSTEM = Darwin ]; then
    ARCHFLAGS="-arch i386 -arch ppc -isysroot /Developer/SDKs/MacOSX10.5.sdk"
    LDARCHFLAGS="$ARCHFLAGS -Wl,-syslibroot,/Developer/SDKs/MacOSX10.5.sdk"
fi

# Building the command-line tool as a shared library is a luxury,
# since there are no clients except a GUI tool which might use it (and
# that is built again anyway by Xcode).
CPPFLAGS="$INCDIRS"
CXXFLAGS="$CXXFLAGS -pipe"
LDFLAGS="$LDFLAGS $LIBDIRS"
BUILD_DIR=false

# The following are options to prepare a developer tree of Ledger for
# building:
#
# --debug
#
#   Build with debugging information.  This doesn't slow things down by much,
#   but gives you useful stack traces to mention in your bug reports.
#   Recommended if you're not running a release version.
#
# --dir PATH
#
#   Building the sources in PATH instead of in the source directory.  This
#   breaks pre-compiled headers, but keeps your source tree clean.
#
# --boost SUFFIX
#
#   Use the boost library with the given SUFFIX.  Check the Boost "Getting
#   Started" documentation for what the different suffixes are and what they
#   mean.  Usually you can see the available suffixes on your system using
#   something like this command:
#
#    $ ls /usr/local/lib/libboost_date_time*
#
#   Here's everything that's available on my machine right now:
#
#    ""      - dynamic optimized Boost library
#    d       - dynamic debug
#    s       - static optimized
#    sd      - static debug
#    mt      - multi-threaded optimized
#    mt-d    - multi-threaded debug
#    mt-s    - multi-threaded static optimized
#    mt-sd   - multi-threaded static debug
#
#   Since Ledger does not use threading, I recommend using the static
#   optimized library unless you wish to build with debugging enabled.  If you
#   want to do that, see the --devel switch below.
#
# --devel
#
#   This means you want to build like the developer does, which means:
#
#    * using pre-compiled headers
#    * with glibc debugging enabled
#    * static linking as much as possible
#
#   The glibc debugging is the only tricky part, since you must have Boost
#   compiled with _GLIBCXX_DEBUG defined also -- which it won't be on your
#   system by default.
#  
#   So, you have to roll your own set of Boost debug libraries in order to
#   support this.  I like this because it gives me the most amount of safety
#   and checking possible, which is great for testing.  Here's how I build a
#   super-debugging Boost:
#
#      src $ git clone git://repo.or.cz/boost.git
#      src $ git checkout -b v1.35.0 svn/Version_1_35_0
#      src $ cd boost
#    boost $ sudo bjam release --prefix=/usr/local/stow/boost_1_35_0 \
#                --build-dir=$HOME/Products/boost_1_35_0 --toolset=darwin \
#                architecture=combined install
#    boost $ sudo bjam debug --prefix=/usr/local/stow/boost_1_35_0 \
#                --build-dir=$HOME/Products/boost_1_35_0 --toolset=darwin \
#                architecture=combined define=_GLIBCXX_DEBUG=1 install
#    boost $ cd /usr/local/stow
#     stow $ stow boost_1_35_0
#
#   Of course, you'll need MacPorts to do this, with both the "bjam" and "stow"
#   packages installed.
#
#   Lastly, you need to build cppunit by hand with GLIBCXX_DEBUG also, or else
#   you'll see UniTests crash in flames and none of the unit tests will run.
#  
#   Now you're ready to run acprep like this:
#  
#    $ ./acprep --devel --debug --boost sd
#
#   Or, as I do it:
#
#    $ ./myacprep
#
# --release
#
#   This is the opposite of --devel: it means you wish to build in a release
#   scenario, preparing a universal binary and building against the non-debug
#   versions of Boost and CppUnit.
#
# NOTE: I do not expect anyone but me to use --devel or --release, so don't be
# surprised if it doesn't work as advertised.  In that case, look for me in
# the #ledger channel on the IRC server irc.freenode.net.

DO_BUILD=false

while [ -n "$1" ]; do
  case "$1" in
    --devel)
        # jww (2008-08-07): Sadly, PCH does not work with Boost+gcc4.0 on
	# OS X.  It does work with gcc4.2, but then _GLIBCXX_DEBUG fails.
	#SWITCHES="$SWITCHES --enable-pch"

	# The use of this flag requires that Boost be also build with
	# _GLIBCXX_DEBUG.
	CPPFLAGS="$CPPFLAGS -D_GLIBCXX_DEBUG=1"
	CPPFLAGS="-isystem /usr/local/stow/cppunit-debug/include $CPPFLAGS"
	LDFLAGS="-L/usr/local/stow/cppunit-debug/lib $LDFLAGS"

	BOOST_SUFFIX="-d-1_35"	# I built mine with _GLIBCXX_DEBUG

        # Do the same thing as --debug below
	SWITCHES="$SWITCHES --enable-debug"
	CPPFLAGS="$CPPFLAGS -DBOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING=1"
	CPPFLAGS="$CPPFLAGS -DBOOST_MULTI_INDEX_ENABLE_SAFE_MODE=1"
	CXXFLAGS="$CXXFLAGS -g"
	LDFLAGS="$LDFLAGS -g"

	# Warning flags
	CXXFLAGS="$CXXFLAGS -Wall -ansi -Winvalid-pch"
	CXXFLAGS="$CXXFLAGS -Wextra"
	CXXFLAGS="$CXXFLAGS -Wcast-align"
	CXXFLAGS="$CXXFLAGS -Wcast-qual"
	#CXXFLAGS="$CXXFLAGS -Wconversion"
	CXXFLAGS="$CXXFLAGS -Wfloat-equal"
	CXXFLAGS="$CXXFLAGS -Wmissing-field-initializers"
	CXXFLAGS="$CXXFLAGS -Wno-endif-labels"
	#CXXFLAGS="$CXXFLAGS -Wold-style-cast"
	CXXFLAGS="$CXXFLAGS -Woverloaded-virtual"
	#CXXFLAGS="$CXXFLAGS -Wshorten-64-to-32"
	CXXFLAGS="$CXXFLAGS -Wsign-compare"
	CXXFLAGS="$CXXFLAGS -Wsign-promo"
	CXXFLAGS="$CXXFLAGS -Wstrict-null-sentinel"
	CXXFLAGS="$CXXFLAGS -Wwrite-strings"

	#CXXFLAGS="$CXXFLAGS -Weffc++"
	CXXFLAGS="$CXXFLAGS -Wno-unused"
	CXXFLAGS="$CXXFLAGS -Wno-old-style-cast"
	CXXFLAGS="$CXXFLAGS -Wno-deprecated"

	if [ $SYSTEM = Darwin ]; then
	    CXXFLAGS="$CXXFLAGS -Wno-shorten-64-to-32"
	fi

	#LDFLAGS="-Wl,-read_only_relocs,suppress"
	#LIBS=""
	#if [ -f /opt/local/lib/libexpat.a ]; then
	#    LIBS="$LIBS /opt/local/lib/libexpat.a"
	#fi
	#if [ -f /opt/local/lib/libgmp.a ]; then
	#    LIBS="$LIBS /opt/local/lib/libgmp.a"
	#fi
	#if [ -f /usr/lib/gcc/i686-apple-darwin9/4.2.1/libgcc_static.a ]; then
	#    LIBS="$LIBS /usr/lib/gcc/i686-apple-darwin9/4.2.1/libgcc_static.a"
	#fi

	shift 1 ;;

    --debug)
	SWITCHES="$SWITCHES --enable-debug"
	CPPFLAGS="$CPPFLAGS -DBOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING=1"
	CPPFLAGS="$CPPFLAGS -DBOOST_MULTI_INDEX_ENABLE_SAFE_MODE=1"
	CXXFLAGS="$CXXFLAGS -g"
	LDFLAGS="$LDFLAGS -g"
	shift 1 ;;
      
    --boost)
	shift 1
	BOOST_SUFFIX="-$1"
	shift 1 ;;

    --gcov)
	CXXFLAGS="$CXXFLAGS -fprofile-arcs -ftest-coverage"
	shift 1 ;;

    --gprof)
        CXXFLAGS="$CXXFLAGS -g -pg"
	shift 1 ;;

    --pic)
	CXXFLAGS="$CXXFLAGS -fPIC"
	shift 1 ;;

    --opt)
	CXXFLAGS="$CXXFLAGS -fomit-frame-pointer -O3"
	shift 1 ;;

    --dir)
	shift 1
	BUILD_DIR="$1"
	shift 1 ;;

    --build)
	DO_BUILD=true
	shift 1 ;;

    --local)
	shift 1 ;;

    --release)
	SWITCHES="$SWITCHES --disable-dependency-tracking"
	CPPFLAGS="-isystem /usr/local/stow/cppunit/include $CPPFLAGS"
	#CXXFLAGS="$CXXFLAGS $ARCHFLAGS"
	#LDFLAGS="$LDFLAGS $LDARCHFLAGS"
	LDFLAGS="-L/usr/local/stow/cppunit/lib $LDFLAGS"

	shift 1 ;;

    *)
	break ;;
  esac
done


HERE="$PWD"

if [ ! "$BUILD_DIR" = "false" ]; then
    if [ ! -d "$BUILD_DIR" ]; then
	mkdir -p "$BUILD_DIR"
    fi
    cd "$BUILD_DIR" || (echo "Cannot change to $BUILD_DIR"; exit 1)
fi

SWITCHES="$SWITCHES --with-boost-suffix=$BOOST_SUFFIX"

PATH="$PYTHON_HOME/bin:$PATH" \
    "$HERE/configure" --srcdir="$HERE" \
	CXX="$CXX" CPPFLAGS="$CPPFLAGS" CXXFLAGS="$CXXFLAGS" \
	LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
	$SWITCHES

# Alter the Makefile so that it's not nearly so verbose.  This makes errors
# and warnings much easier to spot.

if [ -f Makefile ]; then
    perl -i -pe 's/^\t(\$\((LIBTOOL|CXX)\).*?\.cc)$/\t\@echo "   " CXX \$\@;$1 > \/dev\/null/;' Makefile
    perl -i -pe 's/^\tmv -f/\t\@mv -f/;' Makefile
    perl -i -pe 's/^\t(\$\((.*?)LINK\).*)/\t\@echo "   " LD \$\@;$1 > \/dev\/null/;' Makefile
fi

# If the --build flag was passed, start a build right away with the right
# options.

echo '#!/bin/bash' > make.sh
MAKE_VARS="ARCHFLAGS=\"$ARCHFLAGS\""
MAKE_VARS="$MAKE_VARS CPPFLAGS=\"$CPPFLAGS\""
MAKE_VARS="$MAKE_VARS LDFLAGS=\"$LDFLAGS\""
MAKE_VARS="$MAKE_VARS CXXFLAGS=\"$CXXFLAGS\""
MAKE_VARS="$MAKE_VARS DISTCHECK_CONFIGURE_FLAGS=\"$SWITCHES\""
echo "make $MAKE_VARS \"\$@\"" >> make.sh
chmod u+x make.sh

if [ $DO_BUILD = true ]; then
    sh -x make.sh "$@"
fi