#!/usr/bin/env bash
if [ -z "$SAGE_LOCAL" ]; then
echo >&2 "Error: SAGE_LOCAL undefined - exiting..."
exit 1
fi
cd src/
###############################################################################
# Apply patches (if any):
###############################################################################
# Apply patches. See SPKG.txt for information about what each patch
# does.
for patch in ../patches/*.patch; do
[ -r "$patch" ] || continue # Skip non-existing or non-readable patches
patch -p1 <"$patch"
if [ $? -ne 0 ]; then
echo >&2 "Error applying '$patch'"
exit 1
fi
done
###############################################################################
# Set up environment variables, depending on SAGE_* settings:
# Note that GMP-ECM is written in C (and assembler) - no C++ sources.
###############################################################################
# We eventually use / add these settings (or parts of them) to "our" CFLAGS,
# e.g. "-march=..." or "-mcpu=..." and "-mtune=..." to let gcc generate better,
# processor-specific code, since ECM doesn't use them if we set our own:
# (But currently MPIR doesn't provide optimized settings either if we pass
# non-empty CFLAGS; of course the user could set such manually though.)
gmp_cc_pat='/^[ ]*#[ ]*define[ ]\{1,\}__GMP_CC[ ]\{1,\}/s/.*"\([^"]*\)"/\1/p'
gmp_cflags_pat='/^[ ]*#[ ]*define[ ]\{1,\}__GMP_CFLAGS[ ]\{1,\}/s/.*"\([^"]*\)"/\1/p'
gmp_header_file="$SAGE_LOCAL"/include/gmp.h
gmp_cc=`sed -n -e "$gmp_cc_pat" "$gmp_header_file"`
gmp_cflags=`sed -n -e "$gmp_cflags_pat" "$gmp_header_file"`
# At least /some/ newer versions of MPIR define __GMP_CC and __GMP_CFLAGS
# (also in gmp.h! -- how compatible is that?) to (literally) __MPIR_CC and
# __MPIR_CFLAGS, respectively, i.e., to preprocessor variables, so we might
# have to get the real strings from their definitions:
# (Since we currently only match string literals above, both variables would
# be empty in that case, and not contain the names of preprocessor variables.
# We could change the patterns to actually match any definition / "value".)
case "$gmp_cc" in __MPIR_CC|"")
gmp_cc=`sed -n -e "${gmp_cc_pat/GMP/MPIR}" "$gmp_header_file"`
esac
case "$gmp_cflags" in __MPIR_CFLAGS|"")
gmp_cflags=`sed -n -e "${gmp_cflags_pat/GMP/MPIR}" "$gmp_header_file"`
esac
# Extract GMP's/MPIR's settings of CC and CFLAGS from a system-wide installation
# (if present); these are only printed, for informational purposes.
system_gmp_h=""
for incdir in /usr/include /usr/local/include; do
if [ -f $incdir/gmp.h ]; then
system_gmp_h=$incdir/gmp.h
fi
done
if [ -n "$system_gmp_h" ]; then
system_gmp_cc=`sed -n -e "$gmp_cc_pat" $system_gmp_h`
system_gmp_cflags=`sed -n -e "$gmp_cflags_pat" $system_gmp_h`
case "$system_gmp_cc" in __MPIR_CC|"")
system_gmp_cc=`sed -n -e "${gmp_cc_pat/GMP/MPIR}" $system_gmp_h`
esac
case "$system_gmp_cflags" in __MPIR_CFLAGS|"")
system_gmp_cflags=`sed -n -e "${gmp_cflags_pat/GMP/MPIR}" $system_gmp_h`
esac
fi
if [ "$SAGE64" = yes ]; then
echo "Building a 64-bit version of GMP-ECM."
if [ -z "$CFLAG64" ]; then
CFLAG64=-m64
fi
CFLAGS="$CFLAGS $CFLAG64"
LDFLAGS="$LDFLAGS $CFLAG64"; export LDFLAGS
fi
# libtool should add the proper flags, but doesn't use "-fPIC"
# for the *static* library (which the Sage library links to unless
# we also build the shared one). The following only handles the
# most common cases, not all variations with '=yes' or '=no' etc.:
if ! (echo $ECM_CONFIGURE | egrep -- "--enable-shared|--with-pic" >/dev/null) ||
(echo $ECM_CONFIGURE | egrep -- "--disable-shared" >/dev/null);
then
echo "Adding '-fPIC' to CFLAGS since we don't (also) build a shared library."
CFLAGS="$CFLAGS -fPIC" # alternatively add '--with-pic' to 'configure' options
else
# PIC usually slows down the execution, so don't use it for the *static*
# library (unless '--with-pic' was given). libtool does the right thing
# for the shared one we also build, which then will be used by Sage.
echo "Not adding '-fPIC' since we also build a shared library Sage will link"
echo "to, or '--with-pic' was given in ECM_CONFIGURE."
fi
if [ "$SAGE_DEBUG" = yes ]; then
# Add debug symbols and disable optimization:
echo >&2 "Warning: Setting SAGE_DEBUG=yes completely disables optimization."
CFLAGS="-g -O0 $CFLAGS"
echo "You may in addition (or instead) pass '--enable-assert' and/or"
echo "'--enable-memory-debug' to GMP-ECM's 'configure' by setting (and"
echo "of course exporting) ECM_CONFIGURE accordingly."
else
# Enable optimization, may be overridden by user settings:
case "`uname -srm | tr ' ' '-'`" in
Darwin-9*-[Pp]ower*)
# Don't add debug symbols because configure otherwise
# fails due to a bus error in Apple's 'ld' when trying
# to determine if global symbols are prefixed with an
# underscore (cf. http://trac.sagemath.org/sage_trac/ticket/5847#comment:35 ff.):
echo >&2 "Warning: Disabling debug symbols on MacOS X 10.5" \
"PowerPC because of a linker (?) bug."
echo >&2 "See http://trac.sagemath.org/sage_trac/ticket/5847#comment:35" \
"ff. for details."
echo >&2
CFLAGS="-O3 $CFLAGS"
;;
*)
CFLAGS="-g -O3 $CFLAGS"
esac
fi
if [ "$SAGE_FAT_BINARY" = yes ]; then
# XXX Disable SSE2 on x86? (by passing '--enable-sse2=no' to 'configure')
# XXX Disable asm-redc? Or pass some "generic" '--host=...' to 'configure'?
echo >&2 "Warning: SAGE_FAT_BINARY is currently not really supported by this package."
echo >&2 " Add e.g. '--disable-asm-redc' and/or '--enable-sse2=no'"
echo >&2 " to ECM_CONFIGURE if you run into problems."
else
# Tune the code generation to the machine we build on:
cpu_params=""; other_gmp_cflags=""
# Some gcc 4.0.x versions don't support '-march=native', and it's currently
# not supported on all platforms supported by Sage:
if touch foo.c && $CC -march=native -c foo.c &>/dev/null; then
# The compiler supports '-march=native', but the assembler might not
# support (some of) the instructions emitted with this (e.g. the
# Apple assembler doesn't know AVX yet).
cat >foo.c <<-"EOF"
double d;
unsigned long fancy_insns() { return (unsigned long) d; }
int main () { return 0; }
EOF
if $CC -march=native -o foo foo.c &>/dev/null && ./foo >/dev/null; then
cpu_params="-march=native"
else
echo >&2 "Warning: Your assembler apparently doesn't understand the instructions"
echo >&2 " your compiler ($CC) generates with '-march=native'."
echo >&2 " You might also try to compile GMP-ECM with (e.g.)"
echo >&2 " CFLAGS=\"-march=native -mno-avx\""
echo >&2 " to disable specific instruction set extension (in this case, AVX)."
fi
fi
if [ -z "$cpu_params" ]; then
# 'native' not supported, see if GMP / MPIR provides us some CPU type:
for opt in $gmp_cflags; do
case $opt in
-march=*|-mcpu=*|-mtune=*|-mpower*|-mno-power*)
echo "Found CPU parameter in gmp.h: $opt"
cpu_params="$cpu_params $opt"
;;
# perhaps add other options, too (e.g. for different compilers)
*) other_gmp_cflags="$other_gmp_cflags $opt"
esac
done
fi
rm -f foo.* foo
# Only add them if CFLAGS do not already contain similar:
if [ -n "$cpu_params" ] &&
! (echo "$CFLAGS" | egrep -- '-march=|-mcpu=|-mtune=|-mpower|-mno-power' >/dev/null);
then
echo "Using additional host-specific CFLAGS: $cpu_params"
CFLAGS="$cpu_params $CFLAGS"
fi
if [ -n "$other_gmp_cflags" ]; then
echo "Not using other CFLAGS provided by gmp.h: $other_gmp_cflags"
fi
fi
echo
echo "Settings from SAGE_LOCAL/include/gmp.h:"
echo " CC=$gmp_cc"
echo " CFLAGS=$gmp_cflags"
if [ -n "$system_gmp_h" ]; then
echo "Settings found in $system_gmp_h (currently not used):"
echo " CC=$system_gmp_cc"
echo " CFLAGS=$system_gmp_cflags"
fi
echo "Finally using:"
echo " CC=$CC"
echo " CFLAGS=$CFLAGS"
echo " CPP=$CPP"
echo " CPPFLAGS=$CPPFLAGS"
test -n "$CCAS" && echo " CCAS=$CCAS"
test -n "$CCASFLAGS" && echo " CCASFLAGS=$CCASFLAGS"
echo " LDFLAGS=$LDFLAGS"
test -n "$LIBS" && echo " LIBS=$LIBS"
echo " ABI=$ABI"
echo " M4=$M4"
echo "(These settings may still get overridden by 'configure' or Makefiles.)"
export CFLAGS # Not exported by 'sage-env'. LDFLAGS are exported above if
# necessary. We currently don't set (or modify) any other
# environment variables, so don't have to export them here.
###############################################################################
# Now configure ECM:
# (Note: Building (also) a *shared* library is disabled by default.
# Add "--enable-shared" below if you want it, though one can
# now pass extra 'configure' options through ECM_CONFIGURE.)
# If you do so, i.e. add '--enable-shared' by default, also
# adapt the logic regarding '-fPIC' above.
###############################################################################
echo
if [ -z "$ECM_CONFIGURE" ]; then
echo "Now configuring GMP-ECM with the following options:"
else
echo "Now configuring GMP-ECM with additional options as specified by" \
"ECM_CONFIGURE:"
echo " $ECM_CONFIGURE"
echo "Finally configuring GMP-ECM with the following options:"
fi
echo " --prefix=\"$SAGE_LOCAL\""
echo " --libdir=\"$SAGE_LOCAL/lib\""
echo " --with-gmp=\"$SAGE_LOCAL\""
for opt in $ECM_CONFIGURE; do
echo " $opt"
done
if [ -z "$ECM_CONFIGURE" ]; then
echo "You can set ECM_CONFIGURE to pass additional parameters,"
echo "e.g. \"--enable-shared\" to also build a *shared* library,"
echo "or \"--disable-sse2\" if you encounter problems on a Pentium III system."
fi
echo
./configure --prefix="$SAGE_LOCAL" --libdir="$SAGE_LOCAL/lib" \
--with-gmp="$SAGE_LOCAL" \
$ECM_CONFIGURE
if [ $? -ne 0 ]; then
echo >&2 "Error configuring GMP-ECM."
echo >&2 "(See above for the options passed to its 'configure'.)"
exit 1
fi
###############################################################################
# Now build ECM:
###############################################################################
echo
echo "Now building GMP-ECM..."
$MAKE
if [ $? -ne 0 ]; then
echo >&2 "Error building GMP-ECM."
exit 1
fi
###############################################################################
# Remove old executable/header/libraries/manpage:
###############################################################################
echo
echo "Build succeeded. Now removing old binary, header file, manual page and libraries..."
rm -f "$SAGE_LOCAL"/bin/ecm
rm -f "$SAGE_LOCAL"/lib/libecm.*
rm -f "$SAGE_LOCAL"/include/ecm.h
rm -f "$SAGE_LOCAL"/share/man/man1/ecm.1
###############################################################################
# Now install ECM:
###############################################################################
echo "Now installing GMP-ECM..."
$MAKE install
if [ $? -ne 0 ]; then
echo >&2 "Error installing GMP-ECM (though it appears to have built fine)."
exit 1
fi