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

cd src/

###############################################################################
# Previous GMP installations are only removed after a *successful* (re)build,
# before installing the new one. (Done below.)
###############################################################################

###############################################################################
# Set up environment variables:
###############################################################################

user_cflags=$CFLAGS # Save them. 'sage-env' sets CC, but not CFLAGS.
required_cflags=""  # Additional mandatory settings required by Sage, accumulated below.
user_ldflags=$LDFLAGS # Save them.
required_ldflags=""   # Additional mandatory settings required by Sage, accumulated below.
user_abi=$ABI # Just save it.
# In case we changed CPPFLAGS or CXXFLAGS, too, we should save the user's here as well.
# We don't have to add (e.g.) '-m64' to CFLAGS/CPPFLAGS/CXXFLAGS/LDFLAGS, since
# GMP's 'configure' is smart enough to add it if necessary or appropriate.


if [ -z "$CFLAG32" ]; then
    CFLAG32="-m32" # Only used in this script, no need to export it.
fi
if [ -z "$CFLAG64" ]; then
    CFLAG64="-m64" # Only used in this script, no need to export it.
fi


if [ "$SAGE_DEBUG" = yes ]; then
    # Disable optimization, add debug symbols:
    required_cflags="$required_cflags -g -O0"
    echo >&2 "Warning: Building GMP with SAGE_DEBUG=yes disables optimization."
else
    # Add debug symbols by default
    required_cflags="$required_cflags -g"
fi


case "$UNAME" in
    SunOS)
        true;;  # Auto-detect ABI
    Darwin)
        # In some cases (see SAGE_ROOT/spkg/bin/sage-env), on Darwin,
        # CC might be set to clang, but GMP doesn't seem to build
        # with clang.
        CLANG=`command -v clang`
        GCC=`command -v gcc`
        if [ -n "$CC" ] && [ "$CC" = "$CLANG" ] && [ -n "$GCC" ] ; then
            export CC="$GCC"
        fi
        # Do not set ABI=32 on MacOS X 10.6 (Darwin 10) and later, since
        # there everything defaults to 64-bit:
        if [ "`uname -r | sed 's/\..*//'`" -lt 10 ]; then
            # Assume MacOS X 10.4 or 10.5 (Darwin 8 or 9); also, PPC CPUs
            # are only supported by these, not later versions.
            echo "Building a 32-bit version of GMP, which is the only supported option."
            ABI=32
            case "`uname -m`" in
                ppc|ppc64|[Pp]ower*) # Apple's 'uname' returns strange strings
                    # The Darwin assembler rejects code using an
                    # extended instruction set by default (cf. #8664):
                    required_cflags="$required_cflags -Wa,-force_cpusubtype_ALL"
                    ;;
            esac
        else
            # Darwin 10 (MacOS X 10.6) or later.
            # We don't have to set ABI here.
            echo "Building a 64-bit version of GMP, which is the default."
        fi
        ;; # Darwin
    Linux)
        # GMP fails to build on 32-bit operating systems running on
        # 64-bit CPUs if CFLAGS happen to contain '-m32' and ABI is
        # *not* set, so we set it here if necessary:
        # (Cf. http://groups.google.com/group/gmp-devel/browse_thread/thread/46ccdc5dfc3485cd#)
        # Note: This code snippet could in principle be moved out of the
        #       Linux branch, but since we already set ABI for other
        #       OSs above (and print an according message), it's here.
        if [ -z "$ABI" ]; then
            echo "int main(){return 0;}" > foo.c
            # Try building and running a 64-bit executable:
            # (Building usually succeeds even on 32-bit systems, unless e.g. a 32-bit
            # CPU is explicitly selected by CFLAGS, while running does not.)
            if $CC $CFLAGS $CFLAG64 -o foo foo.c 2>/dev/null && ./foo 2>/dev/null; then
                # We can run 64-bit executables.
                # Setting ABI=64 shouldn't be necessary, but shouldn't hurt either.
                echo "Building a 64-bit version of GMP."
                case "`uname -m`" in
                    ppc*) ABI=mode64;;
                    *)    ABI=64
                esac
            elif $CC $CFLAGS $CFLAG32 -o foo foo.c 2>/dev/null && ./foo 2>/dev/null; then
                # We're on a 32-bit OS which cannot run 64-bit executables.
                echo "Building a 32-bit version of GMP."
                ABI=32
            else
                # It seems the compiler does not support -m32 nor -m64 (e.g.
                # GCC on Itanium rejects both); do not set ABI at all.
                echo "Your compiler does not support '$CFLAG32' nor '$CFLAG64'.  Leaving ABI unset."
            fi
            rm -f foo foo.c
        fi
        ;; # Linux
    *) # e.g. AIX or HP-UX
        echo >&2 "Warning: Your platform ($UNAME) isn't yet explicitly supported" \
            "by this GMP spkg, i.e., by Sage's part of it."
