#! /bin/sh

# configure
# Copyright 1984-2017 Cisco Systems, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# source directory, as opposed to the build directory (= current directory)
srcdir=`dirname "$0"`

# gather available machine names from source directory
machs=""; last=""; sep0=""; sep1=""; sep2=""; sep3=""; sep4=" and ";
for fn in "$srcdir"/boot/*/scheme.boot ; do
    next=`echo $fn | sed -e 's/.*\/boot\/\(.*\)\/scheme.boot/\1/'`
    if [ "$next" != '*' ] ; then
        machs=$machs$sep0$last
        last=$next
        sep0=$sep1; sep1=", "; sep2=$sep3; sep3=$sep4; sep4=", and "
    fi
done
# maybe gather additional available machine names from build directory
if [ "$srcdir" != "." ]; then
    for fn in boot/*/scheme.boot ; do
        next=`echo $fn | sed -e 's/boot\/\(.*\)\/scheme.boot/\1/'`
        if [ "$next" != '*' ] ; then
            machs=$machs$sep0$last
            last=$next
            sep0=$sep1; sep1=", "; sep2=$sep3; sep3=$sep4; sep4=", and "
        fi
    done
fi
machs=$machs$sep2$last

if [ "${CFLAGS}" != "" ] ; then
    cflagsset=yes
elif [ "${CFLAGS-default}" = "" ] ; then
    cflagsset=yes
else
    cflagsset=no    
fi

# Machine type to build:
m=""

# Working directory, defaults to $m
w=""

# Machine describing the OS that the kernel runs on, so it determines
# default compiler and linker flags; when $m is a pb variant, then
# this OS is inferred if not specified with `--osmachine=`
flagsm=""

# Used to select a default $m, but in the end corresponds to
# the target machine for boot files when built via pb
defaultm=""

pb=no
pbarch=no
threads=yes
nothreads=no
libffi=no
temproot=""
help=no
forceworkarea=no
gzipmanpages=yes
installowner=""
installgroup=""
installbin=""
installlib=""
installman=""
installdoc=""
installcsug=""
installreleasenotes=""
installschemename="scheme"
installpetitename="petite"
installscriptname="scheme-script"
unamebits=""
relativeBootFiles=yes
disablex11=no
disablecurses=no
disableiconv=no
addflags=yes
addwarningflags=no
default_warning_flags="-Wpointer-arith -Wall -Wextra -Wno-implicit-fallthrough"
: ${CC:="gcc"}
: ${CPPFLAGS:=""}
: ${CFLAGS:=""}
: ${LD:="ld"}
: ${LDFLAGS:=""}
: ${LIBS:=""}
: ${AR:="ar"}
: ${ARFLAGS:="rc"}
: ${RANLIB:="ranlib"}
: ${WINDRES:="windres"}
: ${STRIP:="strip"}
CFLAGS_ADD=
zlibLib=
LZ4Lib=
STEXLIB=
Kernel=KernelLib
buildKernelOnly=no
enableFrompb=yes
pbendian=l
emscripten=no
empetite=no
crossCompile=no
moreBootFiles=
preloadBootFiles=
alwaysUseBootFile=
skipSubmoduleUpdate=
skipImmediateMakefile=
zuoExternal=

CONFIG_UNAME=`uname`

# using `uname`, infer OS-based defaults
case "${CONFIG_UNAME}" in
  Linux)
    if command -v lscpu > /dev/null 2>&1; then
      if lscpu | egrep -i 'Byte Order.*Big Endian' > /dev/null 2>&1 ; then
        pbendian=b
      fi
    fi
    if command -v getconf > /dev/null 2>&1; then
      unamebits=`getconf LONG_BIT`
    fi
    unixsuffix=le
    installprefix=/usr
    installmansuffix=share/man
    ;;
  GNU)
    unixsuffix=gnu # the Hurd
    installprefix=/usr
    installmansuffix=share/man
    ;;
  QNX)
    if uname -m | egrep 'x86' > /dev/null 2>&1 ; then
      m32=i3qnx
      tm32=ti3qnx
    fi
    installprefix=/usr/local
    installmansuffix=man
    ;;
  FreeBSD|DragonFly)
    unixsuffix=fb
    installprefix=/usr/local
    installmansuffix=man
    ;;
  OpenBSD)
    unixsuffix=ob
    installprefix=/usr/local
    installmansuffix=man
    ;;
  NetBSD)
    unixsuffix=nb
    installprefix=/usr
    installmansuffix=share/man
    gzipmanpages=no
    ;;
  Darwin)
    if uname -m | egrep 'i386|i686|amd64|athlon|x86_64' > /dev/null 2>&1 ; then
      m32=i3osx
      m64=a6osx
      tm32=ti3osx
      tm64=ta6osx
    elif uname -m | egrep 'arm|aarch' > /dev/null 2>&1 ; then
      m64=arm64osx
      tm64=tarm64osx
    elif uname -m | egrep 'Power' > /dev/null 2>&1 ; then
      m32=ppc32osx
      tm32=tppc32osx
      pbendian=b
      default_warning_flags=""
    fi
    installprefix=/usr/local
    installmansuffix=share/man
    ;;
  SunOS)
    if uname -m | egrep 'i386|i686|amd64|athlon|x86_64' > /dev/null 2>&1 ; then
      m32=i3s2
      m64=a6s2
      tm32=ti3s2
      tm64=ta6s2
      installprefix=/usr
      installmansuffix=share/man
      gzipmanpages=no
    fi
    ;;
  MINGW*)
    # MSYS2 (but not $MSYSTEM as "MSYS", because Cygwin is not currently supported)
    case "$MSYSTEM" in
        *ARM64*)
            m64=arm64nt
            tm64=tarm64nt
            ;;
        *)
            m32=i3nt
            m64=a6nt
            tm32=ti3nt
            tm64=ta6nt
            ;;
    esac
    # `uname -m` will report the way that `uname` is compiled, but we want
    # to infer bits based on "$MSYSTEM", so override `uname -m` for bits
    case "$MSYSTEM" in
        *32)
            unamebits=32
            ;;
        *)
            unamebits=64
            ;;
    esac
    installprefix=/usr/local
    installmansuffix=share/man
    ;;
