#!/usr/bin/env bash
#
# Write a Makefile for the autotools spkg.  This actually requires a
# Sage with autotools installed, so run this from within a Sage shell.
# This script also requires git.
#
# Typical usage:
# ./spkg-write-makefile >Makefile.build
#

set -e

if [ -z "$SAGE_ROOT" ]; then
    echo >&2 "SAGE_ROOT undefined ... exiting"
    echo >&2 "Maybe run 'sage --sh'?"
    exit 1
fi

# Sanity check that AUTOCONF_VERSION and AUTOMAKE_VERSION works
if ! env "AUTOCONF_VERSION=2.62" autoconf --version | grep >/dev/null '2[.]62'; then
    echo >&2 "The environment variable AUTOCONF_VERSION does not seem to work."
    echo >&2 "Make sure you are running $0 within a Sage shell"
    echo >&2 "with the autotools spkg installed."
    exit 3
fi
if ! env "AUTOMAKE_VERSION=1.9.6" aclocal --version | grep >/dev/null '1[.]9[.]6'; then
    echo >&2 "The environment variable AUTOMAKE_VERSION does not seem to work."
    echo >&2 "Make sure you are running $0 within a Sage shell"
    echo >&2 "with the autotools spkg installed."
    exit 3
fi
if ! env "LIBTOOL_VERSION=1.5.26" libtool --version | grep >/dev/null '1[.]5[.]26'; then
    echo >&2 "The environment variable LIBTOOL_VERSION does not seem to work."
    echo >&2 "Make sure you are running $0 within a Sage shell"
    echo >&2 "with the autotools spkg installed."
    exit 3
fi

export PATH="$SAGE_ROOT/build/pkgs/autotools:$PATH"


# Read versions
source version-list

# Extract upstream autotools tarball
cd "$SAGE_ROOT"
PKG=autotools-`cat build/pkgs/autotools/package-version.txt`
mkdir -p "$SAGE_LOCAL/tmp/sage"
cd "$SAGE_LOCAL/tmp/sage"
tar xjf "$SAGE_ROOT/upstream/$PKG.tar.bz2"
cd $PKG

cat <<EOF
########################################################################
# This file is automatically generated by $0
########################################################################

all: autoconf-all automake-all libtool-all tools-all

########################################################################

EOF

echo 'tools-all: $(SAGE_LOCAL)/bin/makeinfo $(SAGE_LOCAL)/bin/m4 $(SAGE_LOCAL)/bin/help2man'
echo
echo '$(SAGE_LOCAL)/bin/makeinfo: $(SRC)/texinfo-4.13'
# On Windows, copy manifest file.  Otherwise install-info cannot be
# executed without admin privileges, since the name contains the
# string "install".
echo -e '\tif [ "$$UNAME" = CYGWIN ] ; then cp -p "$(SRC)/../install-info.exe.manifest" "$(SAGE_LOCAL)/bin" ; fi'
echo -e '\tcd $< && ./configure --prefix="$(SAGE_LOCAL)" && $(MAKE) && $(MAKE) install'
echo
echo '$(SAGE_LOCAL)/bin/m4: $(SRC)/m4-1.4.17 $(SAGE_LOCAL)/bin/makeinfo'
echo -e '\tcd $< && ./configure --prefix="$(SAGE_LOCAL)" && $(MAKE) && $(MAKE) install'
echo
echo '$(SAGE_LOCAL)/bin/help2man: $(SRC)/help2man-1.46.4 $(SAGE_LOCAL)/bin/makeinfo'
echo -e '\tcd $< && ./configure --prefix="$(SAGE_LOCAL)" && $(MAKE) && $(MAKE) install'
echo
echo '########################################################################'
echo