esac

# Work around a bug in GCC 4.7.0 which breaks the build on Itanium CPUs.
# See #12765, #12751, and http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48496
if [ "`uname -m`" = ia64 ] && [ "`testcc.sh $CC`" = GCC ] ; then
    gcc_version=`$CC -dumpversion`
    case "$gcc_version" in
      4.7.0)
        required_cflags="$required_cflags -O0 -finline-functions -fschedule-insns"
        echo >&2 "Warning: Disabling almost all optimization due to a bug in GCC 4.7.0"
        echo >&2 "         on Itanium, which otherwise would break the build."
        echo >&2 "         See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48496"
        echo >&2 "         for current status and further details."
        ;;
    esac
fi

export ABI CFLAGS CXXFLAGS LDFLAGS # Partially redundant, but safe(r).
# We don't export CPPFLAGS here, since we don't (have to) modify them.

###############################################################################
# Now configure GMP, eventually modifying CFLAGS [further]:
###############################################################################

GMP_CONFIGURE="--enable-shared $GMP_CONFIGURE"

# If we're bootstrapping GCC from the GCC spkg, don't build the C++
# interface (cf. #12782), static libraries and disable fat binary.
# After GCC is built, we will build GMP again.
if [ "$SAGE_BUILD_TOOLCHAIN" = yes ]; then
    echo "Building a reduced version of GMP to bootstrap GCC."
    echo "GMP will later get rebuilt (with the C++ interface and static libraries"
    echo "enabled) using the new compiler."
    GMP_CONFIGURE="$GMP_CONFIGURE --disable-cxx --disable-static"
    SAGE_FAT_BINARY=no
else
    # Also build the static library to be used by e.g. ECM
    # unless we are on Cygwin where we can only build a shared
    # or a static library but not both:
    if [ "$UNAME" = "CYGWIN" ]; then
        echo "Building GMP with the C++ interface and (only) shared libraries."
        GMP_CONFIGURE="--enable-cxx $GMP_CONFIGURE --disable-static"
    else
        echo "Building GMP with the C++ interface and (also) static libraries."
        GMP_CONFIGURE="--enable-cxx --enable-static $GMP_CONFIGURE"
    fi
fi
# (Further options to 'configure' are added below.)

# If SAGE_FAT_BINARY is enabled, then add --enable-fat to configure
# options on Linux x86 systems.  On other systems, fat binaries are not
# supported.  Then we specify a build architecture which doesn't
# have a CPU name in it.  This means which use the vanilla config.guess
# (renamed to configfsf.guess in GMP) file instead of GMP's version.
if [ "$SAGE_FAT_BINARY" = "yes" ]; then
    case "$UNAME-`uname -m`" in
        Linux-i[3456]86)
            echo "** Building with \"fat binary\" support for 32-bit CPUs **"
            GMP_CONFIGURE="--enable-fat $GMP_CONFIGURE"
            ;;
        Linux-x86_64|Linux-amd64)
            echo "** Building with \"fat binary\" support for 64-bit CPUs **"
            GMP_CONFIGURE="--enable-fat $GMP_CONFIGURE"
            ;;
        *) # Anything else
            echo "** Building a generic binary (not assuming any specific CPU) **"
            GMP_CONFIGURE="--build=`./configfsf.guess` $GMP_CONFIGURE"
            ;;
    esac
fi


# Pre-configure GMP to get the settings it would use if CFLAGS were empty:
echo "Checking what CFLAGS GMP would use if they were empty..."
(unset CFLAGS CPPFLAGS CXXFLAGS && ./configure $GMP_CONFIGURE) &>configure-empty.log
if [ $? -ne 0 ]; then
    # Output the log of the failed configure run
    cat configure-empty.log
    echo >&2 "Error configuring GMP (with CFLAGS unset)."
    echo >&2 "Consult `pwd`/config.log for for details."
    exit 1