esac

unknownm=no

# using `uname`, infer architecture-based defaults to refine OS defaults
if [ "$unixsuffix" != "" ] ; then
    if uname -m | egrep 'i386|i686|amd64|athlon|x86_64' > /dev/null 2>&1 ; then
        m32=i3${unixsuffix}
        m64=a6${unixsuffix}
        tm32=ti3${unixsuffix}
        tm64=ta6${unixsuffix}
    elif uname -m | egrep 'power|ppc' > /dev/null 2>&1 ; then
        m32=ppc32${unixsuffix}
        tm32=tppc32${unixsuffix}
        m64=ppc64${unixsuffix}
        tm64=tppc64${unixsuffix}
        if uname -m | egrep 'ppc64le' > /dev/null 2>&1 ; then
            pbendian=l
        else
            pbendian=b
        fi
    elif uname -m | egrep 'armv|aarch64|arm64|evbarm' > /dev/null 2>&1 ; then
        m32=arm32${unixsuffix}
        m64=arm64${unixsuffix}
        tm32=tarm32${unixsuffix}
        tm64=tarm64${unixsuffix}
    elif uname -m | grep 'riscv64' > /dev/null 2>&1 ; then
        m32=""
        m64=rv64${unixsuffix}
        tm32=""
        tm64=trv64${unixsuffix}
    elif uname -m | grep 'loongarch64' > /dev/null 2>&1 ; then
        m32=""
        m64=la64${unixsuffix}
        tm32=""
        tm64=tla64${unixsuffix}
    else
        # using "unknown" helps at least select OS-based flags
        m32=unknown32${unixsuffix}
        m64=unknown64${unixsuffix}
        tm32=tunknown32${unixsuffix}
        tm64=tunknown64${unixsuffix}
        unknownm=yes
    fi
fi

threads=""
bits=""

