#! /bin/bash
# This script needs /bin/bash rather than /bin/sh

###############################################################################
# Note that due to ROSE compatibility with libtool 1.5 and 2.0, some warnings #
# may be output from configure.in and aclocal.m4. These messages come from    #
# aclocal, autoheader, autoconf, and automake and can be safely ignored. In   #
# fact, they should be filtered out already by the autoconf-filter.pl script. #
#   --The Rose Project Management.                                            #
###############################################################################

# Directory containing this script, which must be the top of the source tree.
srcdir="${0%/*}"
srcdir="$(cd $srcdir && pwd)"

# Name of a file that would exist in a ROSE source tree but not other projects
# that might be using this same build script.
SOME_ROSE_FILE="scripts/autoconf-filter.pl"

# This is the default location for build to use as a reference
# to its macro definitions used by Autoconf and Automake.
ROSE_DISTRIBUTION=${ROSE_DISTRIBUTION:-.}

# Parse command-line
do_quiet=yes
do_timing=
while [[ "$#" -gt 0 ]]; do
    arg="$1"; shift
    case "$arg" in
        --quiet)
            do_quiet=yes
            ;;
        --verbose)
            do_quiet=
            ;;
        --timing)
            do_timing=yes
            ;;
        --no-timing)
            do_timing=
            ;;
        --srcpath=*)
            ROSE_DISTRIBUTION="${arg#*=}"
            ;;
        --srcpath)
            ROSE_DISTRIBUTION="$1"; shift
            ;;
        *)
            echo "$0: unrecognized argument: $arg" >&2
            exit 1
            ;;
    esac
done

# If there's no autoconf-filter.pl script in this source tree, then we're building in some project external to ROSE, and
# the "--srcpath" must be specified (or obtained from a config file).
if [ ! -e "$srcdir/$SOME_ROSE_FILE" -a "$ROSE_DISTRIBUTION" = "." ]; then
    [ -r $srcdir/config/ROSE_SOURCES ] && ROSE_DISTRIBUTION="$(head -n1 $srcdir/config/ROSE_SOURCES)"
fi
if [ ! -x "$ROSE_DISTRIBUTION/scripts/autoconf-filter.pl" ]; then
    echo "$0: use '--srcpath=DIR' to point to the ROSE source tree" >&2
    exit 1
fi

# Extracts dotted version number from a tool's "--version" message. Assigns result to $VERSION.
get_version () {
    local message=$1
    export VERSION=$(echo $message | head -n1 | perl -pe 's/.*?([0-9\.]+).*/$1/')
}

# Returns ok (0) if $need is at least as large as $have, where both are version numbers
# of the form X.Y.Z where X, Y, and Z are non-negative integers. Returns not-ok (1) otherwise.
version_ok () {
    local have="$1" need="$2"
	
    local have_major=$(echo $have |cut -d. -f1)
    local have_minor=$(echo $have |cut -d. -f2)
    local have_patch=$(echo $have |cut -d. -f3)
    if [[ -z $have_patch ]]; then have_patch=0; fi

    local need_major=$(echo $need |cut -d. -f1)
    local need_minor=$(echo $need |cut -d. -f2)
    local need_patch=$(echo $need |cut -d. -f3)
    if [[ -z $need_patch ]]; then need_patch=0; fi

    OK=0; NOT_OK=1
    if (( have_major > need_major )); then return $OK; fi
    if (( have_major < need_major )); then return $NOT_OK; fi
    if (( have_minor > need_minor )); then return $OK; fi
    if (( have_minor < need_minor )); then return $NOT_OK; fi
    if (( have_patch > need_patch )); then return $OK; fi
    if (( have_patch < need_patch )); then return $NOT_OK; fi
    return $OK
}

# DQ (12/22/2005): remove the autoconf caches
rm -rf autom4te.cache

