#!/bin/sh
#
#  vanilla{tclsh,wish} - Build script for standard Tcl/Tk
#
#############################################################################
#
# Build script to generate a single-file "vanillawish.exe"
# based on an AndroWish source tree. This is an experiment
# and requires a recent (2016-02-11) AndroWish check-out.
#
# This script must be run in directory outside of the
# AndroWish source tree which gets populated with copies of
# the AndroWish sources and further filled with the compiled
# (Windows 64 bit) products.
#
# It must be invoked with a single argument 'action':
#
# 'init'       initialize current directory from AndroWish
# 'sync'       sync with AndroWish source tree
# 'clean'      run 'make clean' in subdirectories
# 'distclean'  run 'make distclean' in subdirectories
# 'build'      (default action) build everything
#              If all goes well two files "vanillawish.exe" and
#              "vanillatclsh.exe" are produced which can be copied
#              and run on a 64 bit Windows machine and in
#              Wine (with limitations).
#
# Cross toolchains for Linux/i386/x86_64 can be fetched from
#  http://www.ch-werner.de/xtools/crossmingw64-0.4-1.i386.rpm
#  http://www.ch-werner.de/xtools/crossmingw64-0.4-1.x86_64.rpm
# or
#  http://www.ch-werner.de/xtools/crossmingw64-0.4.i386.tar.bz2
#  http://www.ch-werner.de/xtools/crossmingw64-0.4.x86_64.tar.bz2
#
# These toolchains are used on Debian and CentOS 5/6 for building
# the SQLite ODBC driver on http://www.ch-werner.de/sqliteodbc
#
# Debian/Ubuntu provide cross toolchains in the packages
#  mingw-w64 mingw-w64-dev g++-mingw-64 gcc-mingw-w64
#  binutils-mingw-w64-{i686,x86_64}
# which can be used for building vanillawish.exe, too.
#
# Additionally the Wine Windows emulator (version >= 1.6) is
# required during the build process and the development system
# must be configured to transparently run Windows binaries
# using Wine as handler in "binfmt_misc".
#
#############################################################################

set -e

SCRIPTDIR=$(dirname $0)
SCRIPTDIR=$(cd ${SCRIPTDIR} ; pwd)
AWDIR=$(dirname $SCRIPTDIR)
if ! test -d "${AWDIR}/jni" -o ! -d "${AWDIR}/assets" ; then
  echo >&2 "ERROR: installation problem"
  exit 1
fi

if test "$(pwd)" = "${AWDIR}" ; then
  echo >&2 "ERROR: refusing to run in AndroWish source tree"
  exit 1
fi

# prefix where things would be installed on Win32 (= install root)
PFX=/PROGRA~1/Tcl

# working (build) directory
HERE=$(pwd)

# some checks on directory names
if test "$(echo ${HERE} | tr -d [:blank:])" != "${HERE}" ; then
  echo >&2 "ERROR: use another path which doesn't contain blanks"
  exit 1
fi
if test "$(echo ${PFX} | tr -d [:blank:])" != "${PFX}" ; then
  echo >&2 "ERROR: use another prefix which doesn't contain blanks"
  exit 1
fi

case ${PFX} in
  *${HERE}*)
    echo >&2 "ERROR: use another path which doesn't contain '${PFX}'"
    exit 1
    ;;
esac

# prefix relative to working (build) directory
PFX_HERE=${HERE}${PFX}

echo
echo "vanilla{tclsh,wish} - Build script for standard Tcl/Tk"
echo

# the toolchain
if test -d /opt/mingw64/bin ; then
  echo using toolchain from /opt/mingw64/bin
  PATH="/opt/mingw64/bin:$PATH"
  STRIP="x86_64-w64-mingw32-strip"
  AR="x86_64-w64-mingw32-ar"
  RANLIB="x86_64-w64-mingw32-ranlib"
  CC="x86_64-w64-mingw32-gcc -D_WIN32_WINNT=0x0601 -DTCL_UTF_MAX=6"
  CXX="x86_64-w64-mingw32-g++ -D_WIN32_WINNT=0x0601 -DTCL_UTF_MAX=6"
  RC="x86_64-w64-mingw32-windres"
  NM="x86_64-w64-mingw32-nm"
  export STRIP AR RANLIB CC CXX RC NM
else
  echo using toolchain prefix x86_64-w64-mingw32
  STRIP="x86_64-w64-mingw32-strip"
  AR="x86_64-w64-mingw32-ar"
  RANLIB="x86_64-w64-mingw32-ranlib"
  CC="x86_64-w64-mingw32-gcc -D_WIN32_WINNT=0x0601 -DWINVER=0x0601 -DTCL_UTF_MAX=6"
  CXX="x86_64-w64-mingw32-g++ -D_WIN32_WINT=0x0601 -DWINVER=0x0601 -DTCL_UTF_MAX=6"
  RC="x86_64-w64-mingw32-windres"
  NM="x86_64-w64-mingw32-nm"
  export STRIP AR RANLIB CC CXX RC NM
fi

SUBDIRS="tcl libressl zlib curl tcludp tdom tclvfs tclkit trofs tbcload tls"
SUBDIRS="${SUBDIRS} Memchan TclCurl sdl2tk blt jpeg-turbo 3dcanvas"
SUBDIRS="${SUBDIRS} tkimg trf tktable tktreectrl tkpath itk tkhtml twapi"
SUBDIRS="${SUBDIRS} tclx tclwmf libdmtx ZBar zint snack winico tkvnc tksvg"
SUBDIRS="${SUBDIRS} VecTcl tclral tclepeg xotcl nsf vu rl_json tkdnd mpexpr"
SUBDIRS="${SUBDIRS} tclcsv tkzinc libffi ffidl tcl-lmdb DiffUtilTcl"
SUBDIRS="${SUBDIRS} tclparser tclcompiler tdkwin32 snap7 libmodbus"
SUBDIRS="${SUBDIRS} tserialport topcua parse_args tkvlc"

ACTION="$1"
if test -z "$ACTION" ; then
  ACTION=build
fi