while [ $# != 0 ] ; do
  case $1 in
    -m=*)
      m=`echo $1 | sed -e 's/^-m=//'`
      ;;
    --machine=*)
      m=`echo $1 | sed -e 's/^--machine=//'`
      ;;
    --os=*)
      flagsm=`echo $1 | sed -e 's/^--os=//'`
      ;;
    --boot=*)
      mboot=`echo $1 | sed -e 's/^--boot=//'`
      ;;
    --threads)
      threads=yes
      ;;
    --nothreads)
      threads=no
      ;;
    --64)
      bits=64
      ;;
    --32)
      bits=32
      ;;
    --pb)
      pb=yes
      ;;
    --pbarch)
      pbarch=yes
      ;;
    --emscripten)
      emscripten=yes
      CC_FOR_BUILD="${CC}"
      CC="emcc"
      LD="emld"
      AR="emar"
      RANLIB="emranlib"
      ;;
    --force)
      forceworkarea=yes
      enableFrompb=no
      ;;
    --as-is)
      skipSubmoduleUpdate=yes
      ;;
    --nomakefile)
      skipImmediateMakefile=yes
      ;;
    --installprefix=*)
      installprefix=`echo $1 | sed -e 's/^--installprefix=//'`
      ;;
    --prefix=*)
      installprefix=`echo $1 | sed -e 's/^--prefix=//'`
      ;;
    --installlib=*)
      installlib=`echo $1 | sed -e 's/^--installlib=//'`
      ;;
    --installbin=*)
      installbin=`echo $1 | sed -e 's/^--installbin=//'`
      ;;
    --installman=*)
      installman=`echo $1 | sed -e 's/^--installman=//'`
      ;;
    --installdoc=*)
      installdoc=`echo $1 | sed -e 's/^--installdoc=//'`
      ;;
    --installcsug=*)
      installcsug=`echo $1 | sed -e 's/^--installcsug=//'`
      ;;
    --installreleasenotes=*)
      installreleasenotes=`echo $1 | sed -e 's/^--installreleasenotes=//'`
      ;;
    --installowner=*)
      installowner=`echo $1 | sed -e 's/^--installowner=//'`
      ;;
    --installgroup=*)
      installgroup=`echo $1 | sed -e 's/^--installgroup=//'`
      ;;
    --installschemename=*)
      installschemename=`echo $1 | sed -e 's/^--installschemename=//'`
      ;;
    --installpetitename=*)
      installpetitename=`echo $1 | sed -e 's/^--installpetitename=//'`
      ;;
    --installscriptname=*)
      installscriptname=`echo $1 | sed -e 's/^--installscriptname=//'`
      ;;
    --installabsolute)
      relativeBootFiles=no
      ;;
    --toolprefix=*)
      toolprefix=`echo $1 | sed -e 's/^--toolprefix=//'`
      CC="${toolprefix}${CC}"
      LD="${toolprefix}${LD}"
      AR="${toolprefix}${AR}"
      RANLIB="${toolprefix}${RANLIB}"
      WINDRES="${toolprefix}${WINDRES}"
      STRIP="${toolprefix}${STRIP}"
      ;;
    --gzip-man-pages)
      gzipmanpages=yes
      ;;
    --nogzip-man-pages)
      gzipmanpages=no
      ;;
    --temproot=*)
      temproot=`echo $1 | sed -e 's/^--temproot=//'`
      ;;
    --workarea=*)
      w=`echo $1 | sed -e 's/^--workarea=//'`
      ;;
    --help)
      help=yes
      ;;
    --disable-x11)
      disablex11=yes
      ;;
    --disable-curses)
      disablecurses=yes
      ;;
    --disable-iconv)
      disableiconv=yes
      ;;
    --enable-libffi)
      libffi=yes
      ;;
    --disable-auto-flags)
      addflags=no
      ;;
    --enable-warning-flags)
      addwarningflags=yes
      ;;
    --libkernel)
      Kernel=KernelLib
      ;;
    --kernelobj)
      Kernel=KernelO
      ;;
    --emboot=*)
      bootfilenames=`echo $1 | sed -e 's/^--emboot=//'`
      moreBootFiles="${moreBootFiles} ${bootfilenames}"
      ;;
    --empetite)
      empetite=yes
      ;;
    --cross)
      crossCompile=yes
      ;;
    --start=*)
      alwaysUseBootFile=`echo $1 | sed -e 's/^--start=//'`
      ;;
    CC=*)
      CC=`echo $1 | sed -e 's/^CC=//'`
      ;;
    CPPFLAGS=*)
      CPPFLAGS=`echo $1 | sed -e 's/^CPPFLAGS=//'`
      ;;
    CPPFLAGS+=*)
      CPPFLAGS="$CPPFLAGS "`echo $1 | sed -e 's/^CPPFLAGS+=//'`
      ;;
    CFLAGS=*)
      CFLAGS=`echo $1 | sed -e 's/^CFLAGS=//'`
      cflagsset=yes
      ;;
    CFLAGS+=*)
      CFLAGS_ADD="$CFLAGS_ADD "`echo $1 | sed -e 's/^CFLAGS+=//'`
      ;;
    CC_FOR_BUILD=*)
      CC_FOR_BUILD=`echo $1 | sed -e 's/^CC_FOR_BUILD=//'`
      ;;
    CFLAGS_FOR_BUILD=*)
      CFLAGS_FOR_BUILD=`echo $1 | sed -e 's/^CFLAGS_FOR_BUILD=//'`
      ;;
    LD=*)
      LD=`echo $1 | sed -e 's/^LD=//'`
      ;;
    LDFLAGS=*)
      LDFLAGS=`echo $1 | sed -e 's/^LDFLAGS=//'`
      ;;
    LDFLAGS+=*)
      LDFLAGS=`echo $1 | sed -e 's/^LDFLAGS+=//'`
      ;;
    LIBS=*)
      LIBS=`echo $1 | sed -e 's/^LIBS=//'`
      ;;
    LIBS+=*)
      LIBS="${LIBS} "`echo $1 | sed -e 's/^LIBS+=//'`
      ;;
    AR=*)
      AR=`echo $1 | sed -e 's/^AR=//'`
      ;;
    ARFLAGS=*)
      ARFLAGS=`echo $1 | sed -e 's/^ARFLAGS=//'`
      ;;
    RANLIB=*)
      RANLIB=`echo $1 | sed -e 's/^RANLIB=//'`
      ;;
    WINDRES=*)
      WINDRES=`echo $1 | sed -e 's/^WINDRES=//'`
      ;;
    STRIP=*)
      STRIP=`echo $1 | sed -e 's/^STRIP=//'`
      ;;
    ZLIB=*)
      zlibLib=`echo $1 | sed -e 's/^ZLIB=//'`
      ;;
    LZ4=*)
      LZ4Lib=`echo $1 | sed -e 's/^LZ4=//'`
      ;;
    STEXLIB=*)
      STEXLIB=`echo $1 | sed -e 's/^STEXLIB=//'`
      ;;
    ZUO=*)
      zuoExternal=`echo $1 | sed -e 's/^ZUO=//'`
      ;;
    *)
      echo "option '$1' unrecognized or missing an argument; try $0 --help"
      exit 1
      ;;
  esac
  shift
