# This file is a shell script fragment that supplies the information
# necessary for a configure script to process the program in
# this directory.  For more information, look at ../configure.

# If the language specific compiler does not exist, but the "gcc" directory 
# does, we do not build anything. Note, $r is set by the top-level Makefile.
# Note that when we look for the compiler, we search both with and without
# extension to handle cross and canadian cross builds. 
# Note that if $norecursion is set we're being called from config.status,
# so don't check for the compiler; we might be doing a make clean.
compiler_name=cc1plus
rm -f skip-this-dir
if test -n "$r" && [ -z "$norecursion" ] ; then
  if test -d "$r"/gcc; then
    if test -f "$r"/gcc/$compiler_name \
       || test -f "$r"/gcc/$compiler_name.exe; then
      true
    else
      echo "rm -f multilib.out" > skip-this-dir
    fi
  fi
fi

if [ "${srcdir}" = "." ] ; then
  if [ "${with_target_subdir}" != "." ] ; then
    topsrcdir=${with_multisrctop}../..
  else
    topsrcdir=${with_multisrctop}..
  fi
else
  topsrcdir=${srcdir}/..
fi

if [ -d ${topsrcdir}/gcc ] ; then
  configdirs="tests testsuite"
else
  configdirs="tests"
fi
srctrigger=sinst.cc
srcname="ANSI C++ library"
package_makefile_frag=Make.pack
package_makefile_rules_frag=Make.pack.r

# per-host:

# per-target:

echo "# Warning: this fragment is automatically generated" > temp.mt
frags=

# If they didn't specify --enable-shared, don't generate shared libs.
case "${enable_shared}" in
  yes) shared=yes ;;
  no) shared=no ;;
  *libstdc++*) shared=yes ;;
  *) shared=no ;;
esac

if [ "${shared}" = "yes" ]; then
  case "${target}" in
    alpha*-*-linux*)	frags=../../config/mh-elfalphapic ;;
    arm*-*-*)		frags=../../config/mh-armpic ;;
    hppa*-*-*)		frags=../../config/mh-papic ;;
    i[3456]86-*-*)	frags=../../config/mh-x86pic ;;
    powerpc*-*-aix*)	;;
    powerpc*-*-*)	frags=../../config/mh-ppcpic ;;
    *-*-*) 		frags=../../config/mh-${target_cpu}pic ;;
  esac
  case "${target}" in
    *-dec-osf*)		frags="${frags} dec-osf.ml";;
    *-*-hpux*)		frags="${frags} hpux.ml" ;;
    *-*-irix[56]*)	frags="${frags} irix5.ml" ;;
    *-*-linux*aout*)	;;
    *-*-freebsd2*)	;;
    *-*-freebsd*)	frags="${frags} freebsd.ml" ;;
    *-*-linux*)		frags="${frags} linux.ml" ;;
    *-*-openbsd*)		frags="${frags} openbsd.ml" ;;
    *-*-sysv[45]*|*-*-udk*)	frags="${frags} elf.ml" ;;
    *-*-solaris*)	frags="${frags} sol2shm.ml" ;;
    *-*-sunos4*)	frags="${frags} sunos4.ml" ;;
    *-*-aix*)		frags="${frags} aix.ml" ;;
    i[3456]86-*-interix*)	frags="${frags} x86-interix.ml" ;;
    *-*-gnu*)		frags="${frags} gnu.ml" ;;
  esac
fi

# Make sure the right flags are defined for multi-threading.
case "${target}" in
  alpha*-*-linux-gnulibc1)	frags="${frags} linux.mt" ;;
  powerpc*-*-linux-gnulibc1)	frags="${frags} linux.mt" ;;
  *-*-linux-gnu)		frags="${frags} linux.mt" ;;
  *-*-openbsd*)		
  	case "x${enable_threads}" in
		xyes|xposix)	frags="${frags} openbsd.mt" ;;
	esac;;
  m68k-motorola-sysv)		frags="${frags} delta.mt" ;;
  *-*-solaris*)
    case "x${enable_threads}" in
      xposix)			frags="${frags} sol2pth.mt" ;;
      xsolaris)			frags="${frags} sol2solth.mt" ;;
    esac ;;
  *)
    case "x${enable_threads}" in
      xposix)			frags="${frags} posix.mt" ;;
    esac ;;