# Write make rules for many versions of a package
# Usage: write_make_rules PACKAGE VERSION1 VERSION2 ...
write_make_rules() {
    # Package name (e.g. "autoconf")
    p=$1
    shift

    prevv=
    all="$p-all:"
    for v in $*
    do
        echo >&2 "Processing $p-$v"
        cd $p

        # Find out the correct tag for version $v
        tag=`git tag -l | grep -i -x -e "v$v" -e "release-$v" -e "$p-$v" | head -1`
        if [ -z "$tag" ]; then
            echo >&2 "Cannot find tag for $p-$v"
            exit 3
        fi

        # Checkout the version given by the tag (and remove all garbage)
        git checkout -f $tag
        git clean -f -d -x -q

        deps="\$(SAGE_LOCAL)/bin/m4 \$(SAGE_LOCAL)/bin/makeinfo"
        ac_ver=
        am_ver=
        if cat configure.* | grep help2man >/dev/null; then
            deps="$deps \$(SAGE_LOCAL)/bin/help2man"
        fi
        if [ -f configure.ac ]; then
            # Minimum required version of Automake
            if [ ! -f configure ]; then
                # libtool-2.4.3 requires some gnulib files
                if [ -d gnulib ]; then
                    cp -a ../gnulib/build-aux .
                fi
                # Run aclocal, such that AM_INIT_AUTOMAKE is available.
                if [ -d m4 ]; then
                    aclocal -I m4
                else
                    aclocal
                fi
                # Require at least version 1.9.6, a reasonable default.
                am_ver=`( echo 1.9.6; autoconf --trace='AM_INIT_AUTOMAKE:$1' configure.ac ) | latest_version`
                # Run the *correct* version of aclocal, such that we do
                # not introduce unneeded AC_PREREQ() definitions.
                if [ -d m4 ]; then
                    env "AUTOMAKE_VERSION=$am_ver" aclocal -I m4
                else
                    env "AUTOMAKE_VERSION=$am_ver" aclocal
                fi
            fi

            # Minimum required version of Autoconf: always consider
            # AC_PREREQ for Automake, even if "configure" exists.
            if [ ! -f configure ] || [ $p = automake ]; then
                # Require at least version 2.59, a reasonable default.
                ac_ver=`( echo 2.59; autoconf --trace='AC_PREREQ:$1' configure.ac ) | latest_version`
            fi

            # Automake 1.10 thinks it only needs autoconf 2.59, when in fact it needs 2.60.  Fix it up.
            if [ $p = automake ] && [ $v = 1.10 ]; then
                ac_ver=2.60
            fi

            # Minimum required version of libtool.
            # Empty by default.
            lt_ver=`( autoconf --trace='LT_PREREQ:$1' configure.ac ) | latest_version`
        fi
        if [ -n "$ac_ver" ]; then
            deps="$deps \$(SAGE_LOCAL)/autoconf-$ac_ver"
        fi
        if [ -n "$am_ver" ]; then
            deps="$deps \$(SAGE_LOCAL)/automake-$am_ver"
        fi
        if [ -n "$lt_ver" ]; then
            deps="$deps \$(SAGE_LOCAL)/libtool-$lt_ver"
        fi

        # Figure out how to bootstrap
        if [ -f configure ]; then
            bootstrap=
        elif [ -d gnulib ]; then
            bootstrap="bash bootstrap --skip-git --skip-po --gnulib-srcdir=../../src/gnulib && "
        elif [ -f bootstrap.sh ]; then
            bootstrap="bash -c 'set -e; source bootstrap.sh' && "
        elif [ -f bootstrap ]; then
            bootstrap="bash -c 'set -e; source bootstrap' && "
        else
            bootstrap="autoreconf -i -I m4 && "
        fi

        if [ -f autoheader.sh ]; then
            # Work around Autoconf bootstrap bug
            bootstrap="${bootstrap}touch autoupdate.sh && "
        fi

        # Write make rules
        echo "# Extract sources from git repository serially"
        echo "$p-$v/.tarball-version: $prevextract"
        echo -e "\t( cd \$(SRC)/$p && git archive --format=tar --prefix=$p-$v/ $tag ) | tar xf -"
        echo -e "\techo $v >$p-$v/.tarball-version"
        if [ $p = libtool -a ! -f .serial ] ; then
            # The file .serial would be generated at "make dist" time.  It is used in ltversion.m4.
            # If .serial is missing, ltmversion.m4 will be malformed, causing the following warning
            # when the user uses autoreconf.
            #   m4/ltversion.m4:12: warning: ill-formed serial number 'ltversion.m4',
            #                                expecting a version string with only digits and dots
            # See Trac #21047.
            # Since we don't do "make dist" but rather build from a repository check-out, we have to
            # supply the .serial file ourselves.  The following recipe is from libtool's Makefile.am.
            echo -e "\techo $( git log --pretty=oneline | wc -l | sed 's|[\t ]||g ' ) > $p-$v/.serial"
        fi
        echo

        echo "\$(SAGE_LOCAL)/$p-$v: $p-$v/.tarball-version $deps"
        echo -e "\texport MAKE='\$(MAKE) -j1' ; \\\\"
        [ -z "$lt_ver" ] || echo -e "\texport LIBTOOL_VERSION=$lt_ver ; \\\\"
        [ -z "$ac_ver" ] || echo -e "\texport AUTOCONF_VERSION=$ac_ver ; \\\\"
        [ -z "$am_ver" ] || echo -e "\texport AUTOMAKE_VERSION=$am_ver ; \\\\"
        echo -e "\tcd $p-$v && ${bootstrap}\\\\"
        echo -e "\t    ./configure --prefix=\"\$(SAGE_LOCAL)/$p-$v\" && \\\\"
        echo -e "\t    \$\$MAKE && \$\$MAKE install"
        echo -e "\t# Remove all files except for the .* files"
        echo -e "\t[ \"\$\$SAGE_KEEP_BUILT_SPKGS\" = yes ] || rm -rf $p-$v/*"
        echo

        prevextract="$p-$v/.tarball-version"
        all="$all \$(SAGE_LOCAL)/$p-$v"

        cd ..  # Back to upstream source directory
    done
    echo "$all"
    echo
    echo "########################################################################"
    echo
}

write_make_rules autoconf $autoconf_versions
write_make_rules automake $automake_versions
write_make_rules libtool $libtool_versions

cd "$SAGE_LOCAL/tmp/sage"
rm -rf $PKG