clean_build_stamps() {
  for i in $@ ; do
    case "$i" in
      tcl)
        rm -f tcl/win/build-stamp
        ;;
      sdl2tk)
        rm -f sdl2tk/win/build-stamp
        ;;
      tclkit)
        rm -f tclkit/vqtcl/build-stamp
        ;;
      libdmtx)
        rm -f libdmtx/tcl/build-stamp
        ;;
      ZBar)
        rm -f ZBar/tcl/build-stamp
        ;;
      zint)
        rm -f zint/backend_tcl/build-stamp
        ;;
      snack)
        rm -f snack/win/build-stamp snack/win/*.o
        ;;
      VecTcl)
        rm -f VecTcl/WavReader/build-stamp
        rm -f VecTcl/TkBridge/build-stamp
        rm -f VecTcl/build-stamp
        ;;
      xotcl|nsf)
        rm -f ${i}/*.o ${i}/generic/stubs*/*.o
        rm -f ${i}/build-stamp
        ;;
      mpexpr)
        rm -f ${i}/unix/build-stamp
        ;;
      snap7)
        rm -f ${i}/build/win/build-stamp
        ;;
      *)
        rm -f ${i}/build-stamp
        ;;
     esac
  done
}

if test "$ACTION" = "init" ; then
  echo "copying sources"
  for i in ${SUBDIRS} ; do
    echo "  $i"
    if test "$i" = "zlib" ; then
      rsync -a "tcl/compat/zlib" .
    elif test -d  "${AWDIR}/undroid/$i" ; then
      rsync -a "${AWDIR}/undroid/$i" .
    else
      rsync -a "${AWDIR}/jni/$i" .
    fi
  done
  echo
  clean_build_stamps ${SUBDIRS}
  exit 0
fi

if test "$ACTION" = "sync" ; then
  echo "syncing sources"
  for i in ${SUBDIRS} ; do
    echo "  $i"
    if test "$i" = "zlib" ; then
      rsync -utlpr "tcl/compat/zlib" .
    elif test -d  "${AWDIR}/undroid/$i" ; then
      rsync -utlpr "${AWDIR}/undroid/$i" .
    else
      rsync -utlpr "${AWDIR}/jni/$i" .
    fi
  done
  echo
  clean_build_stamps ${SUBDIRS}
  exit 0
fi

if test "$ACTION" = "clean" -o "$ACTION" = "distclean" ; then
  echo "cleaning sources"
  for i in ${SUBDIRS} ; do
    echo "  $i"
    case "$i" in
      tcl)
        (
          exec >> build.log 2>&1
          make -C tcl/win ${ACTION}
        ) || true
	;;
      sdl2tk)
        (
          exec >> build.log 2>&1
          make -C sdl2tk/win ${ACTION} || true
        ) || true
	;;
      tclkit)
        (
          exec >> build.log 2>&1
          make -C tclkit/vqtcl ${ACTION} || true
        ) || true
	;;
      libdmtx)
        (
          exec >> build.log 2>&1
          make -C libdmtx/tcl ${ACTION} || true
        ) || true
	;;
      ZBar)
        (
          exec >> build.log 2>&1
          make -C ZBar/tcl ${ACTION} || true
        ) || true
	;;
      zint)
        (
          exec >> build.log 2>&1
          make -C zint/backend_tcl ${ACTION} || true
        ) || true
	;;
      snack)
        (
          exec >> build.log 2>&1
          make -C snack/win ${ACTION} || true
        ) || true
	;;
      VecTcl)
        (
          exec >> build.log 2>&1
          make -C VecTcl/WavReader ${ACTION} || true
          make -C VecTcl/TkBridge ${ACTION} || true
          make -C VecTcl ${ACTION} || true
        ) || true
	;;
      mpexpr)
        (
          exec >> build.log 2>&1
          make -C mpexpr/unix ${ACTION} || true
        ) || true
        ;;
      tdom)
        (
          exec >> build.log 2>&1
          make -C tdom ${ACTION} || true
          make -C tdom/extensions/tnc ${ACTION} || true
        ) || true
        ;;
      snap7)
        (
          exec >> build.log 2>&1
          make -C snap7/build/win -f win.mk clean || true
        ) || true
        ;;
      *)
        (
          exec >> build.log 2>&1
          make -C $i ${ACTION} || true
        ) || true
        ;;
     esac
  done
  echo
  clean_build_stamps ${SUBDIRS}
  rm -f build.log assets.zip tassets.zip vanillawish.exe vanillatclsh.exe
  rm -rf assets tassets ${PFX_HERE}
  exit 0
fi

if test "$ACTION" != "build" ; then
  echo "Don't know what to do for '${ACTION}'. Specify action as"
  echo "one of 'init', 'sync', 'clean', 'distclean', and 'build'."
  echo "If omitted, the default action is 'build'."
  exit 1
fi

for i in ${SUBDIRS} ; do
  if ! test -d ${i} ; then
    echo >&2 "ERROR: missing directory '$i', please do 'sync' or 'init'."
    exit 1
  fi
done

echo
echo "writing log output to build.log"
echo

echo -e >> build.log \
  "\n***** build started on $(date '+%Y-%m-%d %H:%M:%S') *****\n"

fail() {
  echo -e >> build.log \
    "\n***** build failed on $(date '+%Y-%m-%d %H:%M:%S') *****\n"
  echo "failed, see build.log for details."
  exit 1
}

if test ! -d ${PFX_HERE} ; then
  if test -e .fixup-stamp ; then
    rm -f .fixup-stamp
  fi
fi

test ! -e .fixup-stamp || (
  exec >> build.log 2>&1
  # unfix paths in installation tree
  set -x
  perl -pi -e "s@${PFX}/lib@${HERE}/tcl/win@g" ${PFX_HERE}/bin/*-config || true
  perl -pi -e "s@${PFX}@${PFX_HERE}@g" ${PFX_HERE}/bin/*-config || true
  perl -pi -e "s@${PFX}@${PFX_HERE}@g" ${PFX_HERE}/lib/*.sh || true
  set +x
  rm -f .fixup-stamp
) || fail

echo -n "build Tcl (static) ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd tcl/win
  test -e build-stamp && echo >&3 "already done" && exit 0
  ./configure --prefix=${PFX} --build=x86_64-windows-mingw32 --disable-shared \
    --with-zipfs --with-tickcount || exit 1
  make binaries || exit 1
  make install-binaries install-libraries \
    install-private-headers install-packages INSTALL_ROOT=${HERE} || exit 1
  # symlink for tclsh
  rm -f ${HERE}/tcl/win/tclsh86.exe
  ln -s ${HERE}/tcl/win/tclsh86s.exe ${HERE}/tcl/win/tclsh86.exe 
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build libressl (static, pic) ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd libressl
  test -e build-stamp && echo >&3 "already done" && exit 0
  # libressl >= 2.4 has own setting of _WIN32_WINNT
  CC=`echo $CC | sed -e 's/-D_WIN32_WINNT=0x[0-9]\+//g'`
  CXX=`echo $CC | sed -e 's/-D_WIN32_WINNT=0x[0-9]\+//g'`
  CFLAGS="-DHAVE_ASPRINTF=1 -DHAVE_STRCASECMP=1" \
    ./configure --prefix=${PFX} --build=x86_64-windows-mingw32 --with-pic \
    --disable-shared || exit 1
  # shrink SUBDIRS
  perl -pi -e 's/^SUBDIRS.*/SUBDIRS = crypto ssl include/g' Makefile
  make || exit 1
  make install DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build zlib (static, pic) ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd zlib
  test -e build-stamp && echo >&3 "already done" && exit 0
  ./configure --prefix=${PFX} --static
  make || exit 1
  make install DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
)

