#!/bin/bash

echo "EXTRA_CFLAGS=$EXTRA_CFLAGS"
echo "Command Line:"
echo $0 $*

SRC_DIR=`pwd`
WORKING_DIR=`pwd`
OMF=elf
TARGET_OS=native
UNAME=`uname -s | sed -e 's/[^a-zA-Z].*$//' | tr "[:upper:]" "[:lower:]"`
BUILD_OS="i386-$UNAME"
EXTRA_DEFINES="-DRESOURCE_MISMATCH_OK"
EXTRA_OPTS=
CROSS=
BUILD_OPTION=
STATIC=
INSTALL_DIR=  
XCLM_DIR=
BUILD64=0
export ABI=32

BUGURL="https://www.microchip.com/technical-support"
BUILD="expat gmp cloog libelf zlib"

# What is the native host?
export NATIVE=

THIS_HOST=`uname -s`
this_host=`uname -s | tr "[:upper:]" "[:lower:]"`

# Normalize HOST OS
case $THIS_HOST in
  Darwin*) NATIVE="mac";;
  SunOS*)  NATIVE="solaris";;
  *inux*)  NATIVE="linux";;
  CYGWIN*) NATIVE="mingw32";;
esac


DONE=0
while [ "$DONE" = "0" ]; do
  if [ "${1:-done}" = "done" ]; then
    DONE=1;
  else
    case $1 in
      -user)
         BUGURL="email:`whoami`@`hostname`"
         EXTRA_DEFINES="-DRESOURCE_MISMATCH_OK"
         shift 1;;
      -install=*) 
         INSTALL=`echo $1 | sed 's/.*=//'`;
         shift 1;;
      -install_dir=*) 
         INSTALL_DIR=`echo $1 | sed 's/.*=//'`;
         shift 1;;
      -src=*) 
         SRC_DIR=`echo $1 | sed 's/.*=//'`;
         shift 1;;
      -omf=*) 
         OMF=`echo $1 | sed 's/.*=//'`;
         if [ "$OMF" = "elf" ]; then
           #LTO="--enable-lto"
           LTO="--disable-lto"
         else
           LTO="--disable-lto"
         fi
         shift 1;;
      -cross=*) 
         TARGET_OS=`echo $1 | sed -e 's/.*=//' -e 's/-nolm//' -e 's/-xclm//' -e 's/-exlm//' -e 's/mingw64/mingw32/' -e 's/64//' -e 's/-fusa//'`;
         SUFFIX=`echo $1 | sed -e 's/.*=//'`
         case $SUFFIX in
           *-*) SUFFIX=`echo $SUFFIX | sed -e 's/.*-/-/'`;;
           *) SUFFIX="";
         esac
         if ( echo $1 | grep -q "64" ); then
           BUILD64=1
         fi
         if ( echo $TARGET_OS | grep -v -q -e "native" -e $NATIVE ); then
           if ( echo ${TARGET_OS} | grep "i[0-9]86" ); then
              # full host os specified
              CROSS="--host=${TARGET_OS}"
              ZLIB_TOOLS="${TARGET_OS}"
           else
              if [ "$BUILD64" == "1" ];then 
                CROSS="--host=x86_64-w64-${TARGET_OS}"
                ZLIB_TOOLS="x86_64-w64-${TARGET_OS}"
                BUILD_OS="x86_64-$UNAME"
              else
                CROSS="--host=i386-${TARGET_OS}"
                ZLIB_TOOLS="i386-${TARGET_OS}"
                BUILD_OS="i386-$UNAME"
              fi
           fi
         elif [ "$BUILD64" == "1" ]; then
           BUILD_OS="x86_64-$UNAME"
         fi
         shift 1;;
      -build=*)
         BUILD="$BUILD `echo $1 | sed 's/.*=//'`";
         shift 1;;
      -D*)
         EXTRA_DEFINES="$EXTRA_DEFINES $1"
         shift 1;;
      -?) 
         echo "Usage: $0 <options>"
         echo "    -install=<install-dir>"
         echo "    -src=<src-dir>"
         echo "    -omf=[coff|elf]"
         echo "    -cross=[linux|mingw32]"
         echo "    -build=<module>"
         echo "    -D  specify extra defines for build"
         echo
         exit 1;;
      *) echo "Unknown option $1";
         exit 1;;
    esac
  fi