done

if [ $pbarch = yes ] ; then
    pb=yes
fi

if [ $emscripten = yes ] ; then
    pb=yes
    bits=32
    if [ "$m" != "" ] ; then
        echo "Don't combine --emscripten with -m or --machine"
        exit 1
    fi
    m32=pb32l
    tm32=tpb32l
fi

if [ "$bits" = "" ] ; then
  # infer default bits; this will be irrelevant if a machine is specified
  if [ "$unamebits" != "" ] ; then
    bits="$unamebits"
  elif uname -m | egrep 'amd64|x86_64|aarch64|arm64|ppc64|powerpc64|riscv64|loongarch64' > /dev/null 2>&1 ; then
    bits=64
  # NetBSD `uname -m` produces "evbarm" for AArch64
  elif uname -p | egrep 'aarch64' > /dev/null 2>&1 ; then
    bits=64
  else
    bits=32
  fi
fi

# for pb (and not pbarch), most flags select options for the host
# platform (i.e., for compiling kernel), but `--threads` doubles
# as selection of both the platform and tpb; defaultthreads refers
# to the host platform's threadedness, and we want that to default
# the same way as when `--pb` is not used
if [ "$threads" = "" ] ; then
    case "$m" in
        pb*)
            defaultthreads=no
            ;;
        *)
            defaultthreads=yes
            ;;
    esac
else
    defaultthreads=$threads
fi

# if both machine and threadedness are supplied, check consistency,
# mostly so a selection of pb vs tpb is consistent with the host
if [ "$m" != "" ] ; then
   case "${m}" in
       t*)
           if [ "$threads" = "no" ] ; then
               echo "Machine $m is incompatible with --nothreads"
               exit 1
           fi
            ;;
        *)
           if [ "$threads" = "yes" ] ; then
               echo "Machine $m is incompatible with --threads"
               exit 1
           fi
           ;;
    esac
fi

# infer host machine (in case not specified) from bits and OS/arch;
# it's possible that defaultm will end up as empty
if [ $bits = 64 ] ; then
  if [ $defaultthreads = yes ] ; then defaultm=$tm64 ; else defaultm=$m64 ; fi
else
  if [ $defaultthreads = yes ] ; then defaultm=$tm32 ; else defaultm=$m32 ; fi
fi

if [ "$m" = "" ] ; then
  machine_supplied=no
  if [ $pb = yes ] ; then
     m=pb
     if [ $bits = 64 ] ; then defaultflagsm=$m64 ; else defaultflagsm=$m32 ; fi
     if [ "$defaultflagsm" = "" ] ; then
         defaultflagsm=unknown
     fi
     if [ "$threads" = yes ] ; then
         m=t$m
         defaultflagsm=t$defaultflagsm
     fi
  else
    if [ "$unknownm" != "yes" ] ; then
        m=$defaultm
    fi
    defaultflagsm=$defaultm
    # note that m (and defaultflagsm) could still be "" at this point, in which
    # case "No suitable machine type" will be reported further below
  fi
elif [ $pb = yes ] ; then
  defaultflagsm=$m
  m=pb
else
  case "${m}" in
      pb*|tpb*)
          defaultflagsm=$defaultm
          ;;
      *)
          defaultflagsm=$m
  esac
  defaultm=$m
fi

if [ $pbarch = yes ] ; then
    m=pb$bits$pbendian
    if [ "$defaultthreads" = yes ] ; then
        m=t$m
        defaultflagsm=t$defaultflagsm
    fi
fi

if [ "$flagsm" = "" ] ; then
    flagsm=$defaultflagsm
fi

if [ "$mboot" = "" ] ; then
    mboot="$m"
else
    magain=`echo $mboot | sed -e 's/-.*//'`
    if [ "$m" != "$magain" ]; then
        echo "Machine $m is not consistent with boot directory $magain"
        exit 1
    fi
    buildKernelOnly=yes
fi

if [ "$w" = "" ] ; then
    if [ $emscripten = yes ] ; then
        w=em-$mboot
    else
        w=$mboot
    fi
fi

if [ "$installbin" = "" ] ; then
  installbin=$installprefix/bin
fi

if [ "$installlib" = "" ] ; then
  installlib=$installprefix/lib
fi

if [ "$installman" = "" ] ; then
  installman=$installprefix/$installmansuffix
fi

if [ "$installdoc" = "" ] ; then
  installdoc=$installprefix/share/doc
fi

if [ "$installcsug" = "" ] ; then
  installcsug=$installdoc/csug10.1.0
fi

if [ "$installreleasenotes" = "" ] ; then
  installreleasenotes=$installdoc/csv10.1.0
fi