echo -n "build curl (static, pic) ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd curl
  test -e build-stamp && echo >&3 "already done" && exit 0
  ./configure --prefix=${PFX} --build=x86_64-windows-mingw32 --with-pic \
    --disable-shared --disable-ldap --disable-pthreads \
    --without-libidn2 --without-nghttp2 --without-zsh-functions-dir \
    --without-librtmp --without-libssh2 --without-libpsl --without-axtls \
    --without-nss --without-cyassl --without-mbedtls --without-polarssl \
    --without-gnutls --without-brotli --with-winssl --with-zlib=${HERE}/zlib
  # shrink SUBDIRS
  perl -pi -e 's/^SUBDIRS.*/SUBDIRS = lib include/g' Makefile
  make || exit 1
  make install DESTDIR=${HERE} || exit 1
  # cheat curl binary to make TclCurl configure happy
  echo '#!/bin/false' > ${PFX_HERE}/bin/curl && chmod a+x ${PFX_HERE}/bin/curl
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build tcludp ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd tcludp
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --enable-threads || exit 1
  make || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build tdom ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd tdom
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --enable-threads || exit 1
  make || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1
  cd extensions/tnc
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --with-tdom=../.. --enable-threads || exit 1
  make || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1
  cd ../..
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build tclvfs ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd tclvfs
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --enable-threads || exit 1
  make || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build tclkit/vqtcl ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd tclkit/vqtcl
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --enable-threads || exit 1
  make binaries || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build trofs ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd trofs
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --enable-threads || exit 1
  make binaries libraries || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build tbcload ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd tbcload
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --enable-threads || exit 1
  make || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build tls ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd tls
  test -e build-stamp && echo >&3 "already done" && exit 0
  CFLAGS="-DNO_SSL2=1 -DNO_SSL3=1" DESTDIR=${HERE} ./configure \
    --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --enable-threads \
    --with-ssl-dir=${PFX_HERE} || exit 1
  make || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build Memchan ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd Memchan
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure \
    --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --enable-threads || exit 1
  make binaries libraries || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build TclCurl ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd TclCurl
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} LDFLAGS="-L${PFX_HERE}/lib" \
  ./configure \
    --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-curlprefix=${PFX_HERE} \
    --with-curlinclude=${HERE}/curl/include \
    --with-libcurl=${PFX_HERE}/lib \
    --with-tcl=${HERE}/tcl/win --enable-threads || exit 1
  make binaries libraries || exit 1
  make install-binaries install-libraries install-scripts \
    DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build Tk (Win32 backend, static) ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd sdl2tk/win
  test -e build-stamp && echo >&3 "already done" && exit 0
  # fixup pkgIndex.tcl since we build a static wish
  cat > ../library/pkgIndex.tcl <<'EOD'
if {[catch {package present Tcl 8.6}]} {return}
package ifneeded Tk 8.6.9 {load {} Tk}
EOD
  PATH=${PFX_HERE}/bin:$PATH
  ./configure --prefix=${PFX} --build=x86_64-windows-mingw32 --disable-shared \
    --disable-rpath --with-tcl=${HERE}/tcl/win || exit 1
  make binaries || exit 1
  make install-binaries install-libraries install-private-headers \
    install-demos INSTALL_ROOT=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build blt ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd blt
  test -e build-stamp && echo >&3 "already done" && exit 0
  # to use stubs, get rid of win/X11
  test -d win/X11 && test -d win/dont-use-X11 && rm -rf win/dont-use-X11
  test -d win/X11 && mv win/X11 win/dont-use-X11
  PATH=${PFX_HERE}/bin:$PATH
  # same BLT subset as AndroWish, please
  CFLAGS="-DNO_BGEXEC=1 -DNO_CRC32=1 -DNO_DDE=1"
  CFLAGS="${CFLAGS} -DNO_BGPATTERN=1 -DNO_DATATABLE=1 -DNO_DEBUG=1"
  CFLAGS="${CFLAGS} -DNO_TREE=1 -DNO_WATCH=1 -DNO_PICTURE=1"
  CFLAGS="${CFLAGS} -DNO_TABSET=1 -DNO_TABNOTEBOOK=1 -DNO_HIERBOX=1"
  CFLAGS="${CFLAGS} -DNO_BUSY=1 -DNO_DRAGDROP=1 -DNO_CUTBUFFER=1"
  CFLAGS="${CFLAGS} -DNO_DND=1 -DNO_CONTAINER=1 -DNO_BEEP=1"
  CFLAGS="${CFLAGS} -DNO_PRINTER=1 -DNO_TILE=1 -DNO_TILEFRAME=1"
  CFLAGS="${CFLAGS} -DNO_TILEBUTTON=1 -DNO_TILESCROLLBAR=1 -DNO_TREEVIEW=1"
  CFLAGS="${CFLAGS} -DNO_MOUNTAIN=1 -DNO_TED=1 -DNO_EPSCANV=1"
  CFLAGS="${CFLAGS} -DNO_SENDEVENT=1 -DNO_COMBOTREE=1 -DNO_HTEXT=1"
  CFLAGS="${CFLAGS} -DUSE_TCL_STUBS=1 -DUSE_TK_STUBS=1 -DTK_DRAWANGLEDCHARS=1"
  export CFLAGS
  ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --target=x86_64-windows-mingw32 \
    --with-tcl=${HERE}/tcl/win --with-tk=${HERE}/sdl2tk/win \
    --with-tclincls=${PFX_HERE}/include --with-tkincls=${PFX_HERE}/include \
    --disable-jpeg --enable-threads || exit 1
  # fixup shared lib deps etc.
  perl -pi -e 's/-ltk86/-ltkstub86/g' src/Makefile
  perl -pi -e 's/-ltcl86/-ltclstub86/g' src/Makefile
  perl -pi -e 's@ \$\(bltsh\) \$\(bltwish\)@@g' src/Makefile
  perl -pi -e 's@ install-demo@@g' src/Makefile
  make || exit 1
  make install INSTALL_ROOT=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build jpeg-turbo (static, pic) ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd jpeg-turbo
  test -e build-stamp && echo >&3 "already done" && exit 0
  chmod a+x ./configure
  ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} --with-jpeg8 \
    --enable-static --disable-shared --with-mem-srcdst
  make -C simd libsimd.la || exit 1
  make libjpeg.la || exit 1
  cp -p .libs/libjpeg.a .
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build 3dcanvas ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd 3dcanvas
  test -e build-stamp && echo >&3 "already done" && exit 0
  PATH=${PFX_HERE}/bin:$PATH
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --with-tk=${HERE}/sdl2tk/win \
    --enable-threads || exit 1
  make binaries libraries || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build tkimg ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd tkimg
  test -e build-stamp && echo >&3 "already done" && exit 0
  chmod a+x compat/libtiff/configure
  PATH=${PFX_HERE}/bin:$PATH
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --with-tk=${HERE}/sdl2tk/win \
    --with-libjpeg=${HERE}/jpeg-turbo --enable-threads || exit 1
  make || exit 1
  make install-libraries INSTALL_ROOT=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