fi


# Read GMP-selected flags from Makefile
gmp_cc=`sed -n 's/^CC *= *//p' Makefile`
gmp_cflags=`sed -n 's/^CFLAGS *= *//p' Makefile`
if [ -z "$gmp_cc" ]; then
    echo >&2 "Error: failed to determine \$CC from Makefile"
    echo >&2 "Please report this to <sage-devel@googlegroups.com>"
    exit 1
fi
echo "Settings chosen by GMP when configuring with CFLAGS unset:"
echo "  CC:      $gmp_cc"
echo "  CFLAGS:  $gmp_cflags"
echo "Settings added by Sage to build GMP, taking into account SAGE_DEBUG etc.:"
echo "  CFLAGS:  $required_cflags"  # Might be empty.
echo "  LDFLAGS: $required_ldflags" # Might be empty.
echo "  ABI:     $ABI" # Might be empty, or the one specified by the user.
echo "Settings from the \"global\" environment:"
echo "  CC:      $CC" # Set by Sage, maybe overridden by the user.
echo "  CFLAGS:  $user_cflags"
echo "  LDFLAGS: $user_ldflags"
echo "  ABI:     $user_abi"
echo "  (CPP, CPPFLAGS, CXX and CXXFLAGS are listed below; these don't get modified.)"

# Finally: use GMP's flags, plus those required by Sage for the
# package to build properly, plus those specified by the user.
CFLAGS="$gmp_cflags $required_cflags $user_cflags"
LDFLAGS="$required_ldflags $user_ldflags"

echo "Finally using the following settings:"
echo "  CC=$CC"
echo "  CFLAGS=$CFLAGS"
echo "  CPP=$CPP"
echo "  CPPFLAGS=$CPPFLAGS"
echo "  CXX=$CXX"
echo "  CXXFLAGS=$CXXFLAGS"
echo "  LDFLAGS=$LDFLAGS"
echo "  ABI=$ABI"
echo "(These settings may still get overridden by 'configure' or Makefiles.)"

###############################################################################
# Now really configure GMP with proper settings:
###############################################################################

# We also add '--libdir="$SAGE_LOCAL/lib"' below, since newer autotools may
# otherwise put the libraries into .../lib64 on 64-bit systems (cf. #12131).

echo "Configuring GMP with the following options:"
echo "    --prefix=\"$SAGE_LOCAL\" --libdir=\"$SAGE_LOCAL/lib\" $GMP_CONFIGURE"
echo "You can set GMP_CONFIGURE to pass additional parameters."

# Clear the cache of the previous configure run
find . -name config.cache -exec rm -f {} \;

./configure --prefix="$SAGE_LOCAL" --libdir="$SAGE_LOCAL/lib" $GMP_CONFIGURE
if [ $? -ne 0 ]; then
    echo >&2 "Error configuring GMP. (See above for the options passed to it.)"
    exit 1
fi

###############################################################################
# Now build GMP:
###############################################################################

echo "Now building GMP..."
$MAKE
if [ $? -ne 0 ]; then
    echo >&2 "Error building GMP."
    exit 1
fi

echo "Build succeeded."

###############################################################################
# Remove previous installation (if any), *after* a successful build:
###############################################################################

echo "Removing old GMP/GMPIR headers..."
rm -f "$SAGE_LOCAL"/include/{gmp,mpir}*.h

# Do NOT delete old GMP/GMP shared libraries as Sage's versions of libraries
# used by GCC might still refer to them, such that their deletion would break
# GCC inside Sage. (We could perhaps remove libgmp* though.)
if false; then
    echo "Removing old GMP/MPIR libraries..."
    rm -f "$SAGE_LOCAL"/lib/lib{gmp,mpir}*
else
    echo "Not removing old GMP/MPIR shared libraries, as other libraries"
    echo "and executables might still refer to them:"
    ls -l "$SAGE_LOCAL"/lib/lib{gmp,mpir}*
    echo "(Libraries with the same version number will get updated though.)"
fi

# Mark MPIR as not installed (since we will overwrite it)
rm -f "$SAGE_SPKG_INST"/mpir-*

###############################################################################
# Now install GMP:
###############################################################################

echo "Now installing GMP..."
$MAKE install
if [ $? -ne 0 ]; then
    echo >&2 "Error installing GMP."
    exit 1
fi