if [ "$help" = "yes" ]; then
  echo "Purpose:"
  echo "  $0 determines the machine type and constructs a custom Makefile"
  echo "  taking into account the options below."
  echo ""
  echo "Options (defaults shown in parens):"
  echo "  --machine=<machine type>          explicitly specify machine type ($m)"
  echo "  -m=<machine type>                 same as --machine=<machine type> ($m)"
  echo "  --os=<machine type>               specify OS as a machine type ($flagsm)"
  echo "  --threads                         specify threaded version ($threads)"
  echo "  --nothreads                       specify non-threaded version ($nothreads)"
  echo "  --32|--64                         specify 32/64-bit version ($bits)"
  echo "  --pb                              specify pb (portable bytecode) version"
  echo "  --pbarch                          specify pb with inferred word and endianness"
  echo "  --emscripten                      build via emscripten (\"em\" tool prefix)"
  echo "  --cross                           build host to bootstrap target"
  echo "  --disable-x11                     disable X11 support"
  echo "  --disable-curses                  disable [n]curses support"
  echo "  --disable-iconv                   disable iconv support"
  echo "  --enable-libffi                   enable libffi support for pb"
  echo "  --disable-auto-flags              no auto additions to CFLAGS/LDFLAGS/LIBS"
  echo "  --enable-warning-flags            add GCC warning flags to CFLAGS"
  echo "  --libkernel                       build libkernel.a (the default)"
  echo "  --kernelobj                       build kernel.o instead of libkernel.a"
  echo "  --installprefix=<pathname>        final installation root ($installprefix)"
  echo "  --prefix=<pathname>               alias for --installprefix"
  echo "  --installbin=<pathname>           bin directory ($installbin)"
  echo "  --installlib=<pathname>           lib directory ($installlib)"
  echo "  --installman=<pathname>           manpage directory ($installman)"
  echo "  --installdoc=<pathname>           documentation root ($installdoc)"
  echo "  --installcsug=<pathname>          guide directory ($installcsug)"
  # abbreviate "release notes" to fit default help in 80 cols:
  echo "  --installreleasenotes=<pathname>  notes directory ($installreleasenotes)"
  echo "  --temproot=<pathname>             staging root ($temproot)"
  echo "  --installowner=<ownername>        install with owner ($installowner)"
  echo "  --installgroup=<groupname>        install with group ($installgroup)"
  echo "  --installschemename=<schemename>  install scheme as ($installschemename)"
  echo "  --installpetitename=<petitename>  install petite as ($installpetitename)"
  echo "  --installscriptname=<scriptname>  install scheme-script as ($installscriptname)"
  echo "  --installabsolute                 disable relative boot-file search, bin links"
  echo "  --toolprefix=<prefix>             prefix tool (compiler, linker, ...) names"
  echo "  --boot=<machine type>-<tag>       build from prepared variant (e.g., pbchunk)"
  echo "  --emboot=\"<file> ...\"             additional boot <file>s with emscripten"
  echo "  --empetite                        omit \"scheme.boot\" with emscripten"
  echo "  --start=<name>                    load <boot>.boot instead of <exe>.boot"
  echo "  --[no]gzip-man-pages              compress manual pages ($gzipmanpages)"
  echo "  --workarea=<pathname>             build directory ($w)"
  echo "  --force                           disable use of pb to (re)build boot files"
  echo "  --as-is                           skip Git submodule update"
  echo "  --nomakefile                      create build-directory files only"
  echo "  CC=<C compiler>                   C compiler"
  echo "  CPPFLAGS=<C preprocessor flags>   C preprocessor flags"
  echo "  CPPFLAGS+=<C preprocessor flags>  add C preprocessor flags"
  echo "  CFLAGS=<C compiler flags>         C compiler flags"
  echo "  CFLAGS+=<C compiler flags>        add C compiler flags"
  echo "  CC_FOR_BUILD=<C compiler>         C compiler and flags for build machine"
  echo "  CFLAGS_FOR_BUILD=<C compiler>     additional C flags for build machine"
  echo "  LD=<linker>                       linker"
  echo "  LDFLAGS=<linker flags>            additional linker flags"
  echo "  LDFLAGS+=<linker flags>           add additional linker flags"
  echo "  LIBS=<libraries>                  additional libraries"
  echo "  LIBS+=<libraries>                 add additional libraries"
  echo "  AR=<archiver>                     archiver"
  echo "  ARFLAGS=<archiver flgs>           archiver flags"
  echo "  RANLIB=<archive indexer>          archive indexer"
  echo "  WINDRES=<resource compiler>       resource compiler"
  echo "  STRIP=<strip>                     executable stripper"
  echo "  ZLIB=<lib>                        link to <lib> instead of own zlib"
  echo "  LZ4=<lib>                         link to <lib> instead of own LZ4"
  echo "  STEXLIB=<stex>                    build docs with <stex> instead of own stex"
  echo "  ZUO=<zuo>                         build with <zuo> instead of own Zuo"
  echo ""
  echo "Available machine types: $machs"
  echo ""
  echo "Examples:"
  echo "  $0 --machine=i3le"
  echo ""
  echo "  set machine-type to i3le rather than to determined type"
  echo ""
  echo "  $0 --threads --installprefix=/usr/local"
  echo ""
  echo "  specify threaded version and set installation directory to /usr/local."
  echo ""
  echo "  $0 --installprefix=/usr/local --temproot=/tmp"
  echo ""
  echo "  declare the final destination to be /usr/local but staging area"
  echo "  to be /tmp/usr/local.  Make will record the final destination in the"
  echo "  installed manual pages but actually install the system and manual"
  echo "  pages in the staging area."
  echo ""
  exit 0