esac

for frag in ${frags}; do
  case ${frag} in
    ../* )
      if [ ${srcdir} = . ]; then
	[ -n "${with_target_subdir}" ] && frag=../${frag}
	[ -n "${with_multisrctop}" ] && frag=${with_multisrctop}${frag}
      fi
      ;;
  esac
  frag=${srcdir}/config/$frag
  if [ -f ${frag} ]; then
    echo "Appending ${frag} to target-mkfrag"
    echo "# Following fragment copied from ${frag}" >> temp.mt
    cat ${frag} >> temp.mt
  fi
done

target_makefile_frag=target-mkfrag
${moveifchange} temp.mt target-mkfrag

LIBDIR=yes
TO_TOPDIR=../
ALL='libs'
XCXXINCLUDES="-I${srcdir} -I${srcdir}/stl -I${TO_TOPDIR}libio -I${srcdir}/${TO_TOPDIR}libio"
MOSTLYCLEAN='*.o pic stamp-picdir core so_locations $(MOSTLYCLEAN_JUNK)'
CLEAN='$(CLEAN_JUNK)'
EXTRA_DISTCLEAN='target-mkfrag'

(. ${srcdir}/${TO_TOPDIR}libio/config.shared) >${package_makefile_frag} 2>${package_makefile_rules_frag}

. ${topsrcdir}/config.if
echo "
LIBSTDCXX_INTERFACE=${libstdcxx_interface}
CXX_INTERFACE=${cxx_interface}
LIBC_INTERFACE=${libc_interface}
" >> ${package_makefile_frag}

# This duplicated the AC_PROG_LN_S macro in GNU autoconf.
rm -f conttestdata
if ln -s X conftestdata 2>/dev/null
then
  rm -f conftestdata
  LN_S="ln -s"
else
  LN_S=ln
fi
echo "
LN_S=$LN_S
" >> ${package_makefile_frag}

# post-target:

# If cross-compiling, we install in $(tooldir)/lib or in $(libsubdir)
# depending on --enable-version-specific-runtime-libs.
if [ -n "${with_cross_host}" ] ; then
    rm -f Makefile.tem
    sed \
        -e 's|^\([ 	]*INSTALLDIR[ 	]*=[ 	]*\)\$(libdir)|\1$(tooldir)/lib|' \
        Makefile >Makefile.tem
    mv -f Makefile.tem Makefile
fi

# enable multilib-ing by default.
if [ -z "${enable_multilib}" ]; then
    enable_multilib=yes
fi

. ${topsrcdir}/config-ml.in

gxx_include_dir=
# Specify the g++ header file directory
# Check whether --with-gxx-include-dir or --without-gxx-include-dir was given.
if test "${with_gxx_include_dir+set}" = set; then
  withval="$with_gxx_include_dir"
  case "${withval}" in
    yes)
      echo "configure.in: error: bad value ${withval} given for g++ include directory" 1>&2
      exit 1
      ;;
    no)	;;
    *)	gxx_include_dir=$with_gxx_include_dir ;;
  esac
fi

if test x${gxx_include_dir} = x; then
  if test x${enable_version_specific_runtime_libs} = xyes; then
    gxx_include_dir='${libsubdir}/include/g++'
  else
    gxx_include_dir='${prefix}/include/g++'-${libstdcxx_interface}
  fi
fi

rm -f Makefile.tem
sed -e "s%^gxx_include_dir[ 	]*=.*$%gxx_include_dir=${gxx_include_dir}%" \
       Makefile >Makefile.tem
mv -f Makefile.tem Makefile