done

if [ "$INSTALL" != "" ]; then
  INSTALL_DIR="${INSTALL}-${TARGET_OS}${SUFFIX}"
fi

if ( ! echo $BUILD | grep -q "g++" ); then
  BUILD="$BUILD gcc"
fi

if [ -f $SRC_DIR/../c30_resource/src/c30/resource_info.h ]; then
  C30_RESOURCE_DIR="$SRC_DIR/../c30_resource/src/c30/";
elif [ -f $SRC_DIR/../../c30_resource/src/c30/resource_info.h ]; then
  C30_RESOURCE_DIR="$SRC_DIR/../../c30_resource/src/c30/";
elif [ -f $SRC_DIR/../c30_resource/c30_resource/src/c30/resource_info.h ]; then
  C30_RESOURCE_DIR="$SRC_DIR/../c30_resource/c30_resource/src/c30/"
elif [ -f $SRC_DIR/../../c30_resource/c30_resource/src/c30/resource_info.h ]; then
  C30_RESOURCE_DIR="$SRC_DIR/../../c30_resource/c30_resource/src/c30"
else
  echo "**** cannot find c30_resource"
fi

if [ -f $SRC_DIR/../expat/configure ]; then
  EXPAT_CONFIG="$SRC_DIR/../expat/configure";
else
  echo "**** cannot find expat"
  exit 1
fi

EXE_SUFFIX=""
if ( echo $TARGET_OS | grep -q -i "native" ); then
  if ( echo $BUILD_OS | grep -q -i "cygwin" ); then
     EXE_SUFFIX=".exe"
  fi
else
  if ( echo $TARGET_OS | grep -q -i "mingw32" ); then
     EXE_SUFFIX=".exe"
  fi
fi


if [ "$TARGET_OS" = "i386-darwin" ]; then
  if ( `echo $EXTRA_CFLAGS | grep -v -q -- -arch` ); then
    echo "**** Extra C Flags for mac not set"
    echo "setting them"
    EXTRA_CFLAGS="-arch i386 -isysroot /Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.5"
  fi
fi

if [ "$TARGET_OS" = "native" -a "$BUILD_OS" != "i386-darwin" ]; then
  BUILD="$BUILD ppl"
  # catalina ?
  release_level=`uname -r | sed 's/\..*$//'`
  if [ "$release_level" -gt "17" ]; then
    # catalina is 19
    # high siera is 17 ...
    STATIC="-Wl,-lc++,-lm"
  else
    STATIC="-Wl,-lstdc++,-lm"
  fi
fi

if [ "$BUILD64" == "1" ]; then
  if [ "$NATIVE" == "mac" ]; then
    echo "*** Building for Darwin"
    BUILD_OPTION="--build=i386-apple"
    BUILD_GMP="--host=none-apple --target=none-apple"
  else
    BUILD_OPTION="--build=x86_64-${NATIVE}"
    BUILD_GMP=""
  fi
  ABI=""
else 
  BUILD_OPTION="--build=$BUILD_OS"
fi 

if ( echo $EXTRA_CFLAGS | grep -q -e "cover" ); then
  OPT=
else
  OPT="-O2"
fi

mkdir -p $WORKING_DIR/host-libs

PATH="$INSTALL_DIR/../install-native64-nolm/bin/:$PATH"
echo "PATH: $PATH"

# configure EXPAT

if ( echo $BUILD | grep -q -i expat ); then
echo
echo "*********** EXPAT"
echo 