fi

optFlags=-O2

if [ "$emscripten" = "yes" ]; then
    case "$m" in
        t*)
            flagsm=tem
            ;;
        *)
            flagsm=em
            ;;
    esac
    buildKernelOnly=yes
    disableiconv=yes
    disablecurses=yes
fi

if [ "$cflagsset" = "no" -o "$addwarningflags" = "yes" ] ; then
    warningFlags="$default_warning_flags"
else
    warningFlags=""
fi

# Infer flags needed for threads:
case "${flagsm}" in
  t*le|t*gnu|t*fb|t*ob|t*nb)
      threadFlags="-D_REENTRANT -pthread"
      threadLibs="-lpthread"
      ;;
  t*s2)
      threadFlags="-pthread"
      threadLibs="-lpthread"
      ;;
  tem)
      threadFlags="-pthread"
      threadLibs=""
      ;;
  *)
      threadFlags=""
      threadLibs=""
      ;;
esac

flagsmuni=`echo $flagsm | sed -e 's/^t//'`
muni=`echo $m | sed -e 's/^t//'`

# Set default CFLAGS if not provided at all. Assuming that the
# compiler is for the right platform, compilation should generally
# succeed if no flags are set; anything required should be propagated
# a different way
if [ "$cflagsset" = "no" ] ; then
  case "${flagsmuni}" in
    a6le)
        CFLAGS="-m64 -msse2 ${optFlags}"
        ;;
    a6nt)
        CFLAGS="${optFlags}"
        ;;
    a6*)
        CFLAGS="-m64 ${optFlags}"
        ;;
    i3le) # intentionally not including i3gnu, which may not support sse2
        CFLAGS="-m32 -msse2 -mfpmath=sse ${optFlags}"
        ;;
    i3nt)
        CFLAGS="${optFlags}"
        ;;
    i3qnx)
        CC=qcc
        CFLAGS="-m32 -N2048K ${optFlags}"
        ;;
    i3*)
        CFLAGS="-m32 ${optFlags}"
        ;;
    arm32*)
        CFLAGS="${optFlags}"
        ;;
    arm64osx)
        CFLAGS="-arch arm64 ${optFlags}"
        ;;
    ppc32osx)
        CFLAGS="${optFlags}"
        ;;
    ppc32*)
        CFLAGS="-m32 ${optFlags}"
        ;;
    rv64*)
        CFLAGS="-mabi=lp64d ${optFlags}"
        ;;
    em)
        CFLAGS="${optFlags}"
        ;;
    *)
        CFLAGS="${optFlags}"
        ;;
  esac
fi

CFLAGS="${CFLAGS}${CFLAGS_ADD}"

if [ "$CC_FOR_BUILD" = "" ] ; then
    CC_FOR_BUILD="${CC} ${CFLAGS}"
fi

# Add automatic thread compilation flags, unless suppressed by --disable-auto-flags
if [ "$addflags" = "yes" ] ; then
    if [ "$threadFlags" != "" ] ; then
        CFLAGS="${CFLAGS} ${threadFlags}"
    fi
fi

# Add libffi library, unless suppressed by --disable-auto-flags
if [ "$addflags" = "yes" ] ; then
    if [ "$libffi" = "yes" ] ; then
        LIBS="${LIBS} -lffi"
    fi
fi

cursesLib=-lcurses
ncursesLib=-lncurses

if [ "$disablecurses" = "yes" ]; then
  cursesLib=
  ncursesLib=
fi

if [ "$disableiconv" = "yes" ]; then
    iconvLib=
else
    iconvLib="-liconv"
fi

# Add automatic linking flags, unless suppressed by --disable-auto-flags
if [ "$addflags" = "yes" ] ; then
  case "${flagsm}" in
    *le|*gnu)
        LDFLAGS="${LDFLAGS} -rdynamic"
        ;;
    *fb|*nb)
        LDFLAGS="${LDFLAGS} -rdynamic -L/usr/local/lib"
        ;;
    *ob)
        LDFLAGS="${LDFLAGS} -rdynamic -Wl,--export-dynamic -Wl,-zwxneeded -L/usr/local/lib"
        ;;
    *)
        ;;
  esac

  case "${flagsm}" in
    *le|*gnu)
        LIBS="${LIBS} -lm -ldl ${ncursesLib} -lrt"
        ;;
    *fb|*ob)
        LIBS="${LIBS} ${iconvLib} -lm ${ncursesLib}"
        ;;
    *nb)
        LIBS="${LIBS} -lm ${cursesLib} -lterminfo"
        ;;
    *s2)
        LIBS="${LIBS} -lnsl -ldl -lm ${cursesLib} -lrt"
        ;;
    *osx)
        LIBS="${LIBS} ${iconvLib} -lm ${ncursesLib}"
        ;;
    *nt)
        LIBS="${LIBS} -lshell32 -luser32 -lole32 -lrpcrt4 -luuid"
        ;;
    *qnx)
        if [ "$disableiconv" = "no" ]; then
            iconvLib="/usr/local/lib/libiconv.so"
        fi
        LIBS="${LIBS} -lm ${iconvLib} -lsocket ${ncursesLib}"
        ;;
  esac
  if [ "$threadLibs" != "" ] ; then
    LIBS="${LIBS} ${threadLibs}"
  fi