# trf wants the stub enabled zlib from tkimg

echo -n "build trf ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd trf
  # move compat/stdlib.h out of way
  test -f compat/stdlib.h && mv compat/stdlib.h compat/stdlib.h-DONTUSE
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure \
    --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-zlib-include-dir=$(pwd)/compat \
    --with-zlibtcl=${PFX_HERE}/lib --enable-builtin-bz2 \
    --with-ssl=${PFX_HERE} --enable-static-md5 \
    --with-tcl=${HERE}/tcl/win --enable-threads || exit 1
  perl -pi -e "s@-L${PFX}@-L${PFX_HERE}@g" Makefile
  make binaries libraries || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1
  rm -f ${PFX_HERE}/lib/Trf*/lib*.a
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build tktable ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd tktable
  test -e build-stamp && echo >&3 "already done" && exit 0
  PATH=${PFX_HERE}/bin:$PATH
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --with-tk=${HERE}/sdl2tk/win \
    --enable-threads || exit 1
  make || exit 1
  make install DESTDIR=${HERE} || exit 1
  install -d ${PFX_HERE}/lib/Tktable2.11/demos
  install -m644 demos/*.tcl demos/*.gif ${PFX_HERE}/lib/Tktable2.11/demos
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build tktreectrl ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd tktreectrl
  test -e build-stamp && echo >&3 "already done" && exit 0
  PATH=${PFX_HERE}/bin:$PATH
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --with-tk=${HERE}/sdl2tk/win \
    --enable-threads || exit 1
  make || exit 1
  make install DESTDIR=${HERE} || exit 1
  cp -rp demos ${PFX_HERE}/lib/treectrl2.4.2
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build tkpath ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd tkpath
  test -e build-stamp && echo >&3 "already done" && exit 0
  PATH=${PFX_HERE}/bin:$PATH
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --with-tk=${HERE}/sdl2tk/win \
    --enable-threads || exit 1
  make || exit 1
  make install DESTDIR=${HERE} || exit 1
  cp -rp demos ${PFX_HERE}/lib/tkpath0.3.3
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build itk ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd itk
  test -e build-stamp && echo >&3 "already done" && exit 0
  PATH=${PFX_HERE}/bin:$PATH
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --with-tk=${HERE}/sdl2tk/win \
    --with-itcl=$(echo ${PFX_HERE}/lib/itcl*) || exit 1
  make LIBS="$(echo ${PFX_HERE}/lib/itcl*/libitclstub*.a)" || exit 1
  make install DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build tkhtml ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd tkhtml
  test -e build-stamp && echo >&3 "already done" && exit 0
  PATH=${PFX_HERE}/bin:$PATH
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --with-tk=${HERE}/sdl2tk/win \
    --enable-threads || exit 1
  make || exit 1
  make install DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build twapi ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  CC=`echo $CC | sed -e 's/-D_WIN32_WINNT=0x[0-9]\+//g'`
  CC=`echo $CC | sed -e 's/-DWINVER=0x[0-9]\+//g'`
  cd twapi
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --enable-64bit --with-tcl=${HERE}/tcl/win --enable-threads || exit 1
  make || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build tclx ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd tclx
  test -e build-stamp && echo >&3 "already done" && exit 0
  PATH=${PFX_HERE}/bin:$PATH
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win || exit 1
  make || exit 1
  make install DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build tclwmf ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  CC=`echo $CC | sed -e 's/-D_WIN32_WINNT=0x[0-9]\+//g'`
  cd tclwmf
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} CFLAGS="-I$(pwd)/../jpeg-turbo" \
    LIBS="-L$(pwd)/../jpeg-turbo -ljpeg" ./configure \
      --build=x86_64-windows-mingw32 --prefix=${PFX} \
      --with-tcl=${HERE}/tcl/win --with-tk=${HERE}/sdl2tk/win \
      --enable-threads || exit 1
  make || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build libdmtx ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd libdmtx/tcl
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --with-tk=${HERE}/sdl2tk/win \
    --enable-threads || exit 1
  make binaries || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build ZBar ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd ZBar/tcl
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --with-tk=${HERE}/sdl2tk/win \
    --enable-threads || exit 1
  make binaries || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build zint ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd zint/backend_tcl
  test -e build-stamp && echo >&3 "already done" && exit 0
  chmod +x ./configure
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --with-tk=${HERE}/sdl2tk/win \
    --enable-threads || exit 1
  make binaries || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build snack ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd snack/win
  test -e build-stamp && echo >&3 "already done" && exit 0
  chmod +x ./configure
  CC="${CC} -static-libgcc" DESTDIR=${HERE} \
    ./configure --build=x86_64-windows-mingw32 \
    --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --with-tk=${HERE}/sdl2tk/win \
    --enable-threads || exit 1
  make all || exit 1
  make install DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build winico ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd winico
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --with-tk=${HERE}/sdl2tk/win \
    --enable-threads || exit 1
  make binaries || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build tkvnc ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd tkvnc
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --with-tk=${HERE}/sdl2tk/win \
    --with-zlib=${HERE}/zlib --enable-threads || exit 1
  make binaries || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build tksvg ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd tksvg
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --with-tk=${HERE}/sdl2tk/win \
    --enable-threads || exit 1
  make binaries || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build VecTcl ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd VecTcl
  test -e build-stamp && echo >&3 "already done" && exit 0
  # already preprocessed, no need to expand
  touch generic/vectcl.[ch] generic/compathack.[ch]
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --enable-threads || exit 1
  make || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build VecTclTk ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd VecTcl/TkBridge
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} CFLAGS=-I${HERE}/VecTcl/generic LDFLAGS=-L${HERE}/VecTcl \
    ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --with-tk=${HERE}/sdl2tk/win \
    --with-vectcl=${PFX_HERE}/lib/vectcl0.3 --enable-threads || exit 1
  make LIBS="-L${HERE}/VecTcl -lvectclstub03" || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build WavReader ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd VecTcl/WavReader
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} CFLAGS=-I${HERE}/VecTcl/generic LDFLAGS=-L${HERE}/VecTcl \
    ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --with-vectcl=${PFX_HERE}/lib/vectcl0.3 \
    --enable-threads || exit 1
  make LIBS="-L${HERE}/VecTcl -lvectclstub03" || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build tclral ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd tclral
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --enable-threads || exit 1
  make binaries || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build tclepeg ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd tclepeg
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} CFLAGS="-I${HERE}/jpeg-turbo -DBUILDING_DLL=1" \
    LIBS="-L${HERE}/jpeg-turbo -ljpeg" \
    ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --enable-threads || exit 1
  make binaries || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build xotcl ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd xotcl
  test -e build-stamp && echo >&3 "already done" && exit 0
  CFLAGS="-I${HERE}/tdom/expat" ./configure --build=x86_64-windows-mingw32 \
    --prefix=${PFX} --with-tcl=${HERE}/tcl/win --enable-threads \
    --disable-rpath --without-gdbm --without-aolserver \
    --with-actiweb=yes --with-xotclsh=no --with-xowish=no || exit 1
  make binaries libraries || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1
  rm -f ${PFX_HERE}/lib/xotcl*/*.a
  rm -f ${PFX_HERE}/lib/xotcl*.sh ${PFX_HERE}/lib/xotcl*.dll
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build nsf ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd nsf
  test -e build-stamp && echo >&3 "already done" && exit 0
  ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --enable-threads \
    --disable-rpath || exit 1
  make binaries libraries || exit 1
  make install-binaries install-libraries install-xotcl-libraries \
    DESTDIR=${HERE} || exit 1
  rm -f ${PFX_HERE}/lib/nsf*/*.a
  rm -f ${PFX_HERE}/lib/nsf*.sh ${PFX_HERE}/lib/nsf*.dll
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build vu ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd vu
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --with-tk=${HERE}/sdl2tk/win \
    --enable-threads || exit 1
  make binaries || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build rl_json ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd rl_json
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --enable-threads || exit 1
  make binaries || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build tkdnd ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd tkdnd
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --with-tk=${HERE}/sdl2tk/win \
    --enable-threads || exit 1
  make binaries || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build mpexpr ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd mpexpr/unix
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win || exit 1
  make || exit 1
  make install prefix=${PFX_HERE} exec_prefix=${PFX_HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build tclcsv ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd tclcsv
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --enable-threads || exit 1
  make || exit 1
  make install DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build tkzinc ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd tkzinc
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --with-tk=${HERE}/sdl2tk/win \
    --enable-threads --disable-shape --enable-gl || exit 1
  make package || exit 1
  make install-package install-demos DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build ffidl ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd ffidl
  test -e build-stamp && echo >&3 "already done" && exit 0
  mkdir -p lib-src && rm -rf lib-src/libffi && cp -rp ../libffi lib-src
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --enable-threads \
    --enable-libffi || exit 1
  make || exit 1
  make install DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build tcl-lmdb ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd tcl-lmdb
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --enable-threads || exit 1
  make || exit 1
  make install DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build DiffUtilTcl ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd DiffUtilTcl
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --enable-threads || exit 1
  make || exit 1
  make install DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build tclparser ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd tclparser
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --enable-threads || exit 1
  make || exit 1
  make install DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build tclcompiler ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd tclcompiler
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --enable-threads || exit 1
  make || exit 1
  make install DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build tdkwin32 ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd tdkwin32
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --with-tk=${HERE}/sdl2tk/win \
    --enable-threads || exit 1
  make || exit 1
  make install DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build snap7 ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd snap7/build/win
  test -e build-stamp && echo >&3 "already done" && exit 0
  make -f win.mk || exit 1
  $STRIP ../bin/*.dll || true
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build libmodbus ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd libmodbus
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --disable-tests --disable-static --enable-shared \
    --without-documentation || exit 1
  make || exit 1
  cp -p src/.libs/libmodbus*.dll ${PFX_HERE}/lib/modbus.dll
  $STRIP ${PFX_HERE}/lib/modbus.dll || true
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build tserialport ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd tserialport
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --enable-threads || exit 1
  make prerequisite || exit 1
  make || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build topcua ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd topcua
  test -e build-stamp && echo >&3 "already done" && exit 0
  if test -d /opt/mingw64/bin ; then
    ADDFLAGS="-DIPV6_V6ONLY=27"
  fi
  CFLAGS="-std=c99 $ADDFLAGS" DESTDIR=${HERE} \
    ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
      --with-tcl=${HERE}/tcl/win --enable-threads || exit 1
  make || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build parse_args ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd parse_args
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --enable-threads || exit 1
  make || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "build tkvlc ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  cd tkvlc
  test -e build-stamp && echo >&3 "already done" && exit 0
  DESTDIR=${HERE} ./configure --build=x86_64-windows-mingw32 --prefix=${PFX} \
    --with-tcl=${HERE}/tcl/win --with-tk=${HERE}/sdl2tk/win \
    --enable-threads || exit 1
  make || exit 1
  make install-binaries install-libraries DESTDIR=${HERE} || exit 1
  touch build-stamp
  echo >&3 "done"
) || fail

echo -n "strip binaries ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  set -x
  $STRIP ${PFX_HERE}/bin/*.exe ${PFX_HERE}/lib/*/*.dll
  # fixup paths in installation tree
  perl -pi -e "s@${PFX_HERE}@${PFX}@g" ${PFX_HERE}/bin/*-config
  perl -pi -e "s@${HERE}/tcl/win@${PFX}/lib@g" ${PFX_HERE}/bin/*-config
  perl -pi -e "s@${PFX_HERE}@${PFX}@g" ${PFX_HERE}/lib/*.sh
  set +x
  touch .fixup-stamp
  echo >&3 "done"
) || fail

echo -n "wrap single-file wish and tclsh binaries ... "
(
  exec 3>&1
  exec >> build.log 2>&1
  set -x
  rm -rf assets
  mkdir -p assets
  cp -rp ${PFX_HERE}/lib/tcl8* assets
  cp -rp ${PFX_HERE}/lib/tk8* assets
  cp -rp ${PFX_HERE}/lib/dde* assets
  cp -rp ${PFX_HERE}/lib/reg* assets
  cp -rp ${PFX_HERE}/lib/itcl* assets
  cp -rp ${PFX_HERE}/lib/sqlite3* assets
  cp -rp ${PFX_HERE}/lib/tdbc* assets
  cp -rp ${PFX_HERE}/lib/thread* assets
  cp -rp ${PFX_HERE}/lib/udp* assets
  cp -rp ${PFX_HERE}/lib/tdom[0-9]* assets
  cp -rp ${PFX_HERE}/lib/tnc[0-9]* assets
  cp -rp ${PFX_HERE}/lib/vfs* assets
  cp -rp ${PFX_HERE}/lib/vqtcl* assets
  cp -rp ${PFX_HERE}/lib/tls* assets
  cp -rp ${PFX_HERE}/lib/trofs* assets
  cp -rp ${PFX_HERE}/lib/tbcload* assets
  cp -rp ${PFX_HERE}/lib/Memchan* assets
  cp -rp ${PFX_HERE}/lib/Trf* assets
  cp -rp ${PFX_HERE}/lib/TclCurl* assets
  # BLT demos from AndroWish assets
  cp -rp ${AWDIR}/assets/blt* assets
  cp -rp ${PFX_HERE}/lib/Canvas3d* assets
  cp -rp ${PFX_HERE}/lib/Img* assets
  cp -rp ${PFX_HERE}/lib/Tktable* assets
  cp -rp ${PFX_HERE}/lib/treectrl* assets
  cp -rp ${PFX_HERE}/lib/tkpath* assets
  cp -rp ${PFX_HERE}/lib/itk* assets
  cp -rp ${PFX_HERE}/lib/Tkhtml* assets
  cp -rp ${PFX_HERE}/lib/twapi* assets
  cp -rp ${PFX_HERE}/lib/tclx* assets
  cp -rp ${PFX_HERE}/lib/tclwmf* assets
  cp -rp ${PFX_HERE}/lib/dmtx* assets
  cp -rp ${PFX_HERE}/lib/zbar* assets
  cp -rp ${PFX_HERE}/lib/zint* assets
  cp -rp ${PFX_HERE}/lib/snack* assets
  cp -rp ${PFX_HERE}/lib/Winico* assets
  cp -rp ${PFX_HERE}/lib/vnc* assets
  cp -rp ${PFX_HERE}/lib/tksvg* assets
  # Tcl-only directories
  cp -rp ${AWDIR}/assets/bwidget* assets
  cp -rp ${AWDIR}/assets/classview* assets
  cp -rp ${AWDIR}/assets/fsdialog* assets
  cp -rp ${AWDIR}/assets/gridplus* assets
  cp -rp ${AWDIR}/assets/helpviewer* assets
  cp -rp ${AWDIR}/assets/icons* assets
  cp -rp ${AWDIR}/assets/iwidgets* assets
  cp -rp ${AWDIR}/assets/materialicons* assets
  cp -rp ${AWDIR}/assets/mqtt* assets
  cp -rp ${AWDIR}/assets/pdf4tcl* assets
  cp -rp ${AWDIR}/assets/tcllib* assets
  cp -rp ${AWDIR}/assets/tclsoap* assets
  cp -rp ${AWDIR}/assets/tclws* assets
  cp -rp ${AWDIR}/assets/tfirmata* assets
  cp -rp ${AWDIR}/assets/tile-extras* assets
  cp -rp ${AWDIR}/assets/tkbugz assets
  cp -rp ${AWDIR}/assets/tkcon2* assets
  cp -rp ${AWDIR}/assets/tkconclient* assets
  cp -rp ${AWDIR}/assets/tkinspect* assets
  cp -rp ${AWDIR}/assets/tklib* assets
  cp -rp ${AWDIR}/assets/TkMC* assets
  cp -rp ${AWDIR}/assets/tksqlite* assets
  cp -rp ${AWDIR}/assets/twdbgi* assets
  cp -rp ${AWDIR}/assets/upnp* assets
  cp -rp ${AWDIR}/assets/ukaz* assets
  cp -rp ${AWDIR}/assets/wibble* assets
  cp -rp ${AWDIR}/assets/stardom* assets
  cp -rp ${AWDIR}/assets/snap7* assets
  cp -p snap7/build/bin/snap7*.dll assets/snap7*
  cp -rp ${AWDIR}/assets/modbus* assets
  cp -p ${PFX_HERE}/lib/modbus*.dll assets/modbus*
  cp -rp ${PFX_HERE}/lib/tserialport* assets
  cp -rp ${PFX_HERE}/lib/topcua* assets
  cp -rp ${PFX_HERE}/lib/parse_args* assets
  cp -rp ${PFX_HERE}/lib/tkvlc* assets
  # BLT fixups
  cp -p ${PFX_HERE}/bin/BLT*.dll ${PFX_HERE}/lib/blt*
  cp -p ${PFX_HERE}/lib/blt*/*.dll assets/blt*
  cp -p ${PFX_HERE}/lib/blt*/pkgIndex* assets/blt*
  if test -r ${AWDIR}/undroid/wits/VERSION ; then
    cp -rp ${AWDIR}/undroid/wits \
      assets/wits$(cat ${AWDIR}/undroid/wits/VERSION)
  fi
  # some demos
  cp -p ${AWDIR}/assets/tkimg*/demo.tcl assets/Img*
  cp -rp ${AWDIR}/assets/Canvas3d*/demo assets/Canvas3d*
  if test -d assets/tclwmf* ; then
    cp -rp ${HERE}/tclwmf*/demos assets/tclwmf*
  fi
  cp -rp ${PFX_HERE}/lib/vectcl0* assets
  cp -rp ${PFX_HERE}/lib/vectcltk0* assets
  cp -rp ${AWDIR}/assets/vectcl*/demo assets/vectcl0*
  cp -rp ${PFX_HERE}/lib/WavReader* assets
  cp -rp ${AWDIR}/assets/VecTcLab* assets
  cp -rp ${PFX_HERE}/lib/ral* assets
  cp -rp ${AWDIR}/assets/ralutil* assets
  cp -rp ${PFX_HERE}/lib/tclepeg* assets
  cp -rp ${PFX_HERE}/lib/xotcl* assets
  cp -rp ${PFX_HERE}/lib/nsf* assets
  cp -rp ${PFX_HERE}/lib/vu* assets
  cp -rp ${PFX_HERE}/lib/rl_json* assets
  cp -rp ${PFX_HERE}/lib/tkdnd* assets
  cp -rp ${PFX_HERE}/lib/Mpexpr* assets
  cp -rp ${PFX_HERE}/lib/tclcsv* assets
  cp -rp ${PFX_HERE}/lib/Tkzinc* assets
  cp -rp ${PFX_HERE}/lib/Ffidl* assets
  cp -rp ${PFX_HERE}/lib/lmdb* assets
  cp -rp ${PFX_HERE}/lib/DiffUtil* assets
  cp -rp ${PFX_HERE}/lib/parser* assets
  cp -rp ${PFX_HERE}/lib/tclcompiler* assets
  cp -rp ${PFX_HERE}/lib/win32* assets
  # add stripped down TDK
  cp -rp ${AWDIR}/undroid/TDK assets
  # add shortcuts providing builtin:widget, builtin:tksqlite, etc.
  (
    cd assets
    echo > widget \
      'source [file dirname [info script]]/'$(echo tk8*)'/demos/widget'
    echo > tksqlite \
      'source [file dirname [info script]]/'$(echo tksqlite*)'/tksqlite.tcl'
    echo > imgdemo \
      'source [file dirname [info script]]/'$(echo Img*)'/demo.tcl'
    echo > tkpdemo \
      'source [file dirname [info script]]/'$(echo tkpath*)'/demos/all.tcl'
    echo > 3ddemo \
      'source [file dirname [info script]]/'$(echo Canvas3d*)'/demo/shapes.tcl'
    echo > tkcon \
      'source [file dirname [info script]]/'$(echo tkcon2*)'/tkcon.tcl'
    echo >> tkcon 'eval ::tkcon::Init $argv'
    echo > tkinspect \
      'source [file dirname [info script]]/'$(echo tkinspect*)'/tkinspect.tcl'
    echo > treectrl \
      'source [file dirname [info script]]/'$(echo treectrl*)'/demos/demo.tcl'
    echo > tktable \
      'source [file dirname [info script]]/'$(echo Tktable*)'/demos/spreadsheet.tcl'
    echo > bugz 'source [file dirname [info script]]/tkbugz/tk_bugz.tcl'
    if test -r ${AWDIR}/undroid/wits/VERSION ; then
      echo > wits \
        'source [file dirname [info script]]/'$(echo wits*)'/witsmain.tcl'
    fi
    echo > zint \
      'source [file dirname [info script]]/'$(echo zint*)'/demo.tcl'
    echo > vncviewer \
      'source [file dirname [info script]]/'$(echo vnc*)'/vncviewer.tcl'
    echo > vectclab \
      'source [file dirname [info script]]/'$(echo VecTcLab*)'/vectclab.tcl'
    echo > tkmc \
      'source [file dirname [info script]]/'$(echo TkMC*)'/tkmc.tcl'
    echo > helpviewer \
      'source [file dirname [info script]]/'$(echo helpviewer*/main.tcl)
    echo > zinc-widget \
      'source [file dirname [info script]]/'$(echo Tkzinc*/demos/zinc-widget)
    echo > stardom \
      'source [file dirname [info script]]/'$(echo stardom*/stardom.tcl)
  )
  # add tkchat
  if test -d ${AWDIR}/assets/tkchat* ; then
    cp -rp ${AWDIR}/assets/tkchat* assets
    (
      cd assets
      echo > tkchat \
        'source [file dirname [info script]]/'$(echo tkchat*/tkchat.tcl)
    )
  fi
  # add notebook
  if test -d ${AWDIR}/assets/notebook2.2 ; then
    cp -rp ${AWDIR}/assets/notebook2.2 assets
    echo > assets/notebook \
      'source [file dirname [info script]]/notebook2.2/notebook.tcl'
  fi
  # add sdx
  cp -rp ${HERE}/tclkit/sdx/lib/app-sdx assets/app-sdx2.0
  cp -rp ${HERE}/tclkit/sdx/lib/sdx assets/sdx1.0
  cp -rp ${HERE}/tclkit/sdx/lib/starsync assets/starsync1.0
  cp -rp ${HERE}/tclkit/sdx/lib/stringfileinfo assets/stringfileinfo0.2
  echo > assets/sdx 'package require starkit ; package require app-sdx'
  if test -d ${AWDIR}/undroid/ttk-themes ; then
    cp -rp ${AWDIR}/undroid/ttk-themes assets
  fi
  # add mpksc
  cp -p ${PFX_HERE}/bin/mpksc assets
  # seed vanillatclsh infrastructure
  mkdir assets/gentclsh
  cp -p ${PFX_HERE}/bin/tclsh86s.exe assets/gentclsh/tclsh.exe || exit 1
  # now same for tclsh
  rm -rf tassets
  mkdir -p tassets
  cp -rp ${PFX_HERE}/lib/tcl8* tassets
  cp -rp ${PFX_HERE}/lib/dde* tassets
  cp -rp ${PFX_HERE}/lib/reg* tassets
  cp -rp ${PFX_HERE}/lib/itcl* tassets
  cp -rp ${PFX_HERE}/lib/sqlite3* tassets
  cp -rp ${PFX_HERE}/lib/tdbc* tassets
  cp -rp ${PFX_HERE}/lib/thread* tassets
  cp -rp ${PFX_HERE}/lib/udp* tassets
  cp -rp ${PFX_HERE}/lib/tdom[0-9]* tassets
  cp -rp ${PFX_HERE}/lib/tnc[0-9]* tassets
  cp -rp ${PFX_HERE}/lib/vfs* tassets
  cp -rp ${PFX_HERE}/lib/vqtcl* tassets
  cp -rp ${PFX_HERE}/lib/tls* tassets
  cp -rp ${PFX_HERE}/lib/trofs* tassets
  cp -rp ${PFX_HERE}/lib/tbcload* tassets
  cp -rp ${PFX_HERE}/lib/Memchan* tassets
  cp -rp ${PFX_HERE}/lib/Trf* tassets
  cp -rp ${PFX_HERE}/lib/TclCurl* tassets
  cp -rp ${PFX_HERE}/lib/twapi* tassets
  cp -rp ${PFX_HERE}/lib/tclx* tassets
  cp -rp ${PFX_HERE}/lib/snack* tassets
  rm -f tassets/snack*/libsnack* tassets/snack*/snack.tcl
  cp -rp ${PFX_HERE}/lib/vectcl0* tassets
  cp -rp ${PFX_HERE}/lib/WavReader* tassets
  cp -rp ${PFX_HERE}/lib/ral* tassets
  cp -rp ${AWDIR}/assets/ralutil* tassets
  cp -rp ${PFX_HERE}/lib/tclepeg* tassets
  cp -rp ${PFX_HERE}/lib/xotcl* tassets
  cp -rp ${PFX_HERE}/lib/nsf* tassets
  cp -rp ${PFX_HERE}/lib/rl_json* tassets
  cp -rp ${PFX_HERE}/lib/Mpexpr* tassets
  cp -rp ${PFX_HERE}/lib/tclcsv* tassets
  cp -rp ${PFX_HERE}/lib/Ffidl* tassets
  cp -rp ${PFX_HERE}/lib/lmdb* tassets
  cp -rp ${PFX_HERE}/lib/DiffUtil* tassets
  cp -rp ${PFX_HERE}/lib/parser* tassets
  cp -rp ${PFX_HERE}/lib/tclcompiler* tassets
  cp -rp ${PFX_HERE}/lib/win32* tassets
  # zlibtcl from tkimg needed for trf
  mkdir -p tassets/zlibtcl1.2.11
  cp -p ${PFX_HERE}/lib/Img*/zlibtcl*.dll tassets/zlibtcl*
  (
    cd tassets/zlibtcl*
    echo  > pkgIndex.tcl 'package ifneeded zlibtcl 1.2.11 \'
    echo >> pkgIndex.tcl '  [list load [file join $dir zlibtcl1211.dll]]'
  )
  # Tcl-only directories
  cp -rp ${AWDIR}/assets/mqtt* tassets
  cp -rp ${AWDIR}/assets/pdf4tcl* tassets
  cp -rp ${AWDIR}/assets/tcllib* tassets
  cp -rp ${AWDIR}/assets/tclsoap* tassets
  cp -rp ${AWDIR}/assets/tclws* tassets
  cp -rp ${AWDIR}/assets/tfirmata* tassets
  cp -rp ${AWDIR}/assets/tkconclient* tassets
  cp -rp ${AWDIR}/assets/upnp* tassets
  cp -rp ${AWDIR}/assets/wibble* tassets
  cp -rp ${AWDIR}/assets/snap7* tassets
  cp -p snap7/build/bin/snap7*.dll tassets/snap7*
  cp -rp ${AWDIR}/assets/modbus* tassets
  cp -p ${PFX_HERE}/lib/modbus*.dll tassets/modbus*
  cp -rp ${PFX_HERE}/lib/tserialport* tassets
  cp -rp ${PFX_HERE}/lib/topcua* tassets
  cp -rp ${PFX_HERE}/lib/parse_args* tassets
  cp -rp ${PFX_HERE}/lib/tkvlc* tassets
  # add sdx
  cp -rp ${HERE}/tclkit/sdx/lib/app-sdx tassets/app-sdx2.0
  cp -rp ${HERE}/tclkit/sdx/lib/sdx tassets/sdx1.0
  cp -rp ${HERE}/tclkit/sdx/lib/starsync tassets/starsync1.0
  cp -rp ${HERE}/tclkit/sdx/lib/stringfileinfo tassets/stringfileinfo0.2
  echo > tassets/sdx 'package require starkit ; package require app-sdx'
  # build ZIP to be embedded for vanillatclsh
  rm -f tassets.zip
  ( cd tassets ; rm -f */*.a ; zip -rq ../tassets.zip * )
  # now wrap to single-file binary vanillatclsh
  cp -p ${PFX_HERE}/bin/tclsh86s.exe vanillatclsh.exe || exit 1
  cat tassets.zip >> vanillatclsh.exe || exit 1
  # prepare generator for vanillatclsh
  ( cd assets ; rm -f */*.a )
  find tassets -type f | awk '{ sub("^tassets/", "");  print $0; }' | \
    grep -v ^zlib > assets/gentclsh/filelist
  ( cd assets ; echo Img*/*zlibtcl* ) >> assets/gentclsh/filelist
  head -2 assets/Img*/pkgIndex.tcl > assets/gentclsh/zlibindex
  (
    cd assets
    cat > mktclsh <<'EOD'
set noe [info nameofexecutable]
set f [open [file join $noe gentclsh filelist]]
set nlist [read $f]
close $f
foreach f $nlist {lappend flist ${noe}/$f $f}
lappend flist ${noe}/gentclsh/zlibindex \
  [glob -dir $noe -tails Img*]/pkgIndex.tcl
zipfs::lmkimg vanillatclsh.exe $flist "" [file join $noe gentclsh tclsh.exe]
exit
EOD
  )
  # build ZIP to be embedded for vanillawish
  rm -f assets.zip
  ( cd assets ; rm -f */*.a ; zip -rq ../assets.zip * )
  # now wrap to single-file binary vanillawish
  cp -p ${PFX_HERE}/bin/wish86s.exe vanillawish.exe || exit 1
  cat assets.zip >> vanillawish.exe || exit 1
  set +x
  echo >&3 "done"
) || fail

echo -e >> build.log \
  "\n***** build ended on $(date '+%Y-%m-%d %H:%M:%S') *****\n"

echo
echo "You should now have a new vanilla{tclsh,wish}.exe, happy tcl'ing."
echo
ls -l vanillatclsh.exe vanillawish.exe

#############################################################################
# EOF