mkdir -p expat
( cd expat

  echo $EXPAT_CONFIG ${CROSS} --prefix=$WORKING_DIR/host-libs --disable-shared  --build=$BUILD_OS
  $EXPAT_CONFIG ${CROSS} --prefix=$WORKING_DIR/host-libs --disable-shared --build=$BUILD_OS

  make -j 2 install
)
fi

# configure GMP

if ( echo $BUILD | grep -q -i gmp ); then
echo
echo "*********** GMP"
echo 

mkdir -p gmp
( cd gmp

  echo CXXFLAGS="$EXTRA_CFLAGS $OPT" CFLAGS="$EXTRA_CFLAGS $OPT" $SRC_DIR/gmp/configure ${CROSS} ${BUILD_OPTION} ${BUILD_GMP} --enable-cxx --prefix=$WORKING_DIR//host-libs --disable-shared --enable-static --disable-nls --with-gnu-ld --disable-debug --disable-rpath --enable-fft --enable-hash-synchronization --with-host-libstdcxx="-static-libgcc $STATIC" 
  CXXFLAGS="$EXTRA_CFLAGS $OPT" CFLAGS="$EXTRA_CFLAGS $OPT" $SRC_DIR/gmp/configure ${CROSS} ${BUILD_OPTION} ${BUILD_GMP} --enable-cxx --prefix=$WORKING_DIR//host-libs --disable-shared --enable-static --disable-nls --with-gnu-ld --disable-debug --disable-rpath --enable-fft --enable-hash-synchronization --with-host-libstdcxx="-static-libgcc $STATIC" 

  make -j 2 install
)
fi

if ( echo $BUILD | grep -q -i ppl ); then
echo
echo "*********** PPL"
echo 

mkdir -p ppl
( cd ppl

  if [ "$BUILD64" == "0" ]; then
  export CFLAGS=-m32
  export CXXFLAGS=-m32
  fi 
  echo CXXFLAGS="$EXTRA_CFLAGS $OPT" CFLAGS="$EXTRA_CFLAGS $OPT" $SRC_DIR/ppl/configure ${CROSS} ${BUILD_OPTION} --enable-arch=no --prefix=$WORKING_DIR//host-libs --disable-shared --enable-static --disable-nls --with-libgmp-prefix=$WORKING_DIR//host-libs --with-gmp=$WORKING_DIR//host-libs --enable-optimization=speed --disable-rpath --with-gnu-ld --with-host-libstdcxx="-static-libgcc $STATIC -lm" 

  CXXFLAGS="$EXTRA_CFLAGS $OPT" CFLAGS="$EXTRA_CFLAGS $OPT" $SRC_DIR/ppl/configure ${CROSS} ${BUILD_OPTION} --enable-arch=no --prefix=$WORKING_DIR//host-libs --disable-shared --enable-static --disable-nls --with-libgmp-prefix=$WORKING_DIR//host-libs --with-gmp=$WORKING_DIR//host-libs --enable-optimization=speed --disable-rpath --with-gnu-ld --with-host-libstdcxx="-static-libgcc $STATIC -lm" 

  make -j 2 install
)
fi

if ( echo $BUILD | grep -q -i cloog ); then
echo
echo "*********** CLOOG"
echo 

mkdir -p cloog
(
  cd cloog

  echo CXXFLAGS="$EXTRA_CFLAGS $OPT" CFLAGS="$EXTRA_CFLAGS $OPT" $SRC_DIR/cloog/configure ${CROSS} ${BUILD_OPTION} --prefix=$WORKING_DIR//host-libs --with-gmp=$WORKING_DIR//host-libs --with-ppl=$WORKING_DIR//host-libs --enable-static --disable-shared --with-bits=gmp --disable-rpath --with-gnu-ld --with-host-libstdcxx="$STATIC" 
  CXXFLAGS="$EXTRA_CFLAGS $OPT" CFLAGS="$EXTRA_CFLAGS $OPT" $SRC_DIR/cloog/configure ${CROSS} ${BUILD_OPTION} --prefix=$WORKING_DIR//host-libs --with-gmp=$WORKING_DIR//host-libs --with-ppl=$WORKING_DIR//host-libs --enable-static --disable-shared --with-bits=gmp --disable-rpath --with-gnu-ld --with-host-libstdcxx="$STATIC" 

  make -j 2 install
)
fi