fi

if [ "$skipSubmoduleUpdate" != "yes" ] ; then
  if [ -d '.git' ] && command -v git >/dev/null 2>&1 ; then
    git submodule update --init --depth 1
  fi
fi

submod_instructions () {
    echo $1
    if [ -d '.git' ] ; then
        echo "Initialize and update submodules, probably something like this:"
        echo "  git submodule update --init --depth 1"
    fi
    exit 1
}

if [ "${zuoExternal}" = "" ] ; then
    if [ ! -f "$srcdir"/zuo/configure ] ; then
        submod_instructions 'Source in "zuo" is missing'
    fi
    ZUO="bin/zuo"
    ZUO_DEP="${ZUO}"
    RM_ZUO="rm -f bin/zuo"
    ZUO_TARGET="bin/zuo"
else
    ZUO="${zuoExternal}"
    ZUO_DEP=""
    RM_ZUO="@echo 'Not cleaning external ${zuoExternal}'"
    ZUO_TARGET="DoNotBuildZuo"
fi

if [ ! -f "$srcdir"/nanopass/nanopass.ss ] ; then
    submod_instructions 'Source in "nanopass" is missing'
fi

if [ "${zlibLib}" = "" ] ; then
    if [ ! -f "$srcdir"/zlib/configure ] ; then
        submod_instructions 'Source in "zlib" is missing'
    fi
fi

if [ "${LZ4Lib}" = "" ] ; then
    if [ ! -f "$srcdir"/lz4/lib/Makefile ] ; then
        submod_instructions 'Source in "lz4" is missing'
    fi
fi

if [ "${STEXLIB}" = "" ] ; then
    if [ ! -f "$srcdir"/stex/Mf-stex ] ; then
        submod_instructions 'Source in "stex" is missing'
    fi
fi

# more compile and link flags for c/Mf-unix and mats/Mf-unix
mdinclude=
mdcppflags=
mdcflags=
mdldflags=
mdlinkflags=
zlibConfigureEnv=
zlibConfigureFlags=
exeExtraDeps=
exePostStep=":"
exeSuffix=

# compile flags for c/Mf-unix and mats/Mf-unix
case "${flagsmuni}" in
    *le|*gnu)
        mdcflags="-fPIC -shared"
        ;;
    *fb|*ob)
        mdcflags="-fPIC -shared"
        mdinclude="-I/usr/local/include -I/usr/X11R6/include"
        ;;
    *nb)
        mdcflags="-fPIC -shared"
        ;;
    *nt)
        mdcflags="-shared"
	;;
    *osx)
        mdcflags="-dynamiclib -undefined dynamic_lookup"
        ;;
    *s2)
        mdcflags="-fPIC -shared"
        mdcppflags="-DSOLARIS"
        ;;
    *qnx)
        mdcflags="-fPIC -shared"
        mdinclude="-I/usr/local/include"
        ;;
esac

# dynamic linking flags for c/Mf-unix
case "${flagsmuni}" in
    a6le)
        mdldflags="-melf_x86_64"
        ;;
    i3le)
        mdldflags="-melf_i386"
        ;;
    *le|*gnu)
        ;;
    i3nb)
        mdldflags="-m elf_i386"
        ;;
    *fb|*ob|*nb)
        ;;
    *osx)
        ;;
    a6s2)
        mdldflags="-melf_x86_64"
        ;;
    i3s2)
        mdldflags="-melf_i386"
        ;;
    i3qnx)
        mdlinkflags="-Wl,--export-dynamic"
        mdldflags="-mi386nto"
        ;;
    em)
        mdlinkflags="-s EXIT_RUNTIME=1 -s ALLOW_MEMORY_GROWTH=1"
        ;;
esac

# pre- and post-link-executable step for c/Mf-unix
case "${flagsmuni}" in
    *nb)
        exePostStep='paxctl +m'
        ;;
    em)
        if [ "$empetite" = yes ]; then
            preloadBootFiles="$w/boot/$m/petite.boot"
        else
            preloadBootFiles="$w/boot/$m/petite.boot $w/boot/$m/scheme.boot"
        fi
        preloadBootFiles="$preloadBootFiles $moreBootFiles"
        exeSuffix=".html"
        ;;
esac

# zlib configure flags for c/Mf-unix
case "${flagsmuni}" in
    em)
        if  [ "$zlibLib" = "" ]; then
            zlibLib="-s USE_ZLIB=1"
            CFLAGS="${CFLAGS} -s USE_ZLIB=1"
            # not used, but this is how we might build our own zlib:
            zlibConfigureEnv="CROSS_PREFIX=em uname=wasm-em"
        fi
        ;;