###############################################################################################################################
# Test libtool version and run libtoolize.  Warn if the libtool version is too old, but run it anyway.  Show the command that
# is run by preceding it with a "+ " on stderr as is the usual debugging style for shell scripts.
###############################################################################################################################

# Look for libtoolize, glibtoolize in various places.
libtoolize_name=
if [[ -x /Users/dquinlan/local/libtool-install/bin/libtoolize ]]; then
    # See README.OSX
    libtoolize_name=/Users/dquinlan/local/libtool-install/bin/libtoolize
elif [[ -n "$(type libtoolize)" ]]; then
    libtoolize_name=$(which libtoolize)
elif [[ -n "$(type glibtoolize)" ]]; then
    libtoolize_name=$(which glibtoolize)
else
    # If the user is running build then libtool should be available.
    echo "$0: neither libtoolize nor glibtoolize were found in the user's path." 2>&1
    exit 1;
fi

# Version required and version actually present.
LIBTOOL_VERSION_PREREQ=1.5.6
get_version "`$libtoolize_name --version`"; LIBTOOL_VERSION=$VERSION
if [[ -z "$LIBTOOL_VERSION" ]]; then
    echo "$0: warning: cannot determine libtool version; skipping libtoolize" 2>&1
elif version_ok "$LIBTOOL_VERSION" "$LIBTOOL_VERSION_PREREQ"; then
    (set -x; $libtoolize_name --force --copy --ltdl --automake)
else
    echo "$0: warning: libtool $LIBTOOL_VERSION is too old (require >= $LIBTOOL_VERSION_PREREQ); skipping libtoolize" 2>&1
fi

###############################################################################################################################
# Test version of automake.  Having the wrong version of automake is a common problem.  We can't test for it in the
# configure.in and we want to catch the problem as early as possible.  So we test for it here. This appears to be the only 
# place to test for the correct version of automake -- autoconf can use the AC_PREREQ macro, but there is no AM_PREREQ macro
# for automake. [DQ 2009-09-26]
###############################################################################################################################

AUTOMAKE_VERSION_REQ=1.9.6
get_version "`automake --version`"; AUTOMAKE_VERSION=$VERSION
if [[ -z "$AUTOMAKE_VERSION" ]]; then
    echo "$0: warning: cannot determine automake version" 2>&1
elif version_ok "$AUTOMAKE_VERSION" "$AUTOMAKE_VERSION_PREREQ"; then
    :
else
    echo "$0: warning: automake $AUTOMAKE_VERSION is too old (require >= $AUTOMAKE_VERSION_PREREQ)" 2>&1
fi

###############################################################################################################################
# Run autoconf tools: aclocal, autoheader, autoconf, and automake
###############################################################################################################################

# Debugging (esp. for NMI machines)
[[ -n "$ACLOCAL_INCLUDES" ]] && echo "ACLOCAL_INCLUDES=$ACLOCAL_INCLUDES"

# Automake will expect these files to always exist even if they are in a conditional.  Since we know
# that they will not be used during the build process itself, we can create zero-length dummy files.
# This list should be the same as in configure.in (search for CLASSPATH_COND_IF)
if [[ ! -e src/frontend/CxxFrontend/EDG/Makefile.am ]]; then
    for file in \
        src/frontend/CxxFrontend/EDG/Makefile.in \
        src/frontend/CxxFrontend/EDG/EDG_3.3/Makefile.in \
        src/frontend/CxxFrontend/EDG/EDG_3.3/misc/Makefile.in \
        src/frontend/CxxFrontend/EDG/EDG_3.3/src/Makefile.in \
        src/frontend/CxxFrontend/EDG/EDG_3.10/Makefile.in \
        src/frontend/CxxFrontend/EDG/EDG_3.10/misc/Makefile.in \
        src/frontend/CxxFrontend/EDG/EDG_3.10/src/Makefile.in \
        src/frontend/CxxFrontend/EDG/EDG_3.10/src/disp/Makefile.in \
        src/frontend/CxxFrontend/EDG/EDG_3.10/lib/Makefile.in \
        src/frontend/CxxFrontend/EDG/EDG_4.0/Makefile.in \
        src/frontend/CxxFrontend/EDG/EDG_4.0/misc/Makefile.in \
        src/frontend/CxxFrontend/EDG/EDG_4.0/src/Makefile.in \
        src/frontend/CxxFrontend/EDG/EDG_4.0/src/disp/Makefile.in \
        src/frontend/CxxFrontend/EDG/EDG_4.0/lib/Makefile.in \
        src/frontend/CxxFrontend/EDG/EDG_SAGE_Connection/Makefile.in \
        src/frontend/CxxFrontend/EDG/edgRose/Makefile.in
    do
        mkdir -p $(dirname $file)
        touch $file
    done