if ( echo $BUILD | grep -q -i libelf ); then
echo
echo "*********** LIBELF"
echo 

mkdir -p libelf 
(
  # does this need to be our libelf?

  cd libelf

  echo CXXFLAGS="$EXTRA_CFLAGS $OPT" CFLAGS="$EXTRA_CFLAGS $OPT" $SRC_DIR/libelf/configure ${CROSS} ${BUILD_OPTION} --prefix=$WORKING_DIR//host-libs -disable-shared --disable-nls --disable-debug 
  CXXFLAGS="$EXTRA_CFLAGS $OPT" CFLAGS="$EXTRA_CFLAGS $OPT" $SRC_DIR/libelf/configure ${CROSS} ${BUILD_OPTION} --prefix=$WORKING_DIR//host-libs -disable-shared --disable-nls --disable-debug 

  make -j 2 install
)
fi

if ( echo $BUILD | grep -q -i zlib ); then
echo
echo "*********** ZLIB"
echo 

mkdir -p zlib
(
  cd $SRC_DIR/zlib/

  echo ./configure --prefix=$WORKING_DIR//host-libs
  ./configure --prefix=$WORKING_DIR//host-libs

  make clean
  # note to self: I think the configure will now set AR=,CC= and such for me

  # if [ "$CROSS" != "" ]; then
    if [ "$RANLIB" != "" -a "$AR" != "" -a "$CC" != "" ]; then
      # use the environment
      make -e CFLAGS="$EXTRA_CFLAGS $OPT" LDSBARED="${CC}" prefix=$WORKING_DIR//host-libs install
    else
      make CFLAGS="$EXTRA_CFLAGS $OPT" RANLIB="${ZLIB_TOOLS}-ranlib" LDSBARED="${ZLIB_TOOLS}-gcc" AR="${ZLIB_TOOLS}-ar" CC="${ZLIB_TOOLS}-gcc"  prefix=$WORKING_DIR//host-libs install
    fi
  # else
  #   make install
  # fi

)
fi

if [ $SUFFIX == "-xclm" ] || [ $SUFFIX == "-fusa" ] || [ $SUFFIX == "-exlm" ]; then
  XCLM_DIR=`find $SRC_DIR/../xclm-release -iname xclm_public.h -exec dirname {} \;`
  if [ ! -f "$XCLM_DIR/xclm_public.h" ]; then
    echo "**** cannot find dir containing xclm_public.h"
    exit 1
  fi
  XCLM_DIR="-I $XCLM_DIR"
else
  echo "**** not building with XCLM"
fi

  
if ( echo $BUILD | grep -q -i gcc ); then
echo
echo "*********** GCC"
echo 