esac

if [ "$w" = "$m" ] ; then
    configuringin=""
else
    configuringin=" in $w"
fi

if [ "$flagsm" != "$m" ] ; then
    configuringin="$configuringin to run on $flagsm"
fi

if [ "$m" = "" ] ; then
    enableFrompb=no
    forceworkarea=no
fi

if [ "$buildKernelOnly" = yes ] ; then
    enableFrompb=no
fi

if [ -f boot/$m/scheme.boot -o -f "$srcdir"/boot/$m/scheme.boot ] ; then
    echo "Configuring for $m$configuringin"
elif [ -f "$srcdir"/boot/pb/scheme.boot -a "$enableFrompb" = "yes" ] ; then
    echo "Configuring for $m$configuringin, and will create boot files via pb"
elif [ "$forceworkarea" = yes ] ; then
    echo "Configuring for $m$configuringin despite missing boot files"
else
  if [ "$m" = "" ] ; then
      maybem="<machine type>"
  else
      maybem=$m
  fi
  echo "No suitable machine type found in \"${srcdir}/boot\"."
  echo ""
  echo "Available machine types:"
  echo "  $machs"
  if [ "$machine_supplied" = "no" ] ; then
      echo ""
      if [ "$m" = "" ] ; then
          echo "If the problem is that the machine type was not inferred,"
          echo "you can try"
      else
          echo "If the problem is that the inferred machine type $m is"
          echo "not correct, you can try"
      fi
      echo "  $0 -m=<machine type>"
      echo "to specify one of the available machine types."
  fi
  echo ""
  echo "See \"${srcdir}/BUILDING\" for ways of getting boot files."
  exit 1
fi

case "$srcdir" in
    /*)
        upsrcdir=$srcdir
        ;;
    *)
        upsrcdir=../$srcdir
        ;;
esac

if [ "$skipImmediateMakefile" = "" ] ; then
    # Makefile to build and launch Zuo
    if [ "$crossCompile" = "yes" ] ; then
        makefile_in=Makefile-cross.in
    else
        makefile_in=Makefile.in
    fi
    sed -e 's/$(w)/'$w'/g' "$srcdir"/makefiles/"$makefile_in" > Makefile
fi

mkdir -p $w

if [ "$skipImmediateMakefile" = "" ] ; then
    # Stub Zuo script to lanch the real one, using "Makefile"
    # to locate the workarea:
    cp "$srcdir"/makefiles/buildmain.zuo main.zuo
fi

# Some idea, but in the workarea, so it refers to "workarea.zuo" here:
cp "$srcdir"/makefiles/workmain.zuo $w/main.zuo

# The content of "$w/Mf-config" records configuration decisions,
# and the Zuo build script takes it from there
cat > $w/Mf-config << END
srcdir=$srcdir
upsrcdir=$upsrcdir
m=$m
defaultm=$defaultm
flagsm=$flagsm
mboot=$mboot
crossCompile=$crossCompile
buildKernelOnly=$buildKernelOnly
enableFrompb=$enableFrompb
mdinclude=$mdinclude
mdcppflags=$mdcppflags
mdcflags=$mdcflags
mdldflags=$mdldflags
mdlinkflags=$mdlinkflags
exeExtraDeps=$exeExtraDeps
exePostStep=$exePostStep
exeSuffix=$exeSuffix
zlibConfigureEnv=$zlibConfigureEnv
zlibConfigureFlags=
CC_FOR_BUILD=$CC_FOR_BUILD
CFLAGS_FOR_BUILD=$CFLAGS_FOR_BUILD
CC=$CC
CPPFLAGS=$CPPFLAGS
CFLAGS=$CFLAGS
LD=$LD
LDFLAGS=$LDFLAGS
LIBS=$LIBS
AR=$AR
ARFLAGS=$ARFLAGS
RANLIB=$RANLIB
WINDRES=$WINDRES
STRIP=$STRIP
cursesLib=$cursesLib
ncursesLib=$ncursesLib
zlibLib=$zlibLib
LZ4Lib=$LZ4Lib
STEXLIB=$STEXLIB
warningFlags=$warningFlags
Kernel=$Kernel
installscriptname=$installscriptname
disablecurses=$disablecurses
disableiconv=$disableiconv
disablex11=$disablex11
enablelibffi=$libffi
preloadBootFiles=$preloadBootFiles
alwaysUseBootFile=$alwaysUseBootFile
relativeBootFiles=$relativeBootFiles

ZUO=$ZUO
ZUO_DEP=$ZUO_DEP
RM_ZUO=$RM_ZUO
ZUO_TARGET=$ZUO_TARGET

InstallBin=$installbin
InstallLib=$installlib
InstallMan=$installman/man1
InstallCSUG=$installcsug
InstallReleaseNotes=$installreleasenotes
InstallOwner=$installowner
InstallGroup=$installgroup
TempRoot=$temproot
GzipManPages=$gzipmanpages
InstallSchemeName=$installschemename
InstallPetiteName=$installpetitename
InstallScriptName=$installscriptname
END