fi

# Run all autoconf, indenting their output for readability.  Exit if a tool fails (this is different than the
# semantics of the original version of this script).  The '-I' switches of aclocal are because some macros may be
# installed in non-standard locations (e.g., libxml's on NMI build machines).
(set -ex
    aclocal -I $ROSE_DISTRIBUTION/config -I $ROSE_DISTRIBUTION/acmacros -I /usr/share/aclocal $ACLOCAL_INCLUDES
    autoheader
    autoconf
    automake -a -c -i
) 2>&1 |$ROSE_DISTRIBUTION/scripts/autoconf-filter.pl |sed '/^[^+]/s/^/    /'
if [[ ${PIPESTATUS[0]} -ne 0 ]]; then
    echo "$0: unable to initialize your build environment!" 2>&1
    exit 1
fi

###############################################################################################################################
# Finishing up details
###############################################################################################################################

# Automake manual says that if we use AM_CONFIG_HEADER we have to build the stamp-h.in files
touch stamp-h.in
touch stamp-h1.in

# Add some dynamically-generated targets that run tests on various sample binaries. [RPM]
if [[ -f tests/roseTests/binaryTests/Makefile.in ]]; then
    (cd $ROSE_DISTRIBUTION && ./scripts/sample_binary_rules.pl) || exit 1
fi

# When timing is selected, add a "time" command to the front of the compiles.  This must be done before the --quiet
# handler below is run to get the right output command.
if [[ -n "$do_timing" ]]; then
    echo "$0: converting makefiles for timing (use --no-timing to prevent this)" 2>&1
    find . -name Makefile.in | grep -v libharu | grep -v libltdl | xargs sed -i~ \
        -e "s:^\(LT\)\{0,1\}\(CXX\)\{0,1\}COMPILE =:& echo \"\`pwd\`/\$@\" >> `pwd`/compile_times; /usr/bin/time -o `pwd`/compile_times -a :"
fi

# Rewrite a couple of makefile rules to be less verbose so (1) we can actually see the warning messages
# and (2) XEmacs doesn't get regexp stack overflows when parsing compiler output. See also scripts/rosegit/bin/rosegit-make.
#
# Note:
#     The '$(CXX)...' commands must be replaced also because automake generates them for *.o targets that depend on a *.C that
#     includes a directory component. For example, the automake rule:
#          rdis_SOURCES=RDis/main.C
#     generates a Makefile rule like:
#          main.o: RDis/main.C
#                  $(CXX) $(DEFS) ....... `test -f 'RDis/main.C' || echo '$(srcdir)/'`RDis/main.C
#     It seems that this might be an error on the part of automake since it bypasses libtool. [RPM 2009-04-04]
#
if [[ -n "$do_quiet" ]]; then
    (set -ex; $ROSE_DISTRIBUTION/scripts/quiet-mode) || true;
fi

# Save "--srcpath" value so rosegit-env can pick it up.  No need to do this for ROSE itself, just projects using the
# ROSE build script.
if [ ! -e "$srcdir/$SOME_ROSE_FILE" ]; then
    echo $ROSE_DISTRIBUTION >$srcdir/config/ROSE_SOURCES 2>/dev/null
fi