mkdir -p gcc
(
  cd gcc

  if [ -d $C30_RESOURCE_DIR ]; then
    EXTRA_OPTS="$EXTRA_OPTS -I $C30_RESOURCE_DIR"
  else
    echo "***** cannot find c30_resource"
    exit 1
  fi

  case $SUFFIX in
    "-nolm") ;;
  esac

  DWARF=""
  if [ "$OMF" = "elf" ]; then
    DWARF="--with-dwarf2"
  fi

  echo "{"
  echo "  CXXFLAGS=\"$EXTRA_CFLAGS $OPT\" GCC_FOR_TARGET='pic30-gcc' CC_FOR_TARGET='pic30-gcc' AS_FOR_TARGET=$INSTALL_DIR/../install-native64-nolm/bin/xc16-as LD_FOR_TARGET=$INSTALL_DIR/../install-native64-nolm/bin/xc16-ld CFLAGS=\"$EXTRA_CFLAGS $OPT -DLONG_MODIFIER -D_BUILD_C30_ -D_BUILD_MCHP_ ${EXTRA_OPTS} ${EXTRA_DEFINES}\" $SRC_DIR/gcc/configure ${CROSS} ${BUILD_OPTION} --enable-coverage --target=pic30-$OMF $LTO --disable-threads --disable-libmudflap --disable-libssp --disable-libstdcxx-pch --disable-hosted-libstdcxx --with-gnu-as --with-gnu-ld --enable-languages=c --disable-nls --disable-libgomp --without-headers --disable-libffi --disable-bootstrap --prefix=${INSTALL}/bin --libexecdir=${INSTALL}/bin --program-prefix=pic30- --with-libelf=${WORKING_DIR}/host-libs/ $DWARF --with-gmp=$WORKING_DIR/host-libs --with-ppl=$WORKING_DIR/host-libs --with-cloog=$WORKING_DIR/host-libs --with-zlib=$WORKING_DIR/host-libs --with-bugurl=\"${BUGURL}\" --with-host-libstdcxx=\"$STATIC\" "
  echo "}"

  CXXFLAGS="$EXTRA_CFLAGS $OPT" GCC_FOR_TARGET='pic30-gcc' CC_FOR_TARGET='pic30-gcc' AS_FOR_TARGET=$INSTALL_DIR/../install-native64-nolm/bin/xc16-as LD_FOR_TARGET=$INSTALL_DIR/../install-native64-nolm/bin/xc16-ld CFLAGS="$EXTRA_CFLAGS $OPT -DLONG_MODIFIER -D_BUILD_C30_ -D_BUILD_MCHP_ ${EXTRA_OPTS} ${EXTRA_DEFINES}" $SRC_DIR/gcc/configure ${CROSS} ${BUILD_OPTION} --target=pic30-$OMF $LTO --disable-threads --disable-libmudflap --disable-libssp --disable-libstdcxx-pch --disable-hosted-libstdcxx --with-gnu-as --with-gnu-ld --enable-languages=c --disable-nls --disable-libgomp --without-headers --disable-libffi --disable-bootstrap --prefix=${INSTALL}/bin --libexecdir=${INSTALL}/bin --program-prefix=pic30- --with-libelf=${WORKING_DIR}/host-libs/ $DWARF --with-gmp=$WORKING_DIR/host-libs --with-ppl=$WORKING_DIR/host-libs --with-cloog=$WORKING_DIR/host-libs --with-zlib=$WORKING_DIR/host-libs --with-bugurl="${BUGURL}" --with-host-libstdcxx="$STATIC"
  
  make 
  )
fi


if ( echo $BUILD | grep -q -i g++ ); then
echo
echo "*********** G++"
echo 

