#!/usr/bin/env zsh

# inst-lto-libs - Install GMP and GNU MPFR libraries built with GCC's
# LTO data. See the description of -flto on:
#
#   http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
#   http://gcc.gnu.org/onlinedocs/gccint/LTO.html
#
# So, programs need to be compiled with the -flto option and the same
# GCC version, and linked with the -flto -fuse-linker-plugin options.
# Explicit static linking is needed too.
#
# After a GCC upgrade, the libraries may need to be reinstalled in the
# same way. Therefore, on machines that can be upgraded, it is advised
# to use a $CC value with the GCC version, e.g. "CC=gcc-4.7".
#
# Modify the "ltodir=..." line to change the installation directory.
# For a parallel build, you can set MAKE_JOBS to the number of jobs.
#
# Copyright (C) 2012 Vincent Lefevre <vincent@vinc17.net>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see http://www.gnu.org/licenses/
# or write to the Free Software Foundation, Inc., 51 Franklin St,
# Fifth Floor, Boston, MA 02110-1301, USA.

set -e

if [[ $# -ne 2 && $# -ne 3 ]] then
  echo "Usage: $0 <gmp_tarball> <mpfr_tarball> [ <mpfr_patches> ]" >&2
  exit 1
fi

gmp=$1:a
echo "GMP tarball: $gmp"

mpfr=$2:a
echo "MPFR tarball: $mpfr"

if [[ -n $3 ]] then
  patches=$3:a
  echo "MPFR patches: $patches"
  mpfrpatches() { patch -N -Z -p1 < $patches }
else
  alias mpfrpatches=true
fi

opts="-march=native -O3 -flto=jobserve -fuse-linker-plugin"

: ${CC:=gcc}
echo "Compiler: $CC"

ltowrapper=$($CC -v |& sed -n 's/^COLLECT_LTO_WRAPPER=//p')
if [[ -z $ltowrapper ]] then
  {
    echo "This compiler is unsupported (no COLLECT_LTO_WRAPPER line)."
    echo "'$CC -v' output:"
    $CC -v
  } >&2
  exit 1
fi

ltovers=${${ltowrapper%/lto-wrapper}##*/}
if [[ $ltovers =~ '^[-.0-9]*$' ]] then
  echo "LTO version: $ltovers"
else
  echo "Unsupported COLLECT_LTO_WRAPPER path: $ltowrapper" >&2
  exit 1
fi

ltodir=$HOME/lto/$ltovers
if [[ -d $ltodir ]] then
  echo "Directory $ltodir already exists!" >&2
  exit 1
fi

echo "Install directory: $ltodir"

mkdir -p $ltodir/bin
cat <<EOF > $ltodir/bin/gcc-lto
#!/bin/sh

C_INCLUDE_PATH=$ltodir/include${C_INCLUDE_PATH:+:$C_INCLUDE_PATH}
LIBRARY_PATH=$ltodir/lib${LIBRARY_PATH:+:$LIBRARY_PATH}
export C_INCLUDE_PATH LIBRARY_PATH

EOF

. $ltodir/bin/gcc-lto

tmpdir=$(mktemp -d /tmp/$USER-lto-XXXXXX)
trap 'rm -rf $tmpdir' 1 2 15
pushd $tmpdir

build()
{
  # Note: the -fuse-linker-plugin option is not needed to build the
  # libraries with LTO; but it is probably useful for "make check",
  # in order to enable LTO there.
  ./configure --prefix=$ltodir --disable-shared CC=$CC CFLAGS=$opts
  make ${MAKE_JOBS:+-j$MAKE_JOBS}
  make ${MAKE_JOBS:+-j$MAKE_JOBS} check
  make install
}

tar xf $gmp
pushd gmp-*
build
popd
rm -rf gmp-*

tar xf $mpfr
pushd mpfr-*
mpfrpatches
build
popd
rm -rf mpfr-*

popd
rm -rf $tmpdir

echo "$CC -static $opts" '${@+"$@"}' >> $ltodir/bin/gcc-lto
chmod +x $ltodir/bin/gcc-lto

echo "Installation OK."
echo "To enable LTO, use: $ltodir/bin/gcc-lto"

# $Id: inst-lto-libs 55069 2012-09-19 12:45:50Z vinc17/xvii $