mkdir -p gcc
(
  cd gcc

  if [ -d $C30_RESOURCE_DIR ]; then
    EXTRA_OPTS="$EXTRA_OPTS -I $C30_RESOURCE_DIR"
  else
    echo "***** cannot find c30_resource"
    exit 1
  fi

  case $SUFFIX in
    "-nolm") ;;
  esac

  DWARF=""
  if [ "$OMF" = "elf" ]; then
    DWARF="--with-dwarf2"
  fi

  echo "{"
  echo "  CXXFLAGS=\"$EXTRA_CFLAGS $OPT\" GCC_FOR_TARGET='pic30-gcc' CC_FOR_TARGET='pic30-gcc' AS_FOR_TARGET=$INSTALL_DIR/../install-native64-nolm/bin/xc16-as LD_FOR_TARGET=$INSTALL_DIR/../install-native64-nolm/bin/xc16-ld CFLAGS=\"$EXTRA_CFLAGS $OPT -DLONG_MODIFIER -D_BUILD_C30_ -D_BUILD_MCHP_ ${EXTRA_OPTS} ${EXTRA_DEFINES}\" $SRC_DIR/gcc/configure ${CROSS} ${BUILD_OPTION} --enable-coverage --target=pic30-$OMF $LTO --disable-threads --disable-libmudflap --disable-libssp --disable-libstdcxx-pch --disable-hosted-libstdcxx --with-gnu-as --with-gnu-ld --enable-languages=c,c++ --disable-nls --disable-libgomp --without-headers --disable-libffi --disable-bootstrap --prefix=${INSTALL}/bin --libexecdir=${INSTALL}/bin --program-prefix=pic30- --with-libelf=${WORKING_DIR}/host-libs/ $DWARF --with-gmp=$WORKING_DIR/host-libs --with-ppl=$WORKING_DIR/host-libs --with-cloog=$WORKING_DIR/host-libs --with-zlib=$WORKING_DIR/host-libs --with-bugurl=\"${BUGURL}\" --with-host-libstdcxx=\"$STATIC\" "
  echo "}"

  CXXFLAGS="$EXTRA_CFLAGS $OPT" GCC_FOR_TARGET='pic30-gcc' CC_FOR_TARGET='pic30-gcc' AS_FOR_TARGET=$INSTALL_DIR/../install-native64-nolm/bin/xc16-as LD_FOR_TARGET=$INSTALL_DIR/../install-native64-nolm/bin/xc16-ld CFLAGS="$EXTRA_CFLAGS $OPT -DLONG_MODIFIER -D_BUILD_C30_ -D_BUILD_MCHP_ ${EXTRA_OPTS} ${EXTRA_DEFINES}" $SRC_DIR/gcc/configure ${CROSS} ${BUILD_OPTION} --target=pic30-$OMF $LTO --disable-threads --disable-libmudflap --disable-libssp --disable-libstdcxx-pch --disable-hosted-libstdcxx --with-gnu-as --with-gnu-ld --enable-languages=c,c++ --disable-nls --disable-libgomp --without-headers --disable-libffi --disable-bootstrap --prefix=${INSTALL}/bin --libexecdir=${INSTALL}/bin --program-prefix=pic30- --with-libelf=${WORKING_DIR}/host-libs/ $DWARF --with-gmp=$WORKING_DIR/host-libs --with-ppl=$WORKING_DIR/host-libs --with-cloog=$WORKING_DIR/host-libs --with-zlib=$WORKING_DIR/host-libs --with-bugurl="${BUGURL}" --with-host-libstdcxx="$STATIC"

  make 
  )
fi


# install it

if [ "$INSTALL_DIR" != "" ]; then
  echo
  echo "**** Installing GCC"
  echo
  
  mkdir -p $INSTALL_DIR/bin/bin/

  EXE=
  if [ "$TARGET_OS" = "mingw32" ]; then
    EXE=".exe"
  fi

  if [ -f gcc/gcc/xgcc${EXE} ]; then
    cp -v gcc/gcc/xgcc${EXE}  $INSTALL_DIR/bin/bin/$OMF-gcc${EXE}
  fi

  if [ -f gcc/gcc/g++${EXE} ]; then
    cp -v gcc/gcc/g++${EXE}  $INSTALL_DIR/bin/bin/$OMF-g++${EXE}
  fi

  if [ -f gcc/gcc/cc1${EXE} ]; then
    cp -v gcc/gcc/cc1${EXE}  $INSTALL_DIR/bin/bin/$OMF-cc1${EXE}
  fi

  if [ -f gcc/gcc/cc1plus${EXE} ]; then
    cp -v gcc/gcc/cc1plus${EXE}  $INSTALL_DIR/bin/bin/$OMF-cc1plus${EXE}
  fi

  if [ -f gcc/gcc/cpp${EXE} ]; then
    cp -v gcc/gcc/cpp${EXE}  $INSTALL_DIR/bin/bin/$OMF-cpp${EXE}
  fi
fi
