]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Attempt to get the TEA builder in the amalgamation-autoconf tarball working
authordrh <>
Thu, 17 Oct 2024 13:00:56 +0000 (13:00 +0000)
committerdrh <>
Thu, 17 Oct 2024 13:00:56 +0000 (13:00 +0000)
using hints from Jan Nijtmans.

FossilOrigin-Name: ad9d7bdef95a8da76da0f6db358b6ffb0a0aa9097df2ff52f042e16e62afa8f5

autoconf/tea/Makefile.in
autoconf/tea/README.txt
autoconf/tea/tclconfig/install-sh
autoconf/tea/tclconfig/tcl.m4
autoconf/tea/win/makefile.vc
autoconf/tea/win/rules-ext.vc [new file with mode: 0644]
autoconf/tea/win/rules.vc
autoconf/tea/win/targets.vc [new file with mode: 0644]
manifest
manifest.uuid

index 5264f89f3c55399e3d3c08967f6ee62c2d910ea7..cc98ab1825b60804b72fe455ef9b680adbbb7b6d 100644 (file)
@@ -99,7 +99,6 @@ INSTALL_LIBRARY       = @INSTALL_LIBRARY@
 PACKAGE_NAME   = @PACKAGE_NAME@
 PACKAGE_VERSION        = @PACKAGE_VERSION@
 CC             = @CC@
-CCLD           = @CCLD@
 CFLAGS_DEFAULT = @CFLAGS_DEFAULT@
 CFLAGS_WARNING = @CFLAGS_WARNING@
 EXEEXT         = @EXEEXT@
@@ -311,19 +310,6 @@ VPATH = $(srcdir):$(srcdir)/generic:$(srcdir)/unix:$(srcdir)/win:$(srcdir)/macos
 .c.@OBJEXT@:
        $(COMPILE) -c `@CYGPATH@ $<` -o $@
 
-tclsample.@OBJEXT@:    sampleUuid.h
-
-$(srcdir)/manifest.uuid:
-       printf "git-" >$(srcdir)/manifest.uuid
-       (cd $(srcdir); git rev-parse HEAD >>$(srcdir)/manifest.uuid || \
-           (printf "svn-r" >$(srcdir)/manifest.uuid ; \
-           svn info --show-item last-changed-revision >>$(srcdir)/manifest.uuid) || \
-           printf "unknown" >$(srcdir)/manifest.uuid)
-
-sampleUuid.h:  $(srcdir)/manifest.uuid
-       echo "#define SAMPLE_VERSION_UUID \\" >$@
-       cat $(srcdir)/manifest.uuid >>$@
-       echo "" >>$@
 
 #========================================================================
 # Distribution creation
@@ -451,6 +437,8 @@ install-bin-binaries: binaries
          fi; \
        done
 
+.SUFFIXES: .c .$(OBJEXT)
+
 Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
        cd $(top_builddir) \
          && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
index ea7eb930f295a29f15e521da5000fa5b958346ba..a5217756eef095e788ac8988aefde77ab6b244d5 100644 (file)
@@ -1,27 +1,48 @@
 This is the SQLite extension for Tcl using the Tcl Extension
-Architecture (TEA).  For additional information on SQLite see
+Architecture (TEA). 
 
-        http://www.sqlite.org/
-
--------------------------------------------------------------------
-Update 2024-10-11:
+----------------------- A BETTER WAY ---------------------------
 
 A better way to build the TCL extension for SQLite is to use the
 canonical source code tarball.  For Unix:
 
-   ./configure --with-tclsh=$(TCLSH)
-   make tclextension-install
+    ./configure --with-tclsh=$(TCLSH)
+    make tclextension-install
 
 For Windows:
 
-   nmake /f Makefile.msc tclextension-install TCLSH_CMD=$(TCLSH)
+    nmake /f Makefile.msc tclextension-install TCLSH_CMD=$(TCLSH)
 
 In both of the above, replace $(TCLSH) with the full pathname of
-of the tclsh that you want the SQLite extension to work with.
+of the tclsh that you want the SQLite extension to work with.  See
+step-by-step instructions at the links below for more information:
+
+    https://sqlite.org/src/doc/trunk/doc/compile-for-unix.md
+    https://sqlite.org/src/doc/trunk/doc/compile-for-windows.md
+
+The whole point of the amalgamation-autoconf tarball (in which this
+README.txt file is embedded) is to provide a means of compiling
+SQLite that does not require first installing TCL and/or "tclsh".
+The canonical Makefile in the SQLite source tree provides more
+capabilities (such as the the ability to run test cases to ensure
+that the build worked) and is better maintained.  The only
+downside of the canonical Makfile is that it requires a TCL
+installation.  But if you are wanting to build the TCL extension for
+SQLite, then presumably you already have a TCL installation.  So why
+not just use the more-capable and better-maintained canoncal Makefile?
+
+This TEA builder is derived from code found at
+
+    http://core.tcl-lang.org/tclconfig
+    http://core.tcl-lang.org/sampleextension
+
+The SQLite developers do not understand how it works.  It seems to
+work for us.  It might also work for you.  But we cannot promise that.
+
+If you want to use this TEA builder and it works for you, that's fine.
+But if you have trouble, your the first thing you should do is go back
+to using the canonical Makefile in the SQLite source tree.
 
-This TEA builder is antiquated.  It does not work for TCL9.  The
-SQLite devs don't know how to fix it.  If you would like to help
-fix it, contact us.
 ------------------------------------------------------------------
 
 
index 7c34c3f926031734a8e1a4234a7ab131bdefda3e..ec298b53740270ce82b326c4c2deaa5dcdec4596 100644 (file)
@@ -1,7 +1,7 @@
 #!/bin/sh
 # install - install a program, script, or datafile
 
-scriptversion=2011-04-20.01; # UTC
+scriptversion=2020-11-14.01; # UTC
 
 # This originates from X11R5 (mit/util/scripts/install.sh), which was
 # later released in X11R6 (xc/config/util/install.sh) with the
@@ -35,25 +35,21 @@ scriptversion=2011-04-20.01; # UTC
 # FSF changes to this file are in the public domain.
 #
 # Calling this script install-sh is preferred over install.sh, to prevent
-# `make' implicit rules from creating a file called install from it
+# 'make' implicit rules from creating a file called install from it
 # when there is no Makefile.
 #
 # This script is compatible with the BSD install script, but was written
 # from scratch.
 
+tab='  '
 nl='
 '
-IFS=" ""       $nl"
+IFS=" $tab$nl"
 
-# set DOITPROG to echo to test this script
+# Set DOITPROG to "echo" to test this script.
 
-# Don't use :- since 4.3BSD and earlier shells don't like it.
 doit=${DOITPROG-}
-if test -z "$doit"; then
-  doit_exec=exec
-else
-  doit_exec=$doit
-fi
+doit_exec=${doit:-exec}
 
 # Put in absolute file names if you don't have them in your path;
 # or use environment vars.
@@ -68,22 +64,16 @@ mvprog=${MVPROG-mv}
 rmprog=${RMPROG-rm}
 stripprog=${STRIPPROG-strip}
 
-posix_glob='?'
-initialize_posix_glob='
-  test "$posix_glob" != "?" || {
-    if (set -f) 2>/dev/null; then
-      posix_glob=
-    else
-      posix_glob=:
-    fi
-  }
-'
-
 posix_mkdir=
 
 # Desired mode of installed file.
 mode=0755
 
+# Create dirs (including intermediate dirs) using mode 755.
+# This is like GNU 'install' as of coreutils 8.32 (2020).
+mkdir_umask=22
+
+backupsuffix=
 chgrpcmd=
 chmodcmd=$chmodprog
 chowncmd=
@@ -97,7 +87,7 @@ dir_arg=
 dst_arg=
 
 copy_on_change=false
-no_target_directory=
+is_target_a_directory=possibly
 
 usage="\
 Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
@@ -114,19 +104,28 @@ Options:
      --version  display version info and exit.
 
   -c            (ignored)
-  -C            install only if different (preserve the last data modification time)
+  -C            install only if different (preserve data modification time)
   -d            create directories instead of installing files.
   -g GROUP      $chgrpprog installed files to GROUP.
   -m MODE       $chmodprog installed files to MODE.
   -o USER       $chownprog installed files to USER.
+  -p            pass -p to $cpprog.
   -s            $stripprog installed files.
-  -S            $stripprog installed files.
+  -S SUFFIX     attempt to back up existing files, with suffix SUFFIX.
   -t DIRECTORY  install into DIRECTORY.
   -T            report an error if DSTFILE is a directory.
 
 Environment variables override the default commands:
   CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
   RMPROG STRIPPROG
+
+By default, rm is invoked with -f; when overridden with RMPROG,
+it's up to you to specify -f if you want it.
+
+If -S is not specified, no backups are attempted.
+
+Email bug reports to bug-automake@gnu.org.
+Automake home page: https://www.gnu.org/software/automake/
 "
 
 while test $# -ne 0; do
@@ -138,45 +137,62 @@ while test $# -ne 0; do
     -d) dir_arg=true;;
 
     -g) chgrpcmd="$chgrpprog $2"
-       shift;;
+        shift;;
 
     --help) echo "$usage"; exit $?;;
 
     -m) mode=$2
-       case $mode in
-         *' '* | *'    '* | *'
-'*       | *'*'* | *'?'* | *'['*)
-           echo "$0: invalid mode: $mode" >&2
-           exit 1;;
-       esac
-       shift;;
+        case $mode in
+          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
+            echo "$0: invalid mode: $mode" >&2
+            exit 1;;
+        esac
+        shift;;
 
     -o) chowncmd="$chownprog $2"
-       shift;;
+        shift;;
+
+    -p) cpprog="$cpprog -p";;
 
     -s) stripcmd=$stripprog;;
 
-    -S) stripcmd="$stripprog $2"
-       shift;;
+    -S) backupsuffix="$2"
+        shift;;
 
-    -t) dst_arg=$2
-       shift;;
+    -t)
+        is_target_a_directory=always
+        dst_arg=$2
+        # Protect names problematic for 'test' and other utilities.
+        case $dst_arg in
+          -* | [=\(\)!]) dst_arg=./$dst_arg;;
+        esac
+        shift;;
 
-    -T) no_target_directory=true;;
+    -T) is_target_a_directory=never;;
 
     --version) echo "$0 $scriptversion"; exit $?;;
 
-    --)        shift
-       break;;
+    --) shift
+        break;;
 
-    -*)        echo "$0: invalid option: $1" >&2
-       exit 1;;
+    -*) echo "$0: invalid option: $1" >&2
+        exit 1;;
 
     *)  break;;
   esac
   shift
 done
 
+# We allow the use of options -d and -T together, by making -d
+# take the precedence; this is for compatibility with GNU install.
+
+if test -n "$dir_arg"; then
+  if test -n "$dst_arg"; then
+    echo "$0: target directory not allowed when installing a directory." >&2
+    exit 1
+  fi
+fi
+
 if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
   # When -d is used, all remaining arguments are directories to create.
   # When -t is used, the destination is already specified.
@@ -190,6 +206,10 @@ if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
     fi
     shift # arg
     dst_arg=$arg
+    # Protect names problematic for 'test' and other utilities.
+    case $dst_arg in
+      -* | [=\(\)!]) dst_arg=./$dst_arg;;
+    esac
   done
 fi
 
@@ -198,11 +218,20 @@ if test $# -eq 0; then
     echo "$0: no input file specified." >&2
     exit 1
   fi
-  # It's OK to call `install-sh -d' without argument.
+  # It's OK to call 'install-sh -d' without argument.
   # This can happen when creating conditional directories.
   exit 0
 fi
 
+if test -z "$dir_arg"; then
+  if test $# -gt 1 || test "$is_target_a_directory" = always; then
+    if test ! -d "$dst_arg"; then
+      echo "$0: $dst_arg: Is not a directory." >&2
+      exit 1
+    fi
+  fi
+fi
+
 if test -z "$dir_arg"; then
   do_exit='(exit $ret); exit $ret'
   trap "ret=129; $do_exit" 1
@@ -219,16 +248,16 @@ if test -z "$dir_arg"; then
 
     *[0-7])
       if test -z "$stripcmd"; then
-       u_plus_rw=
+        u_plus_rw=
       else
-       u_plus_rw='% 200'
+        u_plus_rw='% 200'
       fi
       cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
     *)
       if test -z "$stripcmd"; then
-       u_plus_rw=
+        u_plus_rw=
       else
-       u_plus_rw=,u+rw
+        u_plus_rw=,u+rw
       fi
       cp_umask=$mode$u_plus_rw;;
   esac
@@ -236,9 +265,9 @@ fi
 
 for src
 do
-  # Protect names starting with `-'.
+  # Protect names problematic for 'test' and other utilities.
   case $src in
-    -*) src=./$src;;
+    -* | [=\(\)!]) src=./$src;;
   esac
 
   if test -n "$dir_arg"; then
@@ -246,6 +275,10 @@ do
     dstdir=$dst
     test -d "$dstdir"
     dstdir_status=$?
+    # Don't chown directories that already exist.
+    if test $dstdir_status = 0; then
+      chowncmd=""
+    fi
   else
 
     # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
@@ -260,185 +293,150 @@ do
       echo "$0: no destination specified." >&2
       exit 1
     fi
-
     dst=$dst_arg
-    # Protect names starting with `-'.
-    case $dst in
-      -*) dst=./$dst;;
-    esac
 
-    # If destination is a directory, append the input filename; won't work
-    # if double slashes aren't ignored.
+    # If destination is a directory, append the input filename.
     if test -d "$dst"; then
-      if test -n "$no_target_directory"; then
-       echo "$0: $dst_arg: Is a directory" >&2
-       exit 1
+      if test "$is_target_a_directory" = never; then
+        echo "$0: $dst_arg: Is a directory" >&2
+        exit 1
       fi
       dstdir=$dst
-      dst=$dstdir/`basename "$src"`
+      dstbase=`basename "$src"`
+      case $dst in
+       */) dst=$dst$dstbase;;
+       *)  dst=$dst/$dstbase;;
+      esac
       dstdir_status=0
     else
-      # Prefer dirname, but fall back on a substitute if dirname fails.
-      dstdir=`
-       (dirname "$dst") 2>/dev/null ||
-       expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-            X"$dst" : 'X\(//\)[^/]' \| \
-            X"$dst" : 'X\(//\)$' \| \
-            X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
-       echo X"$dst" |
-           sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
-                  s//\1/
-                  q
-                }
-                /^X\(\/\/\)[^/].*/{
-                  s//\1/
-                  q
-                }
-                /^X\(\/\/\)$/{
-                  s//\1/
-                  q
-                }
-                /^X\(\/\).*/{
-                  s//\1/
-                  q
-                }
-                s/.*/./; q'
-      `
-
+      dstdir=`dirname "$dst"`
       test -d "$dstdir"
       dstdir_status=$?
     fi
   fi
 
+  case $dstdir in
+    */) dstdirslash=$dstdir;;
+    *)  dstdirslash=$dstdir/;;
+  esac
+
   obsolete_mkdir_used=false
 
   if test $dstdir_status != 0; then
     case $posix_mkdir in
       '')
-       # Create intermediate dirs using mode 755 as modified by the umask.
-       # This is like FreeBSD 'install' as of 1997-10-28.
-       umask=`umask`
-       case $stripcmd.$umask in
-         # Optimize common cases.
-         *[2367][2367]) mkdir_umask=$umask;;
-         .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
-
-         *[0-7])
-           mkdir_umask=`expr $umask + 22 \
-             - $umask % 100 % 40 + $umask % 20 \
-             - $umask % 10 % 4 + $umask % 2
-           `;;
-         *) mkdir_umask=$umask,go-w;;
-       esac
-
-       # With -d, create the new directory with the user-specified mode.
-       # Otherwise, rely on $mkdir_umask.
-       if test -n "$dir_arg"; then
-         mkdir_mode=-m$mode
+        # With -d, create the new directory with the user-specified mode.
+        # Otherwise, rely on $mkdir_umask.
+        if test -n "$dir_arg"; then
+          mkdir_mode=-m$mode
+        else
+          mkdir_mode=
+        fi
+
+        posix_mkdir=false
+       # The $RANDOM variable is not portable (e.g., dash).  Use it
+       # here however when possible just to lower collision chance.
+       tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+
+       trap '
+         ret=$?
+         rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
+         exit $ret
+       ' 0
+
+       # Because "mkdir -p" follows existing symlinks and we likely work
+       # directly in world-writeable /tmp, make sure that the '$tmpdir'
+       # directory is successfully created first before we actually test
+       # 'mkdir -p'.
+       if (umask $mkdir_umask &&
+           $mkdirprog $mkdir_mode "$tmpdir" &&
+           exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
+       then
+         if test -z "$dir_arg" || {
+              # Check for POSIX incompatibilities with -m.
+              # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+              # other-writable bit of parent directory when it shouldn't.
+              # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+              test_tmpdir="$tmpdir/a"
+              ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
+              case $ls_ld_tmpdir in
+                d????-?r-*) different_mode=700;;
+                d????-?--*) different_mode=755;;
+                *) false;;
+              esac &&
+              $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
+                ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
+                test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+              }
+            }
+         then posix_mkdir=:
+         fi
+         rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
        else
-         mkdir_mode=
+         # Remove any dirs left behind by ancient mkdir implementations.
+         rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
        fi
-
-       posix_mkdir=false
-       case $umask in
-         *[123567][0-7][0-7])
-           # POSIX mkdir -p sets u+wx bits regardless of umask, which
-           # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
-           ;;
-         *)
-           tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
-           trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
-
-           if (umask $mkdir_umask &&
-               exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
-           then
-             if test -z "$dir_arg" || {
-                  # Check for POSIX incompatibilities with -m.
-                  # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
-                  # other-writeable bit of parent directory when it shouldn't.
-                  # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
-                  ls_ld_tmpdir=`ls -ld "$tmpdir"`
-                  case $ls_ld_tmpdir in
-                    d????-?r-*) different_mode=700;;
-                    d????-?--*) different_mode=755;;
-                    *) false;;
-                  esac &&
-                  $mkdirprog -m$different_mode -p -- "$tmpdir" && {
-                    ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
-                    test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
-                  }
-                }
-             then posix_mkdir=:
-             fi
-             rmdir "$tmpdir/d" "$tmpdir"
-           else
-             # Remove any dirs left behind by ancient mkdir implementations.
-             rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
-           fi
-           trap '' 0;;
-       esac;;
+       trap '' 0;;
     esac
 
     if
       $posix_mkdir && (
-       umask $mkdir_umask &&
-       $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+        umask $mkdir_umask &&
+        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
       )
     then :
     else
 
-      # The umask is ridiculous, or mkdir does not conform to POSIX,
+      # mkdir does not conform to POSIX,
       # or it failed possibly due to a race condition.  Create the
       # directory the slow way, step by step, checking for races as we go.
 
       case $dstdir in
-       /*) prefix='/';;
-       -*) prefix='./';;
-       *)  prefix='';;
+        /*) prefix='/';;
+        [-=\(\)!]*) prefix='./';;
+        *)  prefix='';;
       esac
 
-      eval "$initialize_posix_glob"
-
       oIFS=$IFS
       IFS=/
-      $posix_glob set -f
+      set -f
       set fnord $dstdir
       shift
-      $posix_glob set +f
+      set +f
       IFS=$oIFS
 
       prefixes=
 
       for d
       do
-       test -z "$d" && continue
-
-       prefix=$prefix$d
-       if test -d "$prefix"; then
-         prefixes=
-       else
-         if $posix_mkdir; then
-           (umask=$mkdir_umask &&
-            $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
-           # Don't fail if two instances are running concurrently.
-           test -d "$prefix" || exit 1
-         else
-           case $prefix in
-             *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
-             *) qprefix=$prefix;;
-           esac
-           prefixes="$prefixes '$qprefix'"
-         fi
-       fi
-       prefix=$prefix/
+        test X"$d" = X && continue
+
+        prefix=$prefix$d
+        if test -d "$prefix"; then
+          prefixes=
+        else
+          if $posix_mkdir; then
+            (umask $mkdir_umask &&
+             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+            # Don't fail if two instances are running concurrently.
+            test -d "$prefix" || exit 1
+          else
+            case $prefix in
+              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+              *) qprefix=$prefix;;
+            esac
+            prefixes="$prefixes '$qprefix'"
+          fi
+        fi
+        prefix=$prefix/
       done
 
       if test -n "$prefixes"; then
-       # Don't fail if two instances are running concurrently.
-       (umask $mkdir_umask &&
-        eval "\$doit_exec \$mkdirprog $prefixes") ||
-         test -d "$dstdir" || exit 1
-       obsolete_mkdir_used=true
+        # Don't fail if two instances are running concurrently.
+        (umask $mkdir_umask &&
+         eval "\$doit_exec \$mkdirprog $prefixes") ||
+          test -d "$dstdir" || exit 1
+        obsolete_mkdir_used=true
       fi
     fi
   fi
@@ -451,14 +449,25 @@ do
   else
 
     # Make a couple of temp file names in the proper directory.
-    dsttmp=$dstdir/_inst.$$_
-    rmtmp=$dstdir/_rm.$$_
+    dsttmp=${dstdirslash}_inst.$$_
+    rmtmp=${dstdirslash}_rm.$$_
 
     # Trap to clean up those temp files at exit.
     trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
 
     # Copy the file name to the temp name.
-    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+    (umask $cp_umask &&
+     { test -z "$stripcmd" || {
+        # Create $dsttmp read-write so that cp doesn't create it read-only,
+        # which would cause strip to fail.
+        if test -z "$doit"; then
+          : >"$dsttmp" # No need to fork-exec 'touch'.
+        else
+          $doit touch "$dsttmp"
+        fi
+       }
+     } &&
+     $doit_exec $cpprog "$src" "$dsttmp") &&
 
     # and set any options; do chmod last to preserve setuid bits.
     #
@@ -473,20 +482,24 @@ do
 
     # If -C, don't bother to copy if it wouldn't change the file.
     if $copy_on_change &&
-       old=`LC_ALL=C ls -dlL "$dst"    2>/dev/null` &&
-       new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
-
-       eval "$initialize_posix_glob" &&
-       $posix_glob set -f &&
+       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
+       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
+       set -f &&
        set X $old && old=:$2:$4:$5:$6 &&
        set X $new && new=:$2:$4:$5:$6 &&
-       $posix_glob set +f &&
-
+       set +f &&
        test "$old" = "$new" &&
        $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
     then
       rm -f "$dsttmp"
     else
+      # If $backupsuffix is set, and the file being installed
+      # already exists, attempt a backup.  Don't worry if it fails,
+      # e.g., if mv doesn't support -f.
+      if test -n "$backupsuffix" && test -f "$dst"; then
+        $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
+      fi
+
       # Rename the file to the real destination.
       $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
 
@@ -494,24 +507,24 @@ do
       # to itself, or perhaps because mv is so ancient that it does not
       # support -f.
       {
-       # Now remove or move aside any old file at destination location.
-       # We try this two ways since rm can't unlink itself on some
-       # systems and the destination file might be busy for other
-       # reasons.  In this case, the final cleanup might fail but the new
-       # file should still install successfully.
-       {
-         test ! -f "$dst" ||
-         $doit $rmcmd -f "$dst" 2>/dev/null ||
-         { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
-           { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
-         } ||
-         { echo "$0: cannot unlink or rename $dst" >&2
-           (exit 1); exit 1
-         }
-       } &&
-
-       # Now rename the file to the real destination.
-       $doit $mvcmd "$dsttmp" "$dst"
+        # Now remove or move aside any old file at destination location.
+        # We try this two ways since rm can't unlink itself on some
+        # systems and the destination file might be busy for other
+        # reasons.  In this case, the final cleanup might fail but the new
+        # file should still install successfully.
+        {
+          test ! -f "$dst" ||
+          $doit $rmcmd "$dst" 2>/dev/null ||
+          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+            { $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
+          } ||
+          { echo "$0: cannot unlink or rename $dst" >&2
+            (exit 1); exit 1
+          }
+        } &&
+
+        # Now rename the file to the real destination.
+        $doit $mvcmd "$dsttmp" "$dst"
       }
     fi || exit 1
 
@@ -520,9 +533,9 @@ do
 done
 
 # Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
 # time-stamp-start: "scriptversion="
 # time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
+# time-stamp-time-zone: "UTC0"
 # time-stamp-end: "; # UTC"
 # End:
index 455a7964d10fa35dd45c96eaad7d1e1a0dc4f6d2..237d50a7bd567fcd3845782170e350bde26bedb3 100644 (file)
@@ -53,6 +53,10 @@ AC_DEFUN([TEA_PATH_TCLCONFIG], [
            AS_HELP_STRING([--with-tcl],
                [directory containing tcl configuration (tclConfig.sh)]),
            [with_tclconfig="${withval}"])
+       AC_ARG_WITH(tcl8,
+           AS_HELP_STRING([--with-tcl8],
+               [Compile for Tcl8 in Tcl9 environment]),
+           [with_tcl8="${withval}"])
        AC_MSG_CHECKING([for Tcl configuration])
        AC_CACHE_VAL(ac_cv_c_tclconfig,[
 
@@ -138,10 +142,16 @@ AC_DEFUN([TEA_PATH_TCLCONFIG], [
                        `ls -d /usr/pkg/lib 2>/dev/null` \
                        `ls -d /usr/lib 2>/dev/null` \
                        `ls -d /usr/lib64 2>/dev/null` \
+                       `ls -d /usr/lib/tcl9.0 2>/dev/null` \
+                       `ls -d /usr/lib/tcl8.7 2>/dev/null` \
                        `ls -d /usr/lib/tcl8.6 2>/dev/null` \
                        `ls -d /usr/lib/tcl8.5 2>/dev/null` \
+                       `ls -d /usr/local/lib/tcl9.0 2>/dev/null` \
+                       `ls -d /usr/local/lib/tcl8.7 2>/dev/null` \
                        `ls -d /usr/local/lib/tcl8.6 2>/dev/null` \
                        `ls -d /usr/local/lib/tcl8.5 2>/dev/null` \
+                       `ls -d /usr/local/lib/tcl/tcl9.0 2>/dev/null` \
+                       `ls -d /usr/local/lib/tcl/tcl8.7 2>/dev/null` \
                        `ls -d /usr/local/lib/tcl/tcl8.6 2>/dev/null` \
                        `ls -d /usr/local/lib/tcl/tcl8.5 2>/dev/null` \
                        ; do
@@ -282,12 +292,18 @@ AC_DEFUN([TEA_PATH_TKCONFIG], [
                        `ls -d /usr/local/lib 2>/dev/null` \
                        `ls -d /usr/contrib/lib 2>/dev/null` \
                        `ls -d /usr/pkg/lib 2>/dev/null` \
+                       `ls -d /usr/lib/tk9.0 2>/dev/null` \
+                       `ls -d /usr/lib/tk8.7 2>/dev/null` \
                        `ls -d /usr/lib/tk8.6 2>/dev/null` \
                        `ls -d /usr/lib/tk8.5 2>/dev/null` \
                        `ls -d /usr/lib 2>/dev/null` \
                        `ls -d /usr/lib64 2>/dev/null` \
+                       `ls -d /usr/local/lib/tk9.0 2>/dev/null` \
+                       `ls -d /usr/local/lib/tk8.7 2>/dev/null` \
                        `ls -d /usr/local/lib/tk8.6 2>/dev/null` \
                        `ls -d /usr/local/lib/tk8.5 2>/dev/null` \
+                       `ls -d /usr/local/lib/tcl/tk9.0 2>/dev/null` \
+                       `ls -d /usr/local/lib/tcl/tk8.7 2>/dev/null` \
                        `ls -d /usr/local/lib/tcl/tk8.6 2>/dev/null` \
                        `ls -d /usr/local/lib/tcl/tk8.5 2>/dev/null` \
                        ; do
@@ -366,10 +382,10 @@ AC_DEFUN([TEA_LOAD_TCLCONFIG], [
     AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh])
 
     if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then
-        AC_MSG_RESULT([loading])
+       AC_MSG_RESULT([loading])
        . "${TCL_BIN_DIR}/tclConfig.sh"
     else
-        AC_MSG_RESULT([could not find ${TCL_BIN_DIR}/tclConfig.sh])
+       AC_MSG_RESULT([could not find ${TCL_BIN_DIR}/tclConfig.sh])
     fi
 
     # If the TCL_BIN_DIR is the build directory (not the install directory),
@@ -379,9 +395,9 @@ AC_DEFUN([TEA_LOAD_TCLCONFIG], [
     # instead of TCL_BUILD_LIB_SPEC since it will work with both an
     # installed and uninstalled version of Tcl.
     if test -f "${TCL_BIN_DIR}/Makefile" ; then
-        TCL_LIB_SPEC="${TCL_BUILD_LIB_SPEC}"
-        TCL_STUB_LIB_SPEC="${TCL_BUILD_STUB_LIB_SPEC}"
-        TCL_STUB_LIB_PATH="${TCL_BUILD_STUB_LIB_PATH}"
+       TCL_LIB_SPEC="${TCL_BUILD_LIB_SPEC}"
+       TCL_STUB_LIB_SPEC="${TCL_BUILD_STUB_LIB_SPEC}"
+       TCL_STUB_LIB_PATH="${TCL_BUILD_STUB_LIB_PATH}"
     elif test "`uname -s`" = "Darwin"; then
        # If Tcl was built as a framework, attempt to use the libraries
        # from the framework at the given location so that linking works
@@ -474,10 +490,10 @@ AC_DEFUN([TEA_LOAD_TKCONFIG], [
     AC_MSG_CHECKING([for existence of ${TK_BIN_DIR}/tkConfig.sh])
 
     if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then
-        AC_MSG_RESULT([loading])
+       AC_MSG_RESULT([loading])
        . "${TK_BIN_DIR}/tkConfig.sh"
     else
-        AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh])
+       AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh])
     fi
 
     # If the TK_BIN_DIR is the build directory (not the install directory),
@@ -487,9 +503,9 @@ AC_DEFUN([TEA_LOAD_TKCONFIG], [
     # instead of TK_BUILD_LIB_SPEC since it will work with both an
     # installed and uninstalled version of Tcl.
     if test -f "${TK_BIN_DIR}/Makefile" ; then
-        TK_LIB_SPEC="${TK_BUILD_LIB_SPEC}"
-        TK_STUB_LIB_SPEC="${TK_BUILD_STUB_LIB_SPEC}"
-        TK_STUB_LIB_PATH="${TK_BUILD_STUB_LIB_PATH}"
+       TK_LIB_SPEC="${TK_BUILD_LIB_SPEC}"
+       TK_STUB_LIB_SPEC="${TK_BUILD_STUB_LIB_SPEC}"
+       TK_STUB_LIB_PATH="${TK_BUILD_STUB_LIB_PATH}"
     elif test "`uname -s`" = "Darwin"; then
        # If Tk was built as a framework, attempt to use the libraries
        # from the framework at the given location so that linking works
@@ -567,37 +583,37 @@ AC_DEFUN([TEA_LOAD_TKCONFIG], [
 AC_DEFUN([TEA_PROG_TCLSH], [
     AC_MSG_CHECKING([for tclsh])
     if test -f "${TCL_BIN_DIR}/Makefile" ; then
-        # tclConfig.sh is in Tcl build directory
-        if test "${TEA_PLATFORM}" = "windows"; then
-          if test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${EXEEXT}" ; then
-            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${EXEEXT}"
-          elif test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}s${EXEEXT}" ; then
-            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}s${EXEEXT}"
-          elif test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}t${EXEEXT}" ; then
-            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}t${EXEEXT}"
-          elif test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}st${EXEEXT}" ; then
-            TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}st${EXEEXT}"
-          fi
-        else
-            TCLSH_PROG="${TCL_BIN_DIR}/tclsh"
-        fi
+       # tclConfig.sh is in Tcl build directory
+       if test "${TEA_PLATFORM}" = "windows"; then
+         if test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${EXEEXT}" ; then
+           TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${EXEEXT}"
+         elif test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}s${EXEEXT}" ; then
+           TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}s${EXEEXT}"
+         elif test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}t${EXEEXT}" ; then
+           TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}t${EXEEXT}"
+         elif test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}st${EXEEXT}" ; then
+           TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}st${EXEEXT}"
+         fi
+       else
+           TCLSH_PROG="${TCL_BIN_DIR}/tclsh"
+       fi
     else
-        # tclConfig.sh is in install location
-        if test "${TEA_PLATFORM}" = "windows"; then
-            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${EXEEXT}"
-        else
-            TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}"
-        fi
-        list="`ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null` \
-              `ls -d ${TCL_BIN_DIR}/..     2>/dev/null` \
-              `ls -d ${TCL_PREFIX}/bin     2>/dev/null`"
-        for i in $list ; do
-            if test -f "$i/${TCLSH_PROG}" ; then
-                REAL_TCL_BIN_DIR="`cd "$i"; pwd`/"
-                break
-            fi
-        done
-        TCLSH_PROG="${REAL_TCL_BIN_DIR}${TCLSH_PROG}"
+       # tclConfig.sh is in install location
+       if test "${TEA_PLATFORM}" = "windows"; then
+           TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${EXEEXT}"
+       else
+           TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}"
+       fi
+       list="`ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null` \
+             `ls -d ${TCL_BIN_DIR}/..     2>/dev/null` \
+             `ls -d ${TCL_PREFIX}/bin     2>/dev/null`"
+       for i in $list ; do
+           if test -f "$i/${TCLSH_PROG}" ; then
+               REAL_TCL_BIN_DIR="`cd "$i"; pwd`/"
+               break
+           fi
+       done
+       TCLSH_PROG="${REAL_TCL_BIN_DIR}${TCLSH_PROG}"
     fi
     AC_MSG_RESULT([${TCLSH_PROG}])
     AC_SUBST(TCLSH_PROG)
@@ -625,37 +641,37 @@ AC_DEFUN([TEA_PROG_TCLSH], [
 AC_DEFUN([TEA_PROG_WISH], [
     AC_MSG_CHECKING([for wish])
     if test -f "${TK_BIN_DIR}/Makefile" ; then
-        # tkConfig.sh is in Tk build directory
-        if test "${TEA_PLATFORM}" = "windows"; then
-          if test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${EXEEXT}" ; then
-            WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${EXEEXT}"
-          elif test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}s${EXEEXT}" ; then
-            WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}$s{EXEEXT}"
-          elif test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}t${EXEEXT}" ; then
-            WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}t${EXEEXT}"
-          elif test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}st${EXEEXT}" ; then
-            WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}st${EXEEXT}"
-          fi
-        else
-            WISH_PROG="${TK_BIN_DIR}/wish"
-        fi
+       # tkConfig.sh is in Tk build directory
+       if test "${TEA_PLATFORM}" = "windows"; then
+         if test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${EXEEXT}" ; then
+           WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${EXEEXT}"
+         elif test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}s${EXEEXT}" ; then
+           WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}$s{EXEEXT}"
+         elif test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}t${EXEEXT}" ; then
+           WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}t${EXEEXT}"
+         elif test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}st${EXEEXT}" ; then
+           WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}st${EXEEXT}"
+         fi
+       else
+           WISH_PROG="${TK_BIN_DIR}/wish"
+       fi
     else
-        # tkConfig.sh is in install location
-        if test "${TEA_PLATFORM}" = "windows"; then
-            WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${EXEEXT}"
-        else
-            WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}"
-        fi
-        list="`ls -d ${TK_BIN_DIR}/../bin 2>/dev/null` \
-              `ls -d ${TK_BIN_DIR}/..     2>/dev/null` \
-              `ls -d ${TK_PREFIX}/bin     2>/dev/null`"
-        for i in $list ; do
-            if test -f "$i/${WISH_PROG}" ; then
-                REAL_TK_BIN_DIR="`cd "$i"; pwd`/"
-                break
-            fi
-        done
-        WISH_PROG="${REAL_TK_BIN_DIR}${WISH_PROG}"
+       # tkConfig.sh is in install location
+       if test "${TEA_PLATFORM}" = "windows"; then
+           WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${EXEEXT}"
+       else
+           WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}"
+       fi
+       list="`ls -d ${TK_BIN_DIR}/../bin 2>/dev/null` \
+             `ls -d ${TK_BIN_DIR}/..     2>/dev/null` \
+             `ls -d ${TK_PREFIX}/bin     2>/dev/null`"
+       for i in $list ; do
+           if test -f "$i/${WISH_PROG}" ; then
+               REAL_TK_BIN_DIR="`cd "$i"; pwd`/"
+               break
+           fi
+       done
+       WISH_PROG="${REAL_TK_BIN_DIR}${WISH_PROG}"
     fi
     AC_MSG_RESULT([${WISH_PROG}])
     AC_SUBST(WISH_PROG)
@@ -717,22 +733,22 @@ AC_DEFUN([TEA_ENABLE_SHARED], [
     if test "$shared_ok" = "yes" ; then
        AC_MSG_RESULT([shared])
        SHARED_BUILD=1
-        STUBS_BUILD=1
+       STUBS_BUILD=1
     else
        AC_MSG_RESULT([static])
        SHARED_BUILD=0
        AC_DEFINE(STATIC_BUILD, 1, [This a static build])
-        if test "$stubs_ok" = "yes" ; then
-          STUBS_BUILD=1
-        else
-          STUBS_BUILD=0
-        fi
+       if test "$stubs_ok" = "yes" ; then
+         STUBS_BUILD=1
+       else
+         STUBS_BUILD=0
+       fi
     fi
     if test "${STUBS_BUILD}" = "1" ; then
       AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs])
       AC_DEFINE(USE_TCLOO_STUBS, 1, [Use TclOO stubs])
       if test "${TEA_WINDOWINGSYSTEM}" != ""; then
-        AC_DEFINE(USE_TK_STUBS, 1, [Use Tk stubs])
+       AC_DEFINE(USE_TK_STUBS, 1, [Use Tk stubs])
       fi
     fi
 
@@ -1177,21 +1193,21 @@ AC_DEFUN([TEA_CONFIG_CFLAGS], [
            fi
 
            if test "$GCC" != "yes" ; then
-               if test "${SHARED_BUILD}" = "0" ; then
+               if test "${SHARED_BUILD}" = "0" ; then
                    runtime=-MT
-               else
+               else
                    runtime=-MD
-               fi
-               case "x`echo \${VisualStudioVersion}`" in
-                   x1[[4-9]]*)
-                       lflags="${lflags} -nodefaultlib:libucrt.lib"
-                       TEA_ADD_LIBS([ucrt.lib])
-                   ;;
-                   *)
-                   ;;
-               esac
-
-                if test "$do64bit" != "no" ; then
+               fi
+               case "x`echo \${VisualStudioVersion}`" in
+                   x1[[4-9]]*)
+                       lflags="${lflags} -nodefaultlib:libucrt.lib"
+                       TEA_ADD_LIBS([ucrt.lib])
+                   ;;
+                   *)
+                   ;;
+               esac
+
+               if test "$do64bit" != "no" ; then
                    CC="cl.exe"
                    RC="rc.exe"
                    lflags="${lflags} -nologo -MACHINE:${MACHINE} "
@@ -1490,14 +1506,14 @@ AC_DEFUN([TEA_CONFIG_CFLAGS], [
            # Check to enable 64-bit flags for compiler/linker
 
            AS_IF([test "$do64bit" = yes], [
-               AS_IF([test "$GCC" = yes], [
-                   AC_MSG_WARN([64bit mode not supported by gcc])
-               ], [
-                   do64bit_ok=yes
-                   SHLIB_LD="ld -64 -shared -rdata_shared"
-                   CFLAGS="$CFLAGS -64"
-                   LDFLAGS_ARCH="-64"
-               ])
+               AS_IF([test "$GCC" = yes], [
+                   AC_MSG_WARN([64bit mode not supported by gcc])
+               ], [
+                   do64bit_ok=yes
+                   SHLIB_LD="ld -64 -shared -rdata_shared"
+                   CFLAGS="$CFLAGS -64"
+                   LDFLAGS_ARCH="-64"
+               ])
            ])
            ;;
        Linux*|GNU*|NetBSD-Debian|DragonFly-*|FreeBSD-*)
@@ -1519,7 +1535,7 @@ AC_DEFUN([TEA_CONFIG_CFLAGS], [
                    CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
                    LDFLAGS="$LDFLAGS $PTHREAD_LIBS"])
            ;;
-            esac
+           esac
 
            AS_IF([test $doRpath = yes], [
                CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"'])
@@ -1724,9 +1740,9 @@ AC_DEFUN([TEA_CONFIG_CFLAGS], [
            # Digital OSF/1
            SHLIB_CFLAGS=""
            AS_IF([test "$SHARED_BUILD" = 1], [
-               SHLIB_LD='ld -shared -expect_unresolved "*"'
+               SHLIB_LD='ld -shared -expect_unresolved "*"'
            ], [
-               SHLIB_LD='ld -non_shared -expect_unresolved "*"'
+               SHLIB_LD='ld -non_shared -expect_unresolved "*"'
            ])
            SHLIB_SUFFIX=".so"
            AS_IF([test $doRpath = yes], [
@@ -1896,7 +1912,7 @@ AC_DEFUN([TEA_CONFIG_CFLAGS], [
                LDFLAGS="$LDFLAGS -Wl,-Bexport"
                AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[int i;]])],
                        [tcl_cv_ld_Bexport=yes],[tcl_cv_ld_Bexport=no])
-               LDFLAGS=$hold_ldflags])
+               LDFLAGS=$hold_ldflags])
            AS_IF([test $tcl_cv_ld_Bexport = yes], [
                LDFLAGS="$LDFLAGS -Wl,-Bexport"
            ])
@@ -2015,8 +2031,8 @@ dnl # preprocessing tests use only CPPFLAGS.
                SHORT s;
                LONG l;
            ]])],
-        [tcl_cv_winnt_ignore_void=yes],
-        [tcl_cv_winnt_ignore_void=no])
+       [tcl_cv_winnt_ignore_void=yes],
+       [tcl_cv_winnt_ignore_void=no])
        )
        if test "$tcl_cv_winnt_ignore_void" = "yes" ; then
            AC_DEFINE(HAVE_WINNT_IGNORE_VOID, 1,
@@ -2529,20 +2545,19 @@ AC_DEFUN([TEA_TCL_LINK_LIBS], [
 #
 #      Might define the following vars:
 #              _ISOC99_SOURCE
-#              _LARGEFILE64_SOURCE
-#              _LARGEFILE_SOURCE64
+#              _FILE_OFFSET_BITS
 #
 #--------------------------------------------------------------------
 
 AC_DEFUN([TEA_TCL_EARLY_FLAG],[
     AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]),
        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[$2]], [[$3]])],
-           [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[[#define ]$1[ 1
+           [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[[#define ]$1[ ]m4_default([$4],[1])[
 ]$2]], [[$3]])],
        [tcl_cv_flag_]translit($1,[A-Z],[a-z])=yes,
        [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no)]))
     if test ["x${tcl_cv_flag_]translit($1,[A-Z],[a-z])[}" = "xyes"] ; then
-       AC_DEFINE($1, 1, [Add the ]$1[ flag when building])
+       AC_DEFINE($1, m4_default([$4],[1]), [Add the ]$1[ flag when building])
        tcl_flags="$tcl_flags $1"
     fi
 ])
@@ -2552,10 +2567,10 @@ AC_DEFUN([TEA_TCL_EARLY_FLAGS],[
     tcl_flags=""
     TEA_TCL_EARLY_FLAG(_ISOC99_SOURCE,[#include <stdlib.h>],
        [char *p = (char *)strtoll; char *q = (char *)strtoull;])
-    TEA_TCL_EARLY_FLAG(_LARGEFILE64_SOURCE,[#include <sys/stat.h>],
-       [struct stat64 buf; int i = stat64("/", &buf);])
-    TEA_TCL_EARLY_FLAG(_LARGEFILE_SOURCE64,[#include <sys/stat.h>],
-       [char *p = (char *)open64;])
+    if test "${TCL_MAJOR_VERSION}" -ne 8 ; then
+       TEA_TCL_EARLY_FLAG(_FILE_OFFSET_BITS,[#include <sys/stat.h>],
+           [switch (0) { case 0: case (sizeof(off_t)==sizeof(long long)): ; }],64)
+    fi
     if test "x${tcl_flags}" = "x" ; then
        AC_MSG_RESULT([none])
     else
@@ -2579,6 +2594,7 @@ AC_DEFUN([TEA_TCL_EARLY_FLAGS],[
 #              HAVE_STRUCT_DIRENT64, HAVE_DIR64
 #              HAVE_STRUCT_STAT64
 #              HAVE_TYPE_OFF64_T
+#              _TIME_BITS
 #
 #--------------------------------------------------------------------
 
@@ -2592,9 +2608,9 @@ AC_DEFUN([TEA_TCL_64BIT_FLAGS], [
        # See if we could use long anyway  Note that we substitute in the
        # type that is our current guess for a 64-bit type inside this check
        # program, so it should be modified only carefully...
-        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[switch (0) {
-            case 1: case (sizeof(${tcl_type_64bit})==sizeof(long)): ;
-        }]])],[tcl_cv_type_64bit=${tcl_type_64bit}],[])])
+       AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[switch (0) {
+           case 1: case (sizeof(${tcl_type_64bit})==sizeof(long)): ;
+       }]])],[tcl_cv_type_64bit=${tcl_type_64bit}],[])])
     if test "${tcl_cv_type_64bit}" = none ; then
        AC_DEFINE(TCL_WIDE_INT_IS_LONG, 1, [Do 'long' and 'long long' have the same size (64-bit)?])
        AC_MSG_RESULT([yes])
@@ -2609,6 +2625,25 @@ AC_DEFUN([TEA_TCL_64BIT_FLAGS], [
        AC_MSG_RESULT([${tcl_cv_type_64bit}])
 
        # Now check for auxiliary declarations
+    if test "${TCL_MAJOR_VERSION}" -ne 8 ; then
+           AC_CACHE_CHECK([for 64-bit time_t], tcl_cv_time_t_64,[
+               AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>]],
+                   [[switch (0) {case 0: case (sizeof(time_t)==sizeof(long long)): ;}]])],
+                   [tcl_cv_time_t_64=yes],[tcl_cv_time_t_64=no])])
+           if test "x${tcl_cv_time_t_64}" = "xno" ; then
+               # Note that _TIME_BITS=64 requires _FILE_OFFSET_BITS=64
+               # which SC_TCL_EARLY_FLAGS has defined if necessary.
+               AC_CACHE_CHECK([if _TIME_BITS=64 enables 64-bit time_t], tcl_cv__time_bits,[
+                   AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#define _TIME_BITS 64
+#include <sys/types.h>]],
+                       [[switch (0) {case 0: case (sizeof(time_t)==sizeof(long long)): ;}]])],
+                       [tcl_cv__time_bits=yes],[tcl_cv__time_bits=no])])
+               if test "x${tcl_cv__time_bits}" = "xyes" ; then
+                   AC_DEFINE(_TIME_BITS, 64, [_TIME_BITS=64 enables 64-bit time_t.])
+               fi
+           fi
+       fi
+
        AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[
            AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
 #include <dirent.h>]], [[struct dirent64 p;]])],
@@ -2620,7 +2655,7 @@ AC_DEFUN([TEA_TCL_64BIT_FLAGS], [
        AC_CACHE_CHECK([for DIR64], tcl_cv_DIR64,[
            AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
 #include <dirent.h>]], [[struct dirent64 *p; DIR64 d = opendir64(".");
-            p = readdir64(d); rewinddir64(d); closedir64(d);]])],
+           p = readdir64(d); rewinddir64(d); closedir64(d);]])],
                [tcl_cv_DIR64=yes], [tcl_cv_DIR64=no])])
        if test "x${tcl_cv_DIR64}" = "xyes" ; then
            AC_DEFINE(HAVE_DIR64, 1, [Is 'DIR64' in <sys/types.h>?])
@@ -2643,8 +2678,8 @@ AC_DEFUN([TEA_TCL_64BIT_FLAGS], [
        dnl Define HAVE_TYPE_OFF64_T only when the off64_t type and the
        dnl functions lseek64 and open64 are defined.
        if test "x${tcl_cv_type_off64_t}" = "xyes" && \
-               test "x${ac_cv_func_lseek64}" = "xyes" && \
-               test "x${ac_cv_func_open64}" = "xyes" ; then
+               test "x${ac_cv_func_lseek64}" = "xyes" && \
+               test "x${ac_cv_func_open64}" = "xyes" ; then
            AC_DEFINE(HAVE_TYPE_OFF64_T, 1, [Is off64_t in <sys/types.h>?])
            AC_MSG_RESULT([yes])
        else
@@ -2747,8 +2782,6 @@ The PACKAGE_NAME variable must be defined by your TEA configure.ac])
     AC_SUBST(PKG_LIB_FILE)
     AC_SUBST(PKG_LIB_FILE8)
     AC_SUBST(PKG_LIB_FILE9)
-    # Substitute STUB_LIB_FILE in case package creates a stub library too.
-    AC_SUBST(PKG_STUB_LIB_FILE)
 
     # We AC_SUBST these here to ensure they are subst'ed,
     # in case the user doesn't call TEA_ADD_...
@@ -3106,11 +3139,15 @@ AC_DEFUN([TEA_SETUP_COMPILER], [
        fi
     fi
 
+    if test "${TCL_MAJOR_VERSION}" -lt 9 -a "${TCL_MINOR_VERSION}" -lt 7; then
+           AC_DEFINE(Tcl_Size, int, [Is 'Tcl_Size' in <tcl.h>?])
+       fi
+
     #--------------------------------------------------------------------
     # Common compiler flag setup
     #--------------------------------------------------------------------
 
-    AC_C_BIGENDIAN
+    AC_C_BIGENDIAN(,,,[#])
 ])
 
 #------------------------------------------------------------------------
@@ -3174,10 +3211,11 @@ print("manifest needed")
 
     PACKAGE_LIB_PREFIX8="${PACKAGE_LIB_PREFIX}"
     PACKAGE_LIB_PREFIX9="${PACKAGE_LIB_PREFIX}tcl9"
-    if test "${TCL_MAJOR_VERSION}" -gt 8 ; then
+    if test "${TCL_MAJOR_VERSION}" -gt 8 -a x"${with_tcl8}" = x; then
        PACKAGE_LIB_PREFIX="${PACKAGE_LIB_PREFIX9}"
     else
        PACKAGE_LIB_PREFIX="${PACKAGE_LIB_PREFIX8}"
+       AC_DEFINE(TCL_MAJOR_VERSION, 8, [Compile for Tcl8?])
     fi
     if test "${TEA_PLATFORM}" = "windows" ; then
        if test "${SHARED_BUILD}" = "1" ; then
@@ -3202,7 +3240,11 @@ print("manifest needed")
            eval eval "PKG_LIB_FILE=${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
        fi
        # Some packages build their own stubs libraries
-       eval eval "PKG_STUB_LIB_FILE=${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+       if test "${TCL_MAJOR_VERSION}" -gt 8 -a x"${with_tcl8}" = x; then
+           eval eval "PKG_STUB_LIB_FILE=${PACKAGE_LIB_PREFIX8}${PACKAGE_NAME}stub.a"
+       else
+           eval eval "PKG_STUB_LIB_FILE=${PACKAGE_LIB_PREFIX8}${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+       fi
        if test "$GCC" = "yes"; then
            PKG_STUB_LIB_FILE=lib${PKG_STUB_LIB_FILE}
        fi
@@ -3221,12 +3263,16 @@ print("manifest needed")
            eval eval "PKG_LIB_FILE=lib${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${SHARED_LIB_SUFFIX}"
            RANLIB=:
        else
-           eval eval "PKG_LIB_FILE=lib${PACKAGE_LIB_PREFIX8}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
-           eval eval "PKG_LIB_FILE=lib${PACKAGE_LIB_PREFIX9}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+           eval eval "PKG_LIB_FILE8=lib${PACKAGE_LIB_PREFIX8}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
+           eval eval "PKG_LIB_FILE9=lib${PACKAGE_LIB_PREFIX9}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
            eval eval "PKG_LIB_FILE=lib${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}"
        fi
        # Some packages build their own stubs libraries
-       eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_LIB_PREFIX8}${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+       if test "${TCL_MAJOR_VERSION}" -gt 8 -a x"${with_tcl8}" = x; then
+           eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_LIB_PREFIX8}${PACKAGE_NAME}stub.a"
+       else
+           eval eval "PKG_STUB_LIB_FILE=lib${PACKAGE_LIB_PREFIX8}${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}"
+       fi
     fi
 
     # These are escaped so that only CFLAGS is picked up at configure time.
@@ -3240,6 +3286,8 @@ print("manifest needed")
     AC_SUBST(MAKE_SHARED_LIB)
     AC_SUBST(MAKE_STATIC_LIB)
     AC_SUBST(MAKE_STUB_LIB)
+    # Substitute STUB_LIB_FILE in case package creates a stub library too.
+    AC_SUBST(PKG_STUB_LIB_FILE)
     AC_SUBST(RANLIB_STUB)
     AC_SUBST(VC_MANIFEST_EMBED_DLL)
     AC_SUBST(VC_MANIFEST_EMBED_EXE)
@@ -3366,9 +3414,9 @@ AC_DEFUN([TEA_PRIVATE_TCL_HEADERS], [
        # any *_NATIVE vars be defined in the Makefile
        TCL_INCLUDES="-I${TCL_GENERIC_DIR_NATIVE} -I${TCL_PLATFORM_DIR_NATIVE}"
        if test "`uname -s`" = "Darwin"; then
-            # If Tcl was built as a framework, attempt to use
-            # the framework's Headers and PrivateHeaders directories
-            case ${TCL_DEFS} in
+           # If Tcl was built as a framework, attempt to use
+           # the framework's Headers and PrivateHeaders directories
+           case ${TCL_DEFS} in
                *TCL_FRAMEWORK*)
                    if test -d "${TCL_BIN_DIR}/Headers" -a \
                            -d "${TCL_BIN_DIR}/PrivateHeaders"; then
@@ -3376,7 +3424,7 @@ AC_DEFUN([TEA_PRIVATE_TCL_HEADERS], [
                    else
                        TCL_INCLUDES="${TCL_INCLUDES} ${TCL_INCLUDE_SPEC} `echo "${TCL_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`"
                    fi
-                   ;;
+                   ;;
            esac
            result="Using ${TCL_INCLUDES}"
        else
@@ -3817,10 +3865,10 @@ AC_DEFUN([TEA_LOAD_CONFIG], [
     AC_MSG_CHECKING([for existence of ${$1_BIN_DIR}/$1Config.sh])
 
     if test -f "${$1_BIN_DIR}/$1Config.sh" ; then
-        AC_MSG_RESULT([loading])
+       AC_MSG_RESULT([loading])
        . "${$1_BIN_DIR}/$1Config.sh"
     else
-        AC_MSG_RESULT([file not found])
+       AC_MSG_RESULT([file not found])
     fi
 
     #
@@ -3834,11 +3882,11 @@ AC_DEFUN([TEA_LOAD_CONFIG], [
 
     if test -f "${$1_BIN_DIR}/Makefile" ; then
        AC_MSG_WARN([Found Makefile - using build library specs for $1])
-        $1_LIB_SPEC=${$1_BUILD_LIB_SPEC}
-        $1_STUB_LIB_SPEC=${$1_BUILD_STUB_LIB_SPEC}
-        $1_STUB_LIB_PATH=${$1_BUILD_STUB_LIB_PATH}
-        $1_INCLUDE_SPEC=${$1_BUILD_INCLUDE_SPEC}
-        $1_LIBRARY_PATH=${$1_LIBRARY_PATH}
+       $1_LIB_SPEC=${$1_BUILD_LIB_SPEC}
+       $1_STUB_LIB_SPEC=${$1_BUILD_STUB_LIB_SPEC}
+       $1_STUB_LIB_PATH=${$1_BUILD_STUB_LIB_PATH}
+       $1_INCLUDE_SPEC=${$1_BUILD_INCLUDE_SPEC}
+       $1_LIBRARY_PATH=${$1_LIBRARY_PATH}
     fi
 
     AC_SUBST($1_VERSION)
@@ -3919,6 +3967,10 @@ AC_DEFUN([TEA_EXPORT_CONFIG], [
        eval $1_LIB_FLAG="-l$1`echo ${PACKAGE_VERSION} | tr -d .`"
        eval $1_STUB_LIB_FLAG="-l$1stub`echo ${PACKAGE_VERSION} | tr -d .`"
     fi
+    if test "${TCL_MAJOR_VERSION}" -gt 8 -a x"${with_tcl8}" = x; then
+       eval $1_STUB_LIB_FLAG="-l$1stub"
+    fi
+
     $1_BUILD_LIB_SPEC="-L`$CYGPATH $(pwd)` ${$1_LIB_FLAG}"
     $1_LIB_SPEC="-L`$CYGPATH ${pkglibdir}` ${$1_LIB_FLAG}"
     $1_BUILD_STUB_LIB_SPEC="-L`$CYGPATH $(pwd)` [$]{$1_STUB_LIB_FLAG}"
@@ -4008,52 +4060,52 @@ AC_DEFUN([TEA_ZIPFS_SUPPORT], [
     AC_CACHE_VAL(ac_cv_path_macher, [
     search_path=`echo ${PATH} | sed -e 's/:/ /g'`
     for dir in $search_path ; do
-        for j in `ls -r $dir/macher 2> /dev/null` \
-            `ls -r $dir/macher 2> /dev/null` ; do
-        if test x"$ac_cv_path_macher" = x ; then
-            if test -f "$j" ; then
-            ac_cv_path_macher=$j
-            break
-            fi
-        fi
-        done
+       for j in `ls -r $dir/macher 2> /dev/null` \
+           `ls -r $dir/macher 2> /dev/null` ; do
+       if test x"$ac_cv_path_macher" = x ; then
+           if test -f "$j" ; then
+           ac_cv_path_macher=$j
+           break
+           fi
+       fi
+       done
     done
     ])
     if test -f "$ac_cv_path_macher" ; then
-        MACHER_PROG="$ac_cv_path_macher"
-        AC_MSG_RESULT([$MACHER_PROG])
-        AC_MSG_RESULT([Found macher in environment])
+       MACHER_PROG="$ac_cv_path_macher"
+       AC_MSG_RESULT([$MACHER_PROG])
+       AC_MSG_RESULT([Found macher in environment])
     fi
     AC_MSG_CHECKING([for zip])
     AC_CACHE_VAL(ac_cv_path_zip, [
     search_path=`echo ${PATH} | sed -e 's/:/ /g'`
     for dir in $search_path ; do
-        for j in `ls -r $dir/zip 2> /dev/null` \
-            `ls -r $dir/zip 2> /dev/null` ; do
-        if test x"$ac_cv_path_zip" = x ; then
-            if test -f "$j" ; then
-            ac_cv_path_zip=$j
-            break
-            fi
-        fi
-        done
+       for j in `ls -r $dir/zip 2> /dev/null` \
+           `ls -r $dir/zip 2> /dev/null` ; do
+       if test x"$ac_cv_path_zip" = x ; then
+           if test -f "$j" ; then
+           ac_cv_path_zip=$j
+           break
+           fi
+       fi
+       done
     done
     ])
     if test -f "$ac_cv_path_zip" ; then
-        ZIP_PROG="$ac_cv_path_zip"
-        AC_MSG_RESULT([$ZIP_PROG])
-        ZIP_PROG_OPTIONS="-rq"
-        ZIP_PROG_VFSSEARCH="*"
-        AC_MSG_RESULT([Found INFO Zip in environment])
-        # Use standard arguments for zip
+       ZIP_PROG="$ac_cv_path_zip"
+       AC_MSG_RESULT([$ZIP_PROG])
+       ZIP_PROG_OPTIONS="-rq"
+       ZIP_PROG_VFSSEARCH="*"
+       AC_MSG_RESULT([Found INFO Zip in environment])
+       # Use standard arguments for zip
     else
-        # It is not an error if an installed version of Zip can't be located.
-        # We can use the locally distributed minizip instead
-        ZIP_PROG="./minizip${EXEEXT_FOR_BUILD}"
-        ZIP_PROG_OPTIONS="-o -r"
-        ZIP_PROG_VFSSEARCH="*"
-        ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}"
-        AC_MSG_RESULT([No zip found on PATH. Building minizip])
+       # It is not an error if an installed version of Zip can't be located.
+       # We can use the locally distributed minizip instead
+       ZIP_PROG="./minizip${EXEEXT_FOR_BUILD}"
+       ZIP_PROG_OPTIONS="-o -r"
+       ZIP_PROG_VFSSEARCH="*"
+       ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}"
+       AC_MSG_RESULT([No zip found on PATH. Building minizip])
     fi
     AC_SUBST(MACHER_PROG)
     AC_SUBST(ZIP_PROG)
index dacb7c6b3ac5782d0ce3721c0745d9bee04fa9fd..bb32f1a75cd110bb30b1c20506f65eb1355e997d 100644 (file)
-# makefile.vc --                                               -*- Makefile -*-
+#------------------------------------------------------------- -*- makefile -*-
 #
-# Microsoft Visual C++ makefile for use with nmake.exe v1.62+ (VC++ 5.0+)
+# Sample makefile for building Tcl extensions.
 #
-# This makefile is based upon the Tcl 8.4 Makefile.vc and modified to 
-# make it suitable as a general package makefile. Look for the word EDIT
-# which marks sections that may need modification. As a minumum you will
-# need to change the PROJECT, DOTVERSION and DLLOBJS variables to values
-# relevant to your package.
+# Basic build, test and install
+#   nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\tcl
+#   nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\tcl test
+#   nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\tcl install
+#
+# For other build options (debug, static etc.)
+# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
+# detailed documentation.
 #
 # See the file "license.terms" for information on usage and redistribution
 # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-# 
-# Copyright (c) 1995-1996 Sun Microsystems, Inc.
-# Copyright (c) 1998-2000 Ajuba Solutions.
-# Copyright (c) 2001 ActiveState Corporation.
-# Copyright (c) 2001-2002 David Gravereaux.
-# Copyright (c) 2003 Pat Thoyts
 #
-#-------------------------------------------------------------------------
-# RCS: @(#)$Id: makefile.vc,v 1.4 2004/07/26 08:22:05 patthoyts Exp $
-#-------------------------------------------------------------------------
-
-!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(VCINSTALLDIR) && !defined(MSSDK) && !defined(WINDOWSSDKDIR)
-MSG = ^
-You will need to run vcvars32.bat from Developer Studio, first, to setup^
-the environment.  Jump to this line to read the new instructions.
-!error $(MSG)
-!endif
-
 #------------------------------------------------------------------------------
-# HOW TO USE this makefile:
-#
-# 1)  It is now necessary to have %MSVCDir% set in the environment.  This is
-#     used  as a check to see if vcvars32.bat had been run prior to running
-#     nmake or during the installation of Microsoft Visual C++, MSVCDir had
-#     been set globally and the PATH adjusted.  Either way is valid.
-#
-#     You'll need to run vcvars32.bat contained in the MsDev's vc(98)/bin
-#     directory to setup the proper environment, if needed, for your current
-#     setup.  This is a needed bootstrap requirement and allows the swapping of
-#     different environments to be easier.
-#
-# 2)  To use the Platform SDK (not expressly needed), run setenv.bat after
-#     vcvars32.bat according to the instructions for it.  This can also turn on
-#     the 64-bit compiler, if your SDK has it.
-#
-# 3)  Targets are:
-#      all       -- Builds everything.
-#       <project> -- Builds the project (eg: nmake sample)
-#      test      -- Builds and runs the test suite.
-#      install   -- Installs the built binaries and libraries to $(INSTALLDIR)
-#                   in an appropriate subdirectory.
-#      clean/realclean/distclean -- varying levels of cleaning.
-#
-# 4)  Macros usable on the commandline:
-#      INSTALLDIR=<path>
-#              Sets where to install Tcl from the built binaries.
-#              C:\Progra~1\Tcl is assumed when not specified.
-#
-#      OPTS=static,msvcrt,staticpkg,threads,symbols,profile,loimpact,none
-#              Sets special options for the core.  The default is for none.
-#              Any combination of the above may be used (comma separated).
-#              'none' will over-ride everything to nothing.
-#
-#              static  =  Builds a static library of the core instead of a
-#                         dll.  The shell will be static (and large), as well.
-#              msvcrt  =  Effects the static option only to switch it from
-#                         using libcmt(d) as the C runtime [by default] to
-#                         msvcrt(d). This is useful for static embedding
-#                         support.
-#              staticpkg = Effects the static option only to switch
-#                         tclshXX.exe to have the dde and reg extension linked
-#                         inside it.
-#              threads =  Turns on full multithreading support.
-#              thrdalloc = Use the thread allocator (shared global free pool).
-#              symbols =  Adds symbols for step debugging.
-#              profile =  Adds profiling hooks.  Map file is assumed.
-#              loimpact =  Adds a flag for how NT treats the heap to keep memory
-#                         in use, low.  This is said to impact alloc performance.
-#
-#      STATS=memdbg,compdbg,none
-#              Sets optional memory and bytecode compiler debugging code added
-#              to the core.  The default is for none.  Any combination of the
-#              above may be used (comma separated).  'none' will over-ride
-#              everything to nothing.
-#
-#              memdbg   = Enables the debugging memory allocator.
-#              compdbg  = Enables byte compilation logging.
-#
-#      MACHINE=(IX86|IA64|ALPHA)
-#              Set the machine type used for the compiler, linker, and
-#              resource compiler.  This hook is needed to tell the tools
-#              when alternate platforms are requested.  IX86 is the default
-#              when not specified.
-#
-#      TMP_DIR=<path>
-#      OUT_DIR=<path>
-#              Hooks to allow the intermediate and output directories to be
-#              changed.  $(OUT_DIR) is assumed to be 
-#              $(BINROOT)\(Release|Debug) based on if symbols are requested.
-#              $(TMP_DIR) will de $(OUT_DIR)\<buildtype> by default.
-#
-#      TESTPAT=<file>
-#              Reads the tests requested to be run from this file.
-#
-#      CFG_ENCODING=encoding
-#              name of encoding for configuration information. Defaults
-#              to cp1252
-#
-# 5)  Examples:
-#
-#      Basic syntax of calling nmake looks like this:
-#      nmake [-nologo] -f makefile.vc [target|macrodef [target|macrodef] [...]]
-#
-#                        Standard (no frills)
-#       c:\tcl_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat
-#       Setting environment for using Microsoft Visual C++ tools.
-#       c:\tcl_src\win\>nmake -f makefile.vc all
-#       c:\tcl_src\win\>nmake -f makefile.vc install INSTALLDIR=c:\progra~1\tcl
-#
-#                         Building for Win64
-#       c:\tcl_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat
-#       Setting environment for using Microsoft Visual C++ tools.
-#       c:\tcl_src\win\>c:\progra~1\platfo~1\setenv.bat /pre64 /RETAIL
-#       Targeting Windows pre64 RETAIL
-#       c:\tcl_src\win\>nmake -f makefile.vc MACHINE=IA64
-#
-#------------------------------------------------------------------------------
-#==============================================================================
-###############################################################################
-#------------------------------------------------------------------------------
-
-!if !exist("makefile.vc")
-MSG = ^
-You must run this makefile only from the directory it is in.^
-Please `cd` to its location first.
-!error $(MSG)
-!endif
-
-#-------------------------------------------------------------------------
-# Project specific information (EDIT)
-#
-# You should edit this with the name and version of your project. This
-# information is used to generate the name of the package library and
-# it's install location.
-#
-# For example, the sample extension is  going to build sample04.dll and
-# would install it into $(INSTALLDIR)\lib\sample04
-#
-# You need to specify the object files that need to be linked into your
-# binary here.
-#
-#-------------------------------------------------------------------------
-
-PROJECT = sqlite3
-!include "rules.vc"
-
-# nmakehelp -V <file> <tag> will search the file for tag, skips until a
-#      number and returns all character until a character not in [0-9.ab]
-#      is read.
-
-!if [echo REM = This file is generated from Makefile.vc > versions.vc]
-!endif
-# get project version from row "AC_INIT([sqlite], [3.x.y])"
-!if [echo DOTVERSION = \>> versions.vc] \
-   && [nmakehlp -V ..\configure.ac AC_INIT >> versions.vc]
-!endif
-!include "versions.vc"
-
-VERSION         = $(DOTVERSION:.=)
-STUBPREFIX      = $(PROJECT)stub
-
-#-------------------------------------------------------------------------
-# Target names and paths ( shouldn't need changing )
-#-------------------------------------------------------------------------
-
-BINROOT                = .
-ROOT            = ..
-
-PRJIMPLIB      = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
-PRJLIBNAME     = $(PROJECT).$(EXT)
-PRJLIB         = $(OUT_DIR)\$(PRJLIBNAME)
-
-PRJSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
-PRJSTUBLIB     = $(OUT_DIR)\$(PRJSTUBLIBNAME)
 
-### Make sure we use backslash only.
-PRJ_INSTALL_DIR         = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
-LIB_INSTALL_DIR                = $(PRJ_INSTALL_DIR)
-BIN_INSTALL_DIR                = $(PRJ_INSTALL_DIR)
-DOC_INSTALL_DIR                = $(PRJ_INSTALL_DIR)
-SCRIPT_INSTALL_DIR     = $(PRJ_INSTALL_DIR)
-INCLUDE_INSTALL_DIR    = $(_TCLDIR)\include
+# PROJECT is sqlite, not sqlite3 to match TEA AC_INIT definition.
+# This makes the generated DLL name also consistent between the two
+# except for the "t" suffix which is the convention for nmake builds.
+PROJECT = sqlite
+PRJ_PACKAGE_TCLNAME = sqlite3
 
-### The following paths CANNOT have spaces in them.
-GENERICDIR     = $(ROOT)\generic
-WINDIR         = $(ROOT)\win
-LIBDIR          = $(ROOT)\library
-DOCDIR         = $(ROOT)\doc
-TOOLSDIR       = $(ROOT)\tools
-COMPATDIR      = $(ROOT)\compat
+!include "rules-ext.vc"
 
-### Figure out where the primary source code file(s) is/are.
-!if exist("$(ROOT)\..\..\sqlite3.c") && exist("$(ROOT)\..\..\src\tclsqlite.c")
-SQL_INCLUDES = -I"$(ROOT)\..\.."
-SQLITE_SRCDIR = $(ROOT)\..\..
-TCLSQLITE_SRCDIR = $(ROOT)\..\..\src
-DLLOBJS = $(TMP_DIR)\sqlite3.obj $(TMP_DIR)\tclsqlite.obj
-!else
-TCLSQLITE_SRCDIR = $(ROOT)\generic
-DLLOBJS = $(TMP_DIR)\tclsqlite3.obj
-!endif
+PRJ_OBJS = $(TMP_DIR)\tclsqlite3.obj
 
-#---------------------------------------------------------------------
-# Compile flags
-#---------------------------------------------------------------------
-
-!if !$(DEBUG)
-!if $(OPTIMIZING)
-### This cranks the optimization level to maximize speed
-cdebug = -O2 -Op -Gs
-!else
-cdebug =
-!endif
-!else if "$(MACHINE)" == "IA64"
-### Warnings are too many, can't support warnings into errors.
-cdebug = -Z7 -Od -GZ
-!else
-cdebug = -Z7 -WX -Od -GZ
-!endif
-
-### Declarations common to all compiler options
-cflags = -nologo -c -W3 -D_CRT_SECURE_NO_WARNINGS -YX -Fp$(TMP_DIR)^\
-
-!if $(MSVCRT)
-!if $(DEBUG)
-crt = -MDd
-!else
-crt = -MD
-!endif
-!else
-!if $(DEBUG)
-crt = -MTd
-!else
-crt = -MT
-!endif
-!endif
-
-INCLUDES       = $(SQL_INCLUDES) $(TCL_INCLUDES) -I"$(WINDIR)" \
-                  -I"$(GENERICDIR)" -I"$(ROOT)\.."
-BASE_CLFAGS    = $(cflags) $(cdebug) $(crt) $(INCLUDES) \
+# Preprocessor macros specific to sqlite3.
+PRJ_DEFINES = -I"$(ROOT)\.." -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE \
+                  -DSQLITE_ENABLE_DBPAGE_VTAB=1 -DSQLITE_ENABLE_DBSTAT_VTAB=1 \
+                  -DSQLITE_ENABLE_FTS3_PARENTHESIS=1 -DSQLITE_ENABLE_FTS4=1 \
+                  -DSQLITE_ENABLE_FTS5=1 -DSQLITE_ENABLE_COLUMN_METADATA=1 \
+                  -DSQLITE_ENABLE_JSON1=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS=1 \
                   -DSQLITE_3_SUFFIX_ONLY=1 -DSQLITE_ENABLE_RTREE=1 \
-                  -DSQLITE_ENABLE_FTS3=1 -DSQLITE_OMIT_DEPRECATED=1 \
-                  -DSQLITE_ENABLE_FTS4=1 \
-                  -DSQLITE_ENABLE_FTS5=1 \
-                  -DSQLITE_3_SUFFIX_ONLY=1 \
-                  -DSQLITE_ENABLE_RTREE=1 \
-                  -DSQLITE_ENABLE_GEOPOLY=1 \
-                  -DSQLITE_ENABLE_MATH_FUNCTIONS=1 \
-                  -DSQLITE_ENABLE_DESERIALIZE=1 \
-                  -DSQLITE_ENABLE_DBPAGE_VTAB=1 \
-                  -DSQLITE_ENABLE_BYTECODE_VTAB=1 \
-                  -DSQLITE_ENABLE_DBSTAT_VTAB=1 
-
-CON_CFLAGS     = $(cflags) $(cdebug) $(crt) -DCONSOLE -DSQLITE_ENABLE_FTS3=1
-TCL_CFLAGS     = -DBUILD_sqlite -DUSE_TCL_STUBS \
-                  -DPACKAGE_VERSION="\"$(DOTVERSION)\"" $(BASE_CLFAGS) \
-                  $(OPTDEFINES)
-
-#---------------------------------------------------------------------
-# Link flags
-#---------------------------------------------------------------------
-
-!if $(DEBUG)
-ldebug = -debug:full -debugtype:cv
-!else
-ldebug = -release -opt:ref -opt:icf,3
-!endif
-
-### Declarations common to all linker options
-lflags = -nologo -machine:$(MACHINE) $(ldebug)
-
-!if $(PROFILE)
-lflags = $(lflags) -profile
-!endif
-
-!if $(ALIGN98_HACK) && !$(STATIC_BUILD)
-### Align sections for PE size savings.
-lflags = $(lflags) -opt:nowin98
-!else if !$(ALIGN98_HACK) && $(STATIC_BUILD)
-### Align sections for speed in loading by choosing the virtual page size.
-lflags = $(lflags) -align:4096
-!endif
-
-!if $(LOIMPACT)
-lflags = $(lflags) -ws:aggressive
-!endif
-
-dlllflags = $(lflags) -dll
-conlflags = $(lflags) -subsystem:console
-guilflags = $(lflags) -subsystem:windows
-baselibs   = $(TCLSTUBLIB)
-
-#---------------------------------------------------------------------
-# TclTest flags
-#---------------------------------------------------------------------
-
-!IF "$(TESTPAT)" != ""
-TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
-!ENDIF
-
-#---------------------------------------------------------------------
-# Project specific targets (EDIT)
-#---------------------------------------------------------------------
-
-all:       setup $(PROJECT)
-$(PROJECT): setup $(PRJLIB)
-install:    install-binaries install-libraries install-docs
-
-# Tests need to ensure we load the right dll file we
-# have to handle the output differently on Win9x.
-#
-!if "$(OS)" == "Windows_NT"  || "$(MSVCDIR)" == "IDE"
-test: setup $(PROJECT)
-        set TCL_LIBRARY=$(ROOT)/library
-        $(TCLSH) <<
-load $(PRJLIB:\=/)
-cd "$(ROOT)/tests"
-set argv "$(TESTFLAGS)"
-source all.tcl
-<<
-!else
-test: setup $(PROJECT)
-        echo Please wait while the test results are collected
-        set TCL_LIBRARY=$(ROOT)/library
-        $(TCLSH) << >tests.log
-load $(PRJLIB:\=/)
-cd "$(ROOT)/tests"
-set argv "$(TESTFLAGS)"
-source all.tcl
-<<
-        type tests.log | more
-!endif
-
-setup:
-       @if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
-       @if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
-
-$(PRJLIB): $(DLLOBJS)
-       $(link32) $(dlllflags) -out:$@ $(baselibs) @<<
-$**
-<<
-       -@del $*.exp
-
-$(PRJSTUBLIB): $(PRJSTUBOBJS)
-       $(lib32) -nologo -out:$@ $(PRJSTUBOBJS)
-
-#---------------------------------------------------------------------
-# Implicit rules
-#---------------------------------------------------------------------
-
-$(TMP_DIR)\sqlite3.obj:                $(SQLITE_SRCDIR)\sqlite3.c
-       $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ \
-               -c $(SQLITE_SRCDIR)\sqlite3.c
-
-$(TMP_DIR)\tclsqlite.obj:      $(TCLSQLITE_SRCDIR)\tclsqlite.c
-       $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ \
-               -c $(TCLSQLITE_SRCDIR)\tclsqlite.c
-
-$(TMP_DIR)\tclsqlite3.obj:     $(TCLSQLITE_SRCDIR)\tclsqlite3.c
-       $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ \
-               -c $(TCLSQLITE_SRCDIR)\tclsqlite3.c
-
-{$(WINDIR)}.rc{$(TMP_DIR)}.res:
-       $(rc32) -fo $@ -r -i "$(GENERICDIR)" -D__WIN32__ \
-!if $(DEBUG)
-       -d DEBUG \
-!endif
-!if $(TCL_THREADS)
-       -d TCL_THREADS \
-!endif
-!if $(STATIC_BUILD)
-       -d STATIC_BUILD \
-!endif
-       $<
-
-.SUFFIXES:
-.SUFFIXES:.c .rc
-
-#---------------------------------------------------------------------
-# Installation. (EDIT)
-#
-# You may need to modify this section to reflect the final distribution
-# of your files and possibly to generate documentation.
-#
-#---------------------------------------------------------------------
-
-install-binaries:
-       @echo Installing binaries to '$(SCRIPT_INSTALL_DIR)'
-       @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
-       @$(CPY) $(PRJLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
-
-install-libraries:
-        @echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
-        @if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)"
-        @echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
-        @type << >"$(SCRIPT_INSTALL_DIR)\pkgIndex.tcl"
-package ifneeded $(PROJECT) $(DOTVERSION) \
-    [list load [file join $$dir $(PRJLIBNAME)] Sqlite3]
-<<
-
-install-docs:
-       @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
-       @if exist $(DOCDIR) $(CPY) $(DOCDIR)\*.n "$(DOC_INSTALL_DIR)"
-
-#---------------------------------------------------------------------
-# Clean up
-#---------------------------------------------------------------------
-
-clean:
-       @if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
-       @if exist $(WINDIR)\version.vc del $(WINDIR)\version.vc
-
-realclean: clean
-       @if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
-
-distclean: realclean
-       @if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
-       @if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
+                  -DSQLITE_UNTESTABLE=1 -DSQLITE_OMIT_LOOKASIDE=1 \
+                  -DSQLITE_SECURE_DELETE=1 -DSQLITE_SOUNDEX=1 -DSQLITE_ENABLE_GEOPOLY=1 \
+                  -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1 \
+                  -DSQLITE_ENABLE_MATH_FUNCTIONS=1 -DDSQLITE_USE_ALLOCA=1 \
+                  -DSQLITE_ENABLE_STAT4=1 -DSQLITE_OMIT_DEPRECATED=1 \
+                  -DSQLITE_WIN32_GETVERSIONEX=0 -DSQLITE_WIN32_NO_ANSI=1
+PRJ_DEFINES = $(PRJ_DEFINES) -I$(TMP_DIR)
+
+# Standard targets to build, install, test etc.
+!include "$(_RULESDIR)\targets.vc"
+
+# The built-in pkgindex does no suffice for our extension as
+# the PROJECT name (sqlite) is not same as init function name (Sqlite3)
+pkgindex:
+       @echo if {[package vsatisfies [package provide Tcl] 9.0-]} { > $(OUT_DIR)\pkgIndex.tcl
+       @echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
+           [list load [file join $$dir $(PRJLIBNAME9)] [string totitle $(PRJ_PACKAGE_TCLNAME)]] >> $(OUT_DIR)\pkgIndex.tcl
+       @echo } else { >> $(OUT_DIR)\pkgIndex.tcl
+       @echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
+           [list load [file join $$dir $(PRJLIBNAME8)] [string totitle $(PRJ_PACKAGE_TCLNAME)]] >> $(OUT_DIR)\pkgIndex.tcl
+       @echo } >> $(OUT_DIR)\pkgIndex.tcl
+
+# Install the manpage though on Windows, doubt it does much good
+install:    default-install-docs-n
+
+# Explicit dependency rules
diff --git a/autoconf/tea/win/rules-ext.vc b/autoconf/tea/win/rules-ext.vc
new file mode 100644 (file)
index 0000000..479720a
--- /dev/null
@@ -0,0 +1,123 @@
+# This file should only be included in makefiles for Tcl extensions,
+# NOT in the makefile for Tcl itself.
+
+!ifndef _RULES_EXT_VC
+
+# We need to run from the directory the parent makefile is located in.
+# nmake does not tell us what makefile was used to invoke it so parent
+# makefile has to set the MAKEFILEVC macro or we just make a guess and
+# warn if we think that is not the case.
+!if "$(MAKEFILEVC)" == ""
+
+!if exist("$(PROJECT).vc")
+MAKEFILEVC = $(PROJECT).vc
+!elseif exist("makefile.vc")
+MAKEFILEVC = makefile.vc
+!endif
+!endif # "$(MAKEFILEVC)" == ""
+
+!if !exist("$(MAKEFILEVC)")
+MSG = ^
+You must run nmake from the directory containing the project makefile.^
+If you are doing that and getting this message, set the MAKEFILEVC^
+macro to the name of the project makefile.
+!message WARNING: $(MSG)
+!endif
+
+!if "$(PROJECT)" == "tcl"
+!error The rules-ext.vc file is not intended for Tcl itself.
+!endif
+
+# We extract version numbers using the nmakehlp program. For now use
+# the local copy of nmakehlp. Once we locate Tcl, we will use that
+# one if it is newer.
+!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
+!if [$(CC) -nologo -DNDEBUG "nmakehlp.c" -link -subsystem:console > nul]
+!endif
+!else
+!if [copy x86_64-w64-mingw32-nmakehlp.exe nmakehlp.exe >NUL]
+!endif
+!endif
+
+# First locate the Tcl directory that we are working with.
+!if "$(TCLDIR)" != ""
+
+_RULESDIR = $(TCLDIR:/=\)
+
+!else
+
+# If an installation path is specified, that is also the Tcl directory.
+# Also Tk never builds against an installed Tcl, it needs Tcl sources
+!if defined(INSTALLDIR) && "$(PROJECT)" != "tk"
+_RULESDIR=$(INSTALLDIR:/=\)
+!else
+# Locate Tcl sources
+!if [echo _RULESDIR = \> nmakehlp.out] \
+   || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
+_RULESDIR = ..\..\tcl
+!else
+!include nmakehlp.out
+!endif
+
+!endif # defined(INSTALLDIR)....
+
+!endif # ifndef TCLDIR
+
+# Now look for the targets.vc file under the Tcl root. Note we check this
+# file and not rules.vc because the latter also exists on older systems.
+!if exist("$(_RULESDIR)\lib\nmake\targets.vc") # Building against installed Tcl
+_RULESDIR = $(_RULESDIR)\lib\nmake
+!elseif exist("$(_RULESDIR)\win\targets.vc")   # Building against Tcl sources
+_RULESDIR = $(_RULESDIR)\win
+!else
+# If we have not located Tcl's targets file, most likely we are compiling
+# against an older version of Tcl and so must use our own support files.
+_RULESDIR = .
+!endif
+
+!if "$(_RULESDIR)" != "."
+# Potentially using Tcl's support files. If this extension has its own
+# nmake support files, need to compare the versions and pick newer.
+
+!if exist("rules.vc") # The extension has its own copy
+
+!if [echo TCL_RULES_MAJOR = \> versions.vc] \
+   && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MAJOR >> versions.vc]
+!endif
+!if [echo TCL_RULES_MINOR = \>> versions.vc] \
+   && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MINOR >> versions.vc]
+!endif
+
+!if [echo OUR_RULES_MAJOR = \>> versions.vc] \
+   && [nmakehlp -V "rules.vc" RULES_VERSION_MAJOR >> versions.vc]
+!endif
+!if [echo OUR_RULES_MINOR = \>> versions.vc] \
+   && [nmakehlp -V "rules.vc" RULES_VERSION_MINOR >> versions.vc]
+!endif
+!include versions.vc
+# We have a newer version of the support files, use them
+!if ($(TCL_RULES_MAJOR) != $(OUR_RULES_MAJOR)) || ($(TCL_RULES_MINOR) < $(OUR_RULES_MINOR))
+_RULESDIR = .
+!endif
+
+!endif # if exist("rules.vc")
+
+!endif # if $(_RULESDIR) != "."
+
+# Let rules.vc know what copy of nmakehlp.c to use.
+NMAKEHLPC = $(_RULESDIR)\nmakehlp.c
+
+# Get rid of our internal defines before calling rules.vc
+!undef TCL_RULES_MAJOR
+!undef TCL_RULES_MINOR
+!undef OUR_RULES_MAJOR
+!undef OUR_RULES_MINOR
+
+!if exist("$(_RULESDIR)\rules.vc")
+!message *** Using $(_RULESDIR)\rules.vc
+!include "$(_RULESDIR)\rules.vc"
+!else
+!error *** Could not locate rules.vc in $(_RULESDIR)
+!endif
+
+!endif # _RULES_EXT_VC
\ No newline at end of file
index f09e2ea48e70ff449260ba9df7078560e8f5a462..8ecce0e106e81dafadb7f8888b6fd2c872f5d264 100644 (file)
-#------------------------------------------------------------------------------
+#------------------------------------------------------------- -*- makefile -*-
 # rules.vc --
 #
-#      Microsoft Visual C++ makefile include for decoding the commandline
-#      macros.  This file does not need editing to build Tcl.
+# Part of the nmake based build system for Tcl and its extensions.
+# This file does all the hard work in terms of parsing build options,
+# compiler switches, defining common targets and macros. The Tcl makefile
+# directly includes this. Extensions include it via "rules-ext.vc".
+#
+# See TIP 477 (https://core.tcl-lang.org/tips/doc/main/tip/477.md) for
+# detailed documentation.
 #
 # See the file "license.terms" for information on usage and redistribution
 # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 #
 # Copyright (c) 2001-2003 David Gravereaux.
 # Copyright (c) 2003-2008 Patrick Thoyts
+# Copyright (c) 2017      Ashok P. Nadkarni
 #------------------------------------------------------------------------------
 
 !ifndef _RULES_VC
 _RULES_VC = 1
 
-cc32           = $(CC)   # built-in default.
-link32         = link
-lib32          = lib
-rc32           = $(RC)   # built-in default.
+# The following macros define the version of the rules.vc nmake build system
+# For modifications that are not backward-compatible, you *must* change
+# the major version.
+RULES_VERSION_MAJOR = 1
+RULES_VERSION_MINOR = 12
 
-!ifndef INSTALLDIR
-### Assume the normal default.
-_INSTALLDIR    = C:\Program Files\Tcl
+# The PROJECT macro must be defined by parent makefile.
+!if "$(PROJECT)" == ""
+!error *** Error: Macro PROJECT not defined! Please define it before including rules.vc
+!endif
+
+!if "$(PRJ_PACKAGE_TCLNAME)" == ""
+PRJ_PACKAGE_TCLNAME = $(PROJECT)
+!endif
+
+# Also special case Tcl and Tk to save some typing later
+DOING_TCL = 0
+DOING_TK  = 0
+!if "$(PROJECT)" == "tcl"
+DOING_TCL = 1
+!elseif "$(PROJECT)" == "tk"
+DOING_TK = 1
+!endif
+
+!ifndef NEED_TK
+# Backwards compatibility
+!ifdef PROJECT_REQUIRES_TK
+NEED_TK = $(PROJECT_REQUIRES_TK)
 !else
-### Fix the path separators.
-_INSTALLDIR    = $(INSTALLDIR:/=\)
+NEED_TK = 0
+!endif
+!endif
+
+!ifndef NEED_TCL_SOURCE
+NEED_TCL_SOURCE = 0
+!endif
+
+!ifdef NEED_TK_SOURCE
+!if $(NEED_TK_SOURCE)
+NEED_TK = 1
 !endif
+!else
+NEED_TK_SOURCE = 0
+!endif
+
+################################################################
+# Nmake is a pretty weak environment in syntax and capabilities
+# so this file is necessarily verbose. It's broken down into
+# the following parts.
+#
+# 0. Sanity check that compiler environment is set up and initialize
+#    any built-in settings from the parent makefile
+# 1. First define the external tools used for compiling, copying etc.
+#    as this is independent of everything else.
+# 2. Figure out our build structure in terms of the directory, whether
+#    we are building Tcl or an extension, etc.
+# 3. Determine the compiler and linker versions
+# 4. Build the nmakehlp helper application
+# 5. Determine the supported compiler options and features
+# 6. Extract Tcl, Tk, and possibly extensions, version numbers from the
+#    headers
+# 7. Parse the OPTS macro value for user-specified build configuration
+# 8. Parse the STATS macro value for statistics instrumentation
+# 9. Parse the CHECKS macro for additional compilation checks
+# 10. Based on this selected configuration, construct the output
+#     directory and file paths
+# 11. Construct the paths where the package is to be installed
+# 12. Set up the actual options passed to compiler and linker based
+#     on the information gathered above.
+# 13. Define some standard build targets and implicit rules. These may
+#     be optionally disabled by the parent makefile.
+# 14. (For extensions only.) Compare the configuration of the target
+#     Tcl and the extensions and warn against discrepancies.
+#
+# One final note about the macro names used. They are as they are
+# for historical reasons. We would like legacy extensions to
+# continue to work with this make include file so be wary of
+# changing them for consistency or clarity.
+
+# 0. Sanity check compiler environment
+
+# Check to see we are configured to build with MSVC (MSDEVDIR, MSVCDIR or
+# VCINSTALLDIR) or with the MS Platform SDK (MSSDK or WindowsSDKDir)
+
+!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(VCINSTALLDIR) && !defined(MSSDK) && !defined(WINDOWSSDKDIR)
+MSG = ^
+Visual C++ compiler environment not initialized.
+!error $(MSG)
+!endif
+
+# We need to run from the directory the parent makefile is located in.
+# nmake does not tell us what makefile was used to invoke it so parent
+# makefile has to set the MAKEFILEVC macro or we just make a guess and
+# warn if we think that is not the case.
+!if "$(MAKEFILEVC)" == ""
+
+!if exist("$(PROJECT).vc")
+MAKEFILEVC = $(PROJECT).vc
+!elseif exist("makefile.vc")
+MAKEFILEVC = makefile.vc
+!endif
+!endif # "$(MAKEFILEVC)" == ""
+
+!if !exist("$(MAKEFILEVC)")
+MSG = ^
+You must run nmake from the directory containing the project makefile.^
+If you are doing that and getting this message, set the MAKEFILEVC^
+macro to the name of the project makefile.
+!message WARNING: $(MSG)
+!endif
+
+
+################################################################
+# 1. Define external programs being used
 
 #----------------------------------------------------------
 # Set the proper copy method to avoid overwrite questions
@@ -33,28 +141,291 @@ _INSTALLDIR       = $(INSTALLDIR:/=\)
 # "delete all" method.
 #----------------------------------------------------------
 
-!if "$(OS)" == "Windows_NT"
 RMDIR  = rmdir /S /Q
-ERRNULL  = 2>NUL
-!if ![ver | find "4.0" > nul]
-CPY    = echo y | xcopy /i >NUL
-COPY   = copy >NUL
-!else
 CPY    = xcopy /i /y >NUL
+CPYDIR  = xcopy /e /i /y >NUL
 COPY   = copy /y >NUL
+MKDIR   = mkdir
+
+######################################################################
+# 2. Figure out our build environment in terms of what we're building.
+#
+# (a) Tcl itself
+# (b) Tk
+# (c) a Tcl extension using libraries/includes from an *installed* Tcl
+# (d) a Tcl extension using libraries/includes from Tcl source directory
+#
+# This last is needed because some extensions still need
+# some Tcl interfaces that are not publicly exposed.
+#
+# The fragment will set the following macros:
+# ROOT - root of this module sources
+# COMPATDIR - source directory that holds compatibility sources
+# DOCDIR - source directory containing documentation files
+# GENERICDIR - platform-independent source directory
+# WIN_DIR - Windows-specific source directory
+# TESTDIR - directory containing test files
+# TOOLSDIR - directory containing build tools
+# _TCLDIR - root of the Tcl installation OR the Tcl sources. Not set
+#    when building Tcl itself.
+# _INSTALLDIR - native form of the installation path. For Tcl
+#    this will be the root of the Tcl installation. For extensions
+#    this will be the lib directory under the root.
+# TCLINSTALL  - set to 1 if _TCLDIR refers to
+#    headers and libraries from an installed Tcl, and 0 if built against
+#    Tcl sources. Not set when building Tcl itself. Yes, not very well
+#    named.
+# _TCL_H - native path to the tcl.h file
+#
+# If Tk is involved, also sets the following
+# _TKDIR - native form Tk installation OR Tk source. Not set if building
+#    Tk itself.
+# TKINSTALL - set 1 if _TKDIR refers to installed Tk and 0 if Tk sources
+# _TK_H - native path to the tk.h file
+
+# Root directory for sources and assumed subdirectories
+ROOT = $(MAKEDIR)\..
+# The following paths CANNOT have spaces in them as they appear on the
+# left side of implicit rules.
+!ifndef COMPATDIR
+COMPATDIR      = $(ROOT)\compat
+!endif
+!ifndef DOCDIR
+DOCDIR         = $(ROOT)\doc
+!endif
+!ifndef GENERICDIR
+GENERICDIR     = $(ROOT)\generic
+!endif
+!ifndef TOOLSDIR
+TOOLSDIR       = $(ROOT)\tools
+!endif
+!ifndef TESTDIR
+TESTDIR        = $(ROOT)\tests
+!endif
+!ifndef LIBDIR
+!if exist("$(ROOT)\library")
+LIBDIR          = $(ROOT)\library
+!else
+LIBDIR          = $(ROOT)\lib
 !endif
-!else # "$(OS)" != "Windows_NT"
-CPY    = xcopy /i >_JUNK.OUT # On Win98 NUL does not work here.
-COPY   = copy >_JUNK.OUT # On Win98 NUL does not work here.
-RMDIR  = deltree /Y
-NULL    = \NUL # Used in testing directory existence
-ERRNULL = >NUL # Win9x shell cannot redirect stderr
 !endif
-MKDIR   = mkdir
+!ifndef DEMODIR
+!if exist("$(LIBDIR)\demos")
+DEMODIR                = $(LIBDIR)\demos
+!else
+DEMODIR                = $(ROOT)\demos
+!endif
+!endif # ifndef DEMODIR
+# Do NOT use WINDIR because it is Windows internal environment
+# variable to point to c:\windows!
+WIN_DIR                = $(ROOT)\win
 
-#------------------------------------------------------------------------------
-# Determine the host and target architectures and compiler version.
-#------------------------------------------------------------------------------
+!ifndef RCDIR
+!if exist("$(WIN_DIR)\rc")
+RCDIR           = $(WIN_DIR)\rc
+!else
+RCDIR           = $(WIN_DIR)
+!endif
+!endif
+RCDIR = $(RCDIR:/=\)
+
+# The target directory where the built packages and binaries will be installed.
+# INSTALLDIR is the (optional) path specified by the user.
+# _INSTALLDIR is INSTALLDIR using the backslash separator syntax
+!ifdef INSTALLDIR
+### Fix the path separators.
+_INSTALLDIR    = $(INSTALLDIR:/=\)
+!else
+### Assume the normal default.
+_INSTALLDIR    = $(HOMEDRIVE)\Tcl
+!endif
+
+!if $(DOING_TCL)
+
+# BEGIN Case 2(a) - Building Tcl itself
+
+# Only need to define _TCL_H
+_TCL_H = ..\generic\tcl.h
+
+# END Case 2(a) - Building Tcl itself
+
+!elseif $(DOING_TK)
+
+# BEGIN Case 2(b) - Building Tk
+
+TCLINSTALL = 0 # Tk always builds against Tcl source, not an installed Tcl
+!if "$(TCLDIR)" == ""
+!if [echo TCLDIR = \> nmakehlp.out] \
+   || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
+!error *** Could not locate Tcl source directory.
+!endif
+!include nmakehlp.out
+!endif # TCLDIR == ""
+
+_TCLDIR        = $(TCLDIR:/=\)
+_TCL_H  = $(_TCLDIR)\generic\tcl.h
+!if !exist("$(_TCL_H)")
+!error Could not locate tcl.h. Please set the TCLDIR macro to point to the Tcl *source* directory.
+!endif
+
+_TK_H = ..\generic\tk.h
+
+# END Case 2(b) - Building Tk
+
+!else
+
+# BEGIN Case 2(c) or (d) - Building an extension other than Tk
+
+# If command line has specified Tcl location through TCLDIR, use it
+# else default to the INSTALLDIR setting
+!if "$(TCLDIR)" != ""
+
+_TCLDIR        = $(TCLDIR:/=\)
+!if exist("$(_TCLDIR)\include\tcl.h") # Case 2(c) with TCLDIR defined
+TCLINSTALL     = 1
+_TCL_H          = $(_TCLDIR)\include\tcl.h
+!elseif exist("$(_TCLDIR)\generic\tcl.h") # Case 2(d) with TCLDIR defined
+TCLINSTALL     = 0
+_TCL_H          = $(_TCLDIR)\generic\tcl.h
+!endif
+
+!else  #  # Case 2(c) for extensions with TCLDIR undefined
+
+# Need to locate Tcl depending on whether it needs Tcl source or not.
+# If we don't, check the INSTALLDIR for an installed Tcl first
+
+!if exist("$(_INSTALLDIR)\include\tcl.h") && !$(NEED_TCL_SOURCE)
+
+TCLINSTALL     = 1
+TCLDIR          = $(_INSTALLDIR)\..
+# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
+# later so the \.. accounts for the /lib
+_TCLDIR                = $(_INSTALLDIR)\..
+_TCL_H          = $(_TCLDIR)\include\tcl.h
+
+!else # exist(...) && !$(NEED_TCL_SOURCE)
+
+!if [echo _TCLDIR = \> nmakehlp.out] \
+   || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
+!error *** Could not locate Tcl source directory.
+!endif
+!include nmakehlp.out
+TCLINSTALL      = 0
+TCLDIR         = $(_TCLDIR)
+_TCL_H          = $(_TCLDIR)\generic\tcl.h
+
+!endif # exist(...) && !$(NEED_TCL_SOURCE)
+
+!endif # TCLDIR
+
+!ifndef _TCL_H
+MSG =^
+Failed to find tcl.h. The TCLDIR macro is set incorrectly or is not set and default path does not contain tcl.h.
+!error $(MSG)
+!endif
+
+# Now do the same to locate Tk headers and libs if project requires Tk
+!if $(NEED_TK)
+
+!if "$(TKDIR)" != ""
+
+_TKDIR = $(TKDIR:/=\)
+!if exist("$(_TKDIR)\include\tk.h")
+TKINSTALL      = 1
+_TK_H          = $(_TKDIR)\include\tk.h
+!elseif exist("$(_TKDIR)\generic\tk.h")
+TKINSTALL      = 0
+_TK_H          = $(_TKDIR)\generic\tk.h
+!endif
+
+!else # TKDIR not defined
+
+# Need to locate Tcl depending on whether it needs Tcl source or not.
+# If we don't, check the INSTALLDIR for an installed Tcl first
+
+!if exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
+
+TKINSTALL      = 1
+# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
+# later so the \.. accounts for the /lib
+_TKDIR         = $(_INSTALLDIR)\..
+_TK_H          = $(_TKDIR)\include\tk.h
+TKDIR          = $(_TKDIR)
+
+!else # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
+
+!if [echo _TKDIR = \> nmakehlp.out] \
+   || [nmakehlp -L generic\tk.h >> nmakehlp.out]
+!error *** Could not locate Tk source directory.
+!endif
+!include nmakehlp.out
+TKINSTALL      = 0
+TKDIR          = $(_TKDIR)
+_TK_H          = $(_TKDIR)\generic\tk.h
+
+!endif # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
+
+!endif # TKDIR
+
+!ifndef _TK_H
+MSG =^
+Failed to find tk.h. The TKDIR macro is set incorrectly or is not set and default path does not contain tk.h.
+!error $(MSG)
+!endif
+
+!endif # NEED_TK
+
+!if $(NEED_TCL_SOURCE) && $(TCLINSTALL)
+MSG = ^
+*** Warning: This extension requires the source distribution of Tcl.^
+*** Please set the TCLDIR macro to point to the Tcl sources.
+!error $(MSG)
+!endif
+
+!if $(NEED_TK_SOURCE)
+!if $(TKINSTALL)
+MSG = ^
+*** Warning: This extension requires the source distribution of Tk.^
+*** Please set the TKDIR macro to point to the Tk sources.
+!error $(MSG)
+!endif
+!endif
+
+
+# If INSTALLDIR set to Tcl installation root dir then reset to the
+# lib dir for installing extensions
+!if exist("$(_INSTALLDIR)\include\tcl.h")
+_INSTALLDIR=$(_INSTALLDIR)\lib
+!endif
+
+# END Case 2(c) or (d) - Building an extension
+!endif # if $(DOING_TCL)
+
+################################################################
+# 3. Determine compiler version and architecture
+# In this section, we figure out the compiler version and the
+# architecture for which we are building. This sets the
+# following macros:
+# VCVERSION - the internal compiler version as 1200, 1400, 1910 etc.
+#     This is also printed by the compiler in dotted form 19.10 etc.
+# VCVER - the "marketing version", for example Visual C++ 6 for internal
+#     compiler version 1200. This is kept only for legacy reasons as it
+#     does not make sense for recent Microsoft compilers. Only used for
+#     output directory names.
+# ARCH - set to IX86, ARM64 or AMD64 depending on 32- or 64-bit target
+# NATIVE_ARCH - set to IX86, ARM64 or AMD64 for the host machine
+# MACHINE - same as $(ARCH) - legacy
+# _VC_MANIFEST_EMBED_{DLL,EXE} - commands for embedding a manifest if needed
+
+cc32           = $(CC)   # built-in default.
+link32         = link
+lib32          = lib
+rc32           = $(RC)   # built-in default.
+
+#----------------------------------------------------------------
+# Figure out the compiler architecture and version by writing
+# the C macros to a file, preprocessing them with the C
+# preprocessor and reading back the created file
 
 _HASH=^#
 _VC_MANIFEST_EMBED_EXE=
@@ -65,19 +436,70 @@ VCVER=0
     && ![echo ARCH=IX86 >> vercl.x] \
     && ![echo $(_HASH)elif defined(_M_AMD64) >> vercl.x] \
     && ![echo ARCH=AMD64 >> vercl.x] \
+    && ![echo $(_HASH)elif defined(_M_ARM64) >> vercl.x] \
+    && ![echo ARCH=ARM64 >> vercl.x] \
     && ![echo $(_HASH)endif >> vercl.x] \
-    && ![cl -nologo -TC -P vercl.x $(ERRNULL)]
+    && ![$(cc32) -nologo -TC -P vercl.x 2>NUL]
 !include vercl.i
+!if $(VCVERSION) < 1900
 !if ![echo VCVER= ^\> vercl.vc] \
     && ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc]
 !include vercl.vc
 !endif
+!else
+# The simple calculation above does not apply to new Visual Studio releases
+# Keep the compiler version in its native form.
+VCVER = $(VCVERSION)
+!endif
+!endif
+
+!if ![del 2>NUL /q/f vercl.x vercl.i vercl.vc]
 !endif
-!if ![del $(ERRNUL) /q/f vercl.x vercl.i vercl.vc]
+
+#----------------------------------------------------------------
+# The MACHINE macro is used by legacy makefiles so set it as well
+!ifdef MACHINE
+!if "$(MACHINE)" == "x86"
+!undef MACHINE
+MACHINE = IX86
+!elseif "$(MACHINE)" == "arm64"
+!undef MACHINE
+MACHINE = ARM64
+!elseif "$(MACHINE)" == "x64"
+!undef MACHINE
+MACHINE = AMD64
+!endif
+!if "$(MACHINE)" != "$(ARCH)"
+!error Specified MACHINE macro $(MACHINE) does not match detected target architecture $(ARCH).
+!endif
+!else
+MACHINE=$(ARCH)
 !endif
 
+#---------------------------------------------------------------
+# The PLATFORM_IDENTIFY macro matches the values returned by
+# the Tcl platform::identify command
+!if "$(MACHINE)" == "AMD64"
+PLATFORM_IDENTIFY = win32-x86_64
+!elseif "$(MACHINE)" == "ARM64"
+PLATFORM_IDENTIFY = win32-arm
+!else
+PLATFORM_IDENTIFY = win32-ix86
+!endif
+
+# The MULTIPLATFORM macro controls whether binary extensions are installed
+# in platform-specific directories. Intended to be set/used by extensions.
+!ifndef MULTIPLATFORM_INSTALL
+MULTIPLATFORM_INSTALL = 0
+!endif
+
+#------------------------------------------------------------
+# Figure out the *host* architecture by reading the registry
+
 !if ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i x86]
 NATIVE_ARCH=IX86
+!elseif ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i ARM | findstr /i 64-bit]
+NATIVE_ARCH=ARM64
 !else
 NATIVE_ARCH=AMD64
 !endif
@@ -88,185 +510,408 @@ _VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -ou
 _VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
 !endif
 
-!ifndef MACHINE
-MACHINE=$(ARCH)
-!endif
-
-!ifndef CFG_ENCODING
-CFG_ENCODING   = \"cp1252\"
-!endif
-
-!message ===============================================================================
+################################################################
+# 4. Build the nmakehlp program
+# This is a helper app we need to overcome nmake's limiting
+# environment. We will call out to it to get various bits of
+# information about supported compiler options etc.
+#
+# Tcl itself will always use the nmakehlp.c program which is
+# in its own source. It will be kept updated there.
+#
+# Extensions built against an installed Tcl will use the installed
+# copy of Tcl's nmakehlp.c if there is one and their own version
+# otherwise. In the latter case, they would also be using their own
+# rules.vc. Note that older versions of Tcl do not install nmakehlp.c
+# or rules.vc.
+#
+# Extensions built against Tcl sources will use the one from the Tcl source.
+#
+# When building an extension using a sufficiently new version of Tcl,
+# rules-ext.vc will define NMAKEHLPC appropriately to point to the
+# copy of nmakehlp.c to be used.
 
-#----------------------------------------------------------
-# build the helper app we need to overcome nmake's limiting
-# environment.
-#----------------------------------------------------------
+!ifndef NMAKEHLPC
+# Default to the one in the current directory (the extension's own nmakehlp.c)
+NMAKEHLPC = nmakehlp.c
 
-!if !exist(nmakehlp.exe)
-!if [$(cc32) -nologo nmakehlp.c -link -subsystem:console > nul]
+!if !$(DOING_TCL)
+!if $(TCLINSTALL)
+!if exist("$(_TCLDIR)\lib\nmake\nmakehlp.c")
+NMAKEHLPC = $(_TCLDIR)\lib\nmake\nmakehlp.c
 !endif
+!else # !$(TCLINSTALL)
+!if exist("$(_TCLDIR)\win\nmakehlp.c")
+NMAKEHLPC = $(_TCLDIR)\win\nmakehlp.c
 !endif
+!endif # $(TCLINSTALL)
+!endif # !$(DOING_TCL)
 
-#----------------------------------------------------------
-# Test for compiler features
-#----------------------------------------------------------
+!endif # NMAKEHLPC
 
-### test for optimizations
-!if [nmakehlp -c -Ot]
-!message *** Compiler has 'Optimizations'
-OPTIMIZING     = 1
+# We always build nmakehlp even if it exists since we do not know
+# what source it was built from.
+!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
+!if [$(cc32) -nologo "$(NMAKEHLPC)" -link -subsystem:console > nul]
+!endif
 !else
-!message *** Compiler does not have 'Optimizations'
-OPTIMIZING     = 0
+!if [copy $(NMAKEHLPC:nmakehlp.c=x86_64-w64-mingw32-nmakehlp.exe) nmakehlp.exe >NUL]
 !endif
-
-OPTIMIZATIONS   =
-
-!if [nmakehlp -c -Ot]
-OPTIMIZATIONS  = $(OPTIMIZATIONS) -Ot
 !endif
 
-!if [nmakehlp -c -Oi]
-OPTIMIZATIONS  = $(OPTIMIZATIONS) -Oi
-!endif
+################################################################
+# 5. Test for compiler features
+# Visual C++ compiler options have changed over the years. Check
+# which options are supported by the compiler in use.
+#
+# The following macros are set:
+# OPTIMIZATIONS - the compiler flags to be used for optimized builds
+# DEBUGFLAGS - the compiler flags to be used for debug builds
+# LINKERFLAGS - Flags passed to the linker
+#
+# Note that these are the compiler settings *available*, not those
+# that will be *used*. The latter depends on the OPTS macro settings
+# which we have not yet parsed.
+#
+# Also note that some of the flags in OPTIMIZATIONS are not really
+# related to optimization. They are placed there only for legacy reasons
+# as some extensions expect them to be included in that macro.
 
+# -Op improves float consistency. Note only needed for older compilers
+# Newer compilers do not need or support this option.
 !if [nmakehlp -c -Op]
-OPTIMIZATIONS  = $(OPTIMIZATIONS) -Op
+FPOPTS  = -Op
 !endif
 
+# Strict floating point semantics - present in newer compilers in lieu of -Op
 !if [nmakehlp -c -fp:strict]
-OPTIMIZATIONS  = $(OPTIMIZATIONS) -fp:strict
+FPOPTS  = $(FPOPTS) -fp:strict
+!endif
+
+!if "$(MACHINE)" == "IX86"
+### test for pentium errata
+!if [nmakehlp -c -QI0f]
+!message *** Compiler has 'Pentium 0x0f fix'
+FPOPTS  = $(FPOPTS) -QI0f
+!else
+!message *** Compiler does not have 'Pentium 0x0f fix'
+!endif
 !endif
 
-!if [nmakehlp -c -Gs]
-OPTIMIZATIONS  = $(OPTIMIZATIONS) -Gs
+### test for optimizations
+# /O2 optimization includes /Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy as per
+# documentation. Note we do NOT want /Gs as that inserts a _chkstk
+# stack probe at *every* function entry, not just those with more than
+# a page of stack allocation resulting in a performance hit.  However,
+# /O2 documentation is misleading as its stack probes are simply the
+# default page size locals allocation probes and not what is implied
+# by an explicit /Gs option.
+
+OPTIMIZATIONS = $(FPOPTS)
+
+!if [nmakehlp -c -O2]
+OPTIMIZING = 1
+OPTIMIZATIONS   = $(OPTIMIZATIONS) -O2
+!else
+# Legacy, really. All modern compilers support this
+!message *** Compiler does not have 'Optimizations'
+OPTIMIZING = 0
 !endif
 
+# Checks for buffer overflows in local arrays
 !if [nmakehlp -c -GS]
 OPTIMIZATIONS  = $(OPTIMIZATIONS) -GS
 !endif
 
+# Link time optimization. Note that this option (potentially) makes
+# generated libraries only usable by the specific VC++ version that
+# created it. Requires /LTCG linker option
 !if [nmakehlp -c -GL]
 OPTIMIZATIONS  = $(OPTIMIZATIONS) -GL
+CC_GL_OPT_ENABLED = 1
+!else
+# In newer compilers -GL and -YX are incompatible.
+!if [nmakehlp -c -YX]
+OPTIMIZATIONS  = $(OPTIMIZATIONS) -YX
 !endif
+!endif # [nmakehlp -c -GL]
 
-DEBUGFLAGS     =
+DEBUGFLAGS     = $(FPOPTS)
 
+# Run time error checks. Not available or valid in a release, non-debug build
+# RTC is for modern compilers, -GZ is legacy
 !if [nmakehlp -c -RTC1]
 DEBUGFLAGS     = $(DEBUGFLAGS) -RTC1
 !elseif [nmakehlp -c -GZ]
 DEBUGFLAGS     = $(DEBUGFLAGS) -GZ
 !endif
 
-COMPILERFLAGS  =-W3 -DUNICODE -D_UNICODE
+#----------------------------------------------------------------
+# Linker flags
 
-# In v13 -GL and -YX are incompatible.
-!if [nmakehlp -c -YX]
-!if ![nmakehlp -c -GL]
-OPTIMIZATIONS  = $(OPTIMIZATIONS) -YX
-!endif
+# LINKER_TESTFLAGS are for internal use when we call nmakehlp to test
+# if the linker supports a specific option. Without these flags link will
+# return "LNK1561: entry point must be defined" error compiling from VS-IDE:
+# They are not passed through to the actual application / extension
+# link rules.
+!ifndef LINKER_TESTFLAGS
+LINKER_TESTFLAGS = /DLL /NOENTRY /OUT:nmakehlp.out
 !endif
 
-!if "$(MACHINE)" == "IX86"
-### test for pentium errata
-!if [nmakehlp -c -QI0f]
-!message *** Compiler has 'Pentium 0x0f fix'
-COMPILERFLAGS  = $(COMPILERFLAGS) -QI0f
-!else
-!message *** Compiler does not have 'Pentium 0x0f fix'
+LINKERFLAGS     =
+
+# If compiler has enabled link time optimization, linker must too with -ltcg
+!ifdef CC_GL_OPT_ENABLED
+!if [nmakehlp -l -ltcg $(LINKER_TESTFLAGS)]
+LINKERFLAGS     = $(LINKERFLAGS) -ltcg
+!endif
+!endif
+
+
+################################################################
+# 6. Extract various version numbers from headers
+# For Tcl and Tk, version numbers are extracted from tcl.h and tk.h
+# respectively. For extensions, versions are extracted from the
+# configure.in or configure.ac from the TEA configuration if it
+# exists, and unset otherwise.
+# Sets the following macros:
+# TCL_MAJOR_VERSION
+# TCL_MINOR_VERSION
+# TCL_RELEASE_SERIAL
+# TCL_PATCH_LEVEL
+# TCL_PATCH_LETTER
+# TCL_VERSION
+# TK_MAJOR_VERSION
+# TK_MINOR_VERSION
+# TK_RELEASE_SERIAL
+# TK_PATCH_LEVEL
+# TK_PATCH_LETTER
+# TK_VERSION
+# DOTVERSION - set as (for example) 2.5
+# VERSION - set as (for example 25)
+#--------------------------------------------------------------
+
+!if [echo REM = This file is generated from rules.vc > versions.vc]
+!endif
+!if [echo TCL_MAJOR_VERSION = \>> versions.vc] \
+   && [nmakehlp -V "$(_TCL_H)" "define TCL_MAJOR_VERSION" >> versions.vc]
 !endif
+!if [echo TCL_MINOR_VERSION = \>> versions.vc] \
+   && [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc]
+!endif
+!if [echo TCL_RELEASE_SERIAL = \>> versions.vc] \
+   && [nmakehlp -V "$(_TCL_H)" TCL_RELEASE_SERIAL >> versions.vc]
+!endif
+!if [echo TCL_PATCH_LEVEL = \>> versions.vc] \
+   && [nmakehlp -V "$(_TCL_H)" TCL_PATCH_LEVEL >> versions.vc]
 !endif
 
-!if "$(MACHINE)" == "IA64"
-### test for Itanium errata
-!if [nmakehlp -c -QIA64_Bx]
-!message *** Compiler has 'B-stepping errata workarounds'
-COMPILERFLAGS   = $(COMPILERFLAGS) -QIA64_Bx
-!else
-!message *** Compiler does not have 'B-stepping errata workarounds'
+!if defined(_TK_H)
+!if [echo TK_MAJOR_VERSION = \>> versions.vc] \
+   && [nmakehlp -V $(_TK_H) "define TK_MAJOR_VERSION" >> versions.vc]
+!endif
+!if [echo TK_MINOR_VERSION = \>> versions.vc] \
+   && [nmakehlp -V $(_TK_H) TK_MINOR_VERSION >> versions.vc]
 !endif
+!if [echo TK_RELEASE_SERIAL = \>> versions.vc] \
+   && [nmakehlp -V "$(_TK_H)" TK_RELEASE_SERIAL >> versions.vc]
 !endif
+!if [echo TK_PATCH_LEVEL = \>> versions.vc] \
+   && [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc]
+!endif
+!endif # _TK_H
 
-!if "$(MACHINE)" == "IX86"
-### test for -align:4096, when align:512 will do.
-!if [nmakehlp -l -opt:nowin98]
-!message *** Linker has 'Win98 alignment problem'
-ALIGN98_HACK   = 1
+!include versions.vc
+
+TCL_VERSION    = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
+TCL_DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
+!if [nmakehlp -f $(TCL_PATCH_LEVEL) "a"]
+TCL_PATCH_LETTER = a
+!elseif [nmakehlp -f $(TCL_PATCH_LEVEL) "b"]
+TCL_PATCH_LETTER = b
 !else
-!message *** Linker does not have 'Win98 alignment problem'
-ALIGN98_HACK   = 0
+TCL_PATCH_LETTER = .
 !endif
+
+!if defined(_TK_H)
+
+TK_VERSION     = $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)
+TK_DOTVERSION  = $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
+!if [nmakehlp -f $(TK_PATCH_LEVEL) "a"]
+TK_PATCH_LETTER = a
+!elseif [nmakehlp -f $(TK_PATCH_LEVEL) "b"]
+TK_PATCH_LETTER = b
 !else
-ALIGN98_HACK   = 0
+TK_PATCH_LETTER = .
 !endif
 
-LINKERFLAGS     =
-
-!if [nmakehlp -l -ltcg]
-LINKERFLAGS     =-ltcg
 !endif
 
-#----------------------------------------------------------
-# Decode the options requested.
-#----------------------------------------------------------
+# Set DOTVERSION and VERSION
+!if $(DOING_TCL)
+
+DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
+VERSION = $(TCL_VERSION)
 
-!if "$(OPTS)" == "" || [nmakehlp -f "$(OPTS)" "none"]
+!elseif $(DOING_TK)
+
+DOTVERSION = $(TK_DOTVERSION)
+VERSION = $(TK_VERSION)
+
+!else # Doing a non-Tk extension
+
+# If parent makefile has not defined DOTVERSION, try to get it from TEA
+# first from a configure.in file, and then from configure.ac
+!ifndef DOTVERSION
+!if [echo DOTVERSION = \> versions.vc] \
+   || [nmakehlp -V $(ROOT)\configure.in ^[$(PROJECT)^] >> versions.vc]
+!if [echo DOTVERSION = \> versions.vc] \
+   || [nmakehlp -V $(ROOT)\configure.ac ^[$(PROJECT)^] >> versions.vc]
+!error *** Could not figure out extension version. Please define DOTVERSION in parent makefile before including rules.vc.
+!endif
+!endif
+!include versions.vc
+!endif # DOTVERSION
+VERSION         = $(DOTVERSION:.=)
+
+!endif # $(DOING_TCL) ... etc.
+
+# Windows RC files have 3 version components. Ensure this irrespective
+# of how many components the package has specified. Basically, ensure
+# minimum 4 components by appending 4 0's and then pick out the first 4.
+# Also take care of the fact that DOTVERSION may have "a" or "b" instead
+# of "." separating the version components.
+DOTSEPARATED=$(DOTVERSION:a=.)
+DOTSEPARATED=$(DOTSEPARATED:b=.)
+!if [echo RCCOMMAVERSION = \> versions.vc] \
+  || [for /f "tokens=1,2,3,4,5* delims=." %a in ("$(DOTSEPARATED).0.0.0.0") do echo %a,%b,%c,%d >> versions.vc]
+!error *** Could not generate RCCOMMAVERSION ***
+!endif
+!include versions.vc
+
+########################################################################
+# 7. Parse the OPTS macro to work out the requested build configuration.
+# Based on this, we will construct the actual switches to be passed to the
+# compiler and linker using the macros defined in the previous section.
+# The following macros are defined by this section based on OPTS
+# STATIC_BUILD - 0 -> Tcl is to be built as a shared library
+#                1 -> build as a static library and shell
+# TCL_THREADS - legacy but always 1 on Windows since winsock requires it.
+# DEBUG - 1 -> debug build, 0 -> release builds
+# SYMBOLS - 1 -> generate PDB's, 0 -> no PDB's
+# PROFILE - 1 -> generate profiling info, 0 -> no profiling
+# PGO     - 1 -> profile based optimization, 0 -> no
+# MSVCRT  - 1 -> link to dynamic C runtime even when building static Tcl build
+#           0 -> link to static C runtime for static Tcl build.
+#           Does not impact shared Tcl builds (STATIC_BUILD == 0)
+#           Default: 1 for Tcl 8.7 and up, 0 otherwise.
+# TCL_USE_STATIC_PACKAGES - 1 -> statically link the registry and dde extensions
+#           in the Tcl and Wish shell. 0 -> keep them as shared libraries. Does
+#           not impact shared Tcl builds. Implied by STATIC_BUILD since Tcl 8.7.
+# USE_THREAD_ALLOC - 1 -> Use a shared global free pool for allocation.
+#           0 -> Use the non-thread allocator.
+# UNCHECKED - 1 -> when doing a debug build with symbols, use the release
+#           C runtime, 0 -> use the debug C runtime.
+# USE_STUBS - 1 -> compile to use stubs interfaces, 0 -> direct linking
+# CONFIG_CHECK - 1 -> check current build configuration against Tcl
+#           configuration (ignored for Tcl itself)
+# _USE_64BIT_TIME_T - forces a build using 64-bit time_t for 32-bit build
+#           (CRT library should support this, not needed for Tcl 9.x)
+# Further, LINKERFLAGS are modified based on above.
+
+# Default values for all the above
 STATIC_BUILD   = 0
 TCL_THREADS    = 1
 DEBUG          = 0
 SYMBOLS                = 0
 PROFILE                = 0
 PGO            = 0
-MSVCRT         = 0
-LOIMPACT       = 0
+MSVCRT         = 1
 TCL_USE_STATIC_PACKAGES        = 0
 USE_THREAD_ALLOC = 1
 UNCHECKED      = 0
+CONFIG_CHECK    = 1
+!if $(DOING_TCL)
+USE_STUBS       = 0
 !else
+USE_STUBS       = 1
+!endif
+
+# If OPTS is not empty AND does not contain "none" which turns off all OPTS
+# set the above macros based on OPTS content
+!if "$(OPTS)" != "" && ![nmakehlp -f "$(OPTS)" "none"]
+
+# OPTS are specified, parse them
+
 !if [nmakehlp -f $(OPTS) "static"]
 !message *** Doing static
 STATIC_BUILD   = 1
-!else
-STATIC_BUILD   = 0
 !endif
+
+!if [nmakehlp -f $(OPTS) "nostubs"]
+!message *** Not using stubs
+USE_STUBS      = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "nomsvcrt"]
+!message *** Doing nomsvcrt
+MSVCRT         = 0
+!else
 !if [nmakehlp -f $(OPTS) "msvcrt"]
 !message *** Doing msvcrt
-MSVCRT         = 1
 !else
+!if $(TCL_MAJOR_VERSION) == 8 && $(TCL_MINOR_VERSION) < 7 && $(STATIC_BUILD)
 MSVCRT         = 0
 !endif
-!if [nmakehlp -f $(OPTS) "staticpkg"]
+!endif
+!endif # [nmakehlp -f $(OPTS) "nomsvcrt"]
+
+!if [nmakehlp -f $(OPTS) "staticpkg"] && $(STATIC_BUILD)
 !message *** Doing staticpkg
 TCL_USE_STATIC_PACKAGES        = 1
-!else
-TCL_USE_STATIC_PACKAGES        = 0
 !endif
+
 !if [nmakehlp -f $(OPTS) "nothreads"]
 !message *** Compile explicitly for non-threaded tcl
-TCL_THREADS    = 0
-!else
-TCL_THREADS    = 1
-USE_THREAD_ALLOC= 1
+TCL_THREADS = 0
+USE_THREAD_ALLOC= 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "tcl8"]
+!message *** Build for Tcl8
+TCL_BUILD_FOR = 8
 !endif
+
+!if $(TCL_MAJOR_VERSION) == 8
+!if [nmakehlp -f $(OPTS) "time64bit"]
+!message *** Force 64-bit time_t
+_USE_64BIT_TIME_T = 1
+!endif
+!endif
+
+# Yes, it's weird that the "symbols" option controls DEBUG and
+# the "pdbs" option controls SYMBOLS. That's historical.
 !if [nmakehlp -f $(OPTS) "symbols"]
 !message *** Doing symbols
 DEBUG          = 1
 !else
 DEBUG          = 0
 !endif
+
 !if [nmakehlp -f $(OPTS) "pdbs"]
 !message *** Doing pdbs
 SYMBOLS                = 1
 !else
 SYMBOLS                = 0
 !endif
+
 !if [nmakehlp -f $(OPTS) "profile"]
 !message *** Doing profile
 PROFILE                = 1
 !else
 PROFILE                = 0
 !endif
+
 !if [nmakehlp -f $(OPTS) "pgi"]
 !message *** Doing profile guided optimization instrumentation
 PGO            = 1
@@ -276,53 +921,149 @@ PGO              = 2
 !else
 PGO            = 0
 !endif
+
 !if [nmakehlp -f $(OPTS) "loimpact"]
-!message *** Doing loimpact
-LOIMPACT       = 1
-!else
-LOIMPACT       = 0
+!message *** Warning: ignoring option "loimpact" - deprecated on modern Windows.
 !endif
+
+# TBD - should get rid of this option
 !if [nmakehlp -f $(OPTS) "thrdalloc"]
 !message *** Doing thrdalloc
 USE_THREAD_ALLOC = 1
 !endif
+
 !if [nmakehlp -f $(OPTS) "tclalloc"]
-!message *** Doing tclalloc
 USE_THREAD_ALLOC = 0
 !endif
-!if [nmakehlp -f $(OPTS) "unchecked"]
-!message *** Doing unchecked
-UNCHECKED = 1
-!else
-UNCHECKED = 0
+
+!if [nmakehlp -f $(OPTS) "unchecked"]
+!message *** Doing unchecked
+UNCHECKED = 1
+!else
+UNCHECKED = 0
+!endif
+
+!if [nmakehlp -f $(OPTS) "noconfigcheck"]
+CONFIG_CHECK = 1
+!else
+CONFIG_CHECK = 0
+!endif
+
+!endif # "$(OPTS)" != ""  && ... parsing of OPTS
+
+# Set linker flags based on above
+
+!if $(PGO) > 1
+!if [nmakehlp -l -ltcg:pgoptimize $(LINKER_TESTFLAGS)]
+LINKERFLAGS    = $(LINKERFLAGS:-ltcg=) -ltcg:pgoptimize
+!else
+MSG=^
+This compiler does not support profile guided optimization.
+!error $(MSG)
+!endif
+!elseif $(PGO) > 0
+!if [nmakehlp -l -ltcg:pginstrument $(LINKER_TESTFLAGS)]
+LINKERFLAGS    = $(LINKERFLAGS:-ltcg=) -ltcg:pginstrument
+!else
+MSG=^
+This compiler does not support profile guided optimization.
+!error $(MSG)
+!endif
+!endif
+
+################################################################
+# 8. Parse the STATS macro to configure code instrumentation
+# The following macros are set by this section:
+# TCL_MEM_DEBUG - 1 -> enables memory allocation instrumentation
+#                 0 -> disables
+# TCL_COMPILE_DEBUG - 1 -> enables byte compiler logging
+#                     0 -> disables
+
+# Default both are off
+TCL_MEM_DEBUG      = 0
+TCL_COMPILE_DEBUG   = 0
+
+!if "$(STATS)" != "" && ![nmakehlp -f "$(STATS)" "none"]
+
+!if [nmakehlp -f $(STATS) "memdbg"]
+!message *** Doing memdbg
+TCL_MEM_DEBUG      = 1
+!else
+TCL_MEM_DEBUG      = 0
+!endif
+
+!if [nmakehlp -f $(STATS) "compdbg"]
+!message *** Doing compdbg
+TCL_COMPILE_DEBUG   = 1
+!else
+TCL_COMPILE_DEBUG   = 0
+!endif
+
+!endif
+
+####################################################################
+# 9. Parse the CHECKS macro to configure additional compiler checks
+# The following macros are set by this section:
+# WARNINGS - compiler switches that control the warnings level
+# TCL_NO_DEPRECATED - 1 -> disable support for deprecated functions
+#                     0 -> enable deprecated functions
+
+# Defaults - Permit deprecated functions and warning level 3
+TCL_NO_DEPRECATED          = 0
+WARNINGS                   = -W3
+
+!if "$(CHECKS)" != "" && ![nmakehlp -f "$(CHECKS)" "none"]
+
+!if [nmakehlp -f $(CHECKS) "nodep"]
+!message *** Doing nodep check
+TCL_NO_DEPRECATED          = 1
+!endif
+
+!if [nmakehlp -f $(CHECKS) "fullwarn"]
+!message *** Doing full warnings check
+WARNINGS                   = -W4
+!if [nmakehlp -l -warn:3 $(LINKER_TESTFLAGS)]
+LINKERFLAGS                = $(LINKERFLAGS) -warn:3
 !endif
 !endif
 
+!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]
+!message *** Doing 64bit portability warnings
+WARNINGS                   = $(WARNINGS) -Wp64
+!endif
 
-!if !$(STATIC_BUILD)
-# Make sure we don't build overly fat DLLs.
-MSVCRT         = 1
-# We shouldn't statically put the extensions inside the shell when dynamic.
-TCL_USE_STATIC_PACKAGES = 0
 !endif
 
 
-#----------------------------------------------------------
+################################################################
+# 10. Construct output directory and file paths
 # Figure-out how to name our intermediate and output directories.
-# We wouldn't want different builds to use the same .obj files
-# by accident.
-#----------------------------------------------------------
+# In order to avoid inadvertent mixing of object files built using
+# different compilers, build configurations etc.,
+#
+# Naming convention (suffixes):
+#   t = full thread support. (Not used for Tcl >= 8.7)
+#   s = static library (as opposed to an import library)
+#   g = linked to the debug enabled C run-time.
+#   x = special static build when it links to the dynamic C run-time.
+#
+# The following macros are set in this section:
+# SUFX - the suffix to use for binaries based on above naming convention
+# BUILDDIRTOP - the toplevel default output directory
+#      is of the form {Release,Debug}[_AMD64][_COMPILERVERSION]
+# TMP_DIR - directory where object files are created
+# OUT_DIR - directory where output executables are created
+# Both TMP_DIR and OUT_DIR are defaulted only if not defined by the
+# parent makefile (or command line). The default values are
+# based on BUILDDIRTOP.
+# STUBPREFIX - name of the stubs library for this project
+# PRJIMPLIB - output path of the generated project import library
+# PRJLIBNAME - name of generated project library
+# PRJLIB     - output path of generated project library
+# PRJSTUBLIBNAME - name of the generated project stubs library
+# PRJSTUBLIB - output path of the generated project stubs library
+# RESFILE - output resource file (only if not static build)
 
-#----------------------------------------
-# Naming convention:
-#   t = full thread support.
-#   s = static library (as opposed to an
-#      import library)
-#   g = linked to the debug enabled C
-#      run-time.
-#   x = special static build when it
-#      links to the dynamic C run-time.
-#----------------------------------------
 SUFX       = tsgx
 
 !if $(DEBUG)
@@ -338,7 +1079,7 @@ BUILDDIRTOP =$(BUILDDIRTOP)_$(MACHINE)
 BUILDDIRTOP =$(BUILDDIRTOP)_VC$(VCVER)
 !endif
 
-!if !$(DEBUG) || $(DEBUG) && $(UNCHECKED)
+!if !$(DEBUG) || $(TCL_VERSION) > 86 || $(DEBUG) && $(UNCHECKED)
 SUFX       = $(SUFX:g=)
 !endif
 
@@ -348,20 +1089,18 @@ TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX
 TMP_DIRFULL = $(TMP_DIRFULL:Static=)
 SUFX       = $(SUFX:s=)
 EXT        = dll
-!if $(MSVCRT)
 TMP_DIRFULL = $(TMP_DIRFULL:X=)
 SUFX       = $(SUFX:x=)
-!endif
 !else
 TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=)
 EXT        = lib
-!if !$(MSVCRT)
+!if $(MSVCRT) && $(TCL_VERSION) > 86 || !$(MSVCRT) && $(TCL_VERSION) < 87
 TMP_DIRFULL = $(TMP_DIRFULL:X=)
 SUFX       = $(SUFX:x=)
 !endif
 !endif
 
-!if !$(TCL_THREADS)
+!if !$(TCL_THREADS) || $(TCL_VERSION) > 86
 TMP_DIRFULL = $(TMP_DIRFULL:Threaded=)
 SUFX       = $(SUFX:t=)
 !endif
@@ -377,334 +1116,798 @@ OUT_DIR            = $(TMP_DIR)
 !endif
 !endif
 
+# Relative paths -> absolute
+!if [echo OUT_DIR = \> nmakehlp.out] \
+   || [nmakehlp -Q "$(OUT_DIR)" >> nmakehlp.out]
+!error *** Could not fully qualify path OUT_DIR=$(OUT_DIR)
+!endif
+!if [echo TMP_DIR = \>> nmakehlp.out] \
+   || [nmakehlp -Q "$(TMP_DIR)" >> nmakehlp.out]
+!error *** Could not fully qualify path TMP_DIR=$(TMP_DIR)
+!endif
+!include nmakehlp.out
 
-#----------------------------------------------------------
-# Decode the statistics requested.
-#----------------------------------------------------------
+# The name of the stubs library for the project being built
+STUBPREFIX      = $(PROJECT)stub
 
-!if "$(STATS)" == "" || [nmakehlp -f "$(STATS)" "none"]
-TCL_MEM_DEBUG      = 0
-TCL_COMPILE_DEBUG   = 0
-!else
-!if [nmakehlp -f $(STATS) "memdbg"]
-!message *** Doing memdbg
-TCL_MEM_DEBUG      = 1
+#
+# Set up paths to various Tcl executables and libraries needed by extensions
+#
+
+# TIP 430. Unused for 8.6 but no harm defining it to allow a common rules.vc
+TCL_ZIP_FILE = libtcl$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)$(TCL_PATCH_LETTER)$(TCL_RELEASE_SERIAL).zip
+TK_ZIP_FILE = libtk$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)$(TK_PATCH_LETTER)$(TK_RELEASE_SERIAL).zip
+
+!if $(DOING_TCL)
+TCLSHNAME       = $(PROJECT)sh$(VERSION)$(SUFX).exe
+TCLSH          = $(OUT_DIR)\$(TCLSHNAME)
+TCLIMPLIB      = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
+TCLLIBNAME     = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
+TCLLIB         = $(OUT_DIR)\$(TCLLIBNAME)
+TCLSCRIPTZIP    = $(OUT_DIR)\$(TCL_ZIP_FILE)
+
+!if $(TCL_MAJOR_VERSION) == 8
+TCLSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
 !else
-TCL_MEM_DEBUG      = 0
+TCLSTUBLIBNAME = $(STUBPREFIX).lib
 !endif
-!if [nmakehlp -f $(STATS) "compdbg"]
-!message *** Doing compdbg
-TCL_COMPILE_DEBUG   = 1
+TCLSTUBLIB     = $(OUT_DIR)\$(TCLSTUBLIBNAME)
+TCL_INCLUDES    = -I"$(WIN_DIR)" -I"$(GENERICDIR)"
+
+!else # !$(DOING_TCL)
+
+!if $(TCLINSTALL) # Building against an installed Tcl
+
+# When building extensions, we need to locate tclsh. Depending on version
+# of Tcl we are building against, this may or may not have a "t" suffix.
+# Try various possibilities in turn.
+TCLSH          = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX:t=).exe
+!if !exist("$(TCLSH)")
+TCLSH           = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX:t=).exe
+!endif
+
+!if $(TCL_MAJOR_VERSION) == 8
+TCLSTUBLIB     = $(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib
 !else
-TCL_COMPILE_DEBUG   = 0
+TCLSTUBLIB     = $(_TCLDIR)\lib\tclstub.lib
 !endif
+TCLIMPLIB      = $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX:t=).lib
+# When building extensions, may be linking against Tcl that does not add
+# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
+!if !exist("$(TCLIMPLIB)")
+TCLIMPLIB      = $(_TCLDIR)\lib\tcl$(TCL_VERSION)t$(SUFX:t=).lib
 !endif
+TCL_LIBRARY    = $(_TCLDIR)\lib
+TCLREGLIB      = $(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib
+TCLDDELIB      = $(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib
+TCLSCRIPTZIP   = $(_TCLDIR)\lib\$(TCL_ZIP_FILE)
+TCLTOOLSDIR    = \must\have\tcl\sources\to\build\this\target
+TCL_INCLUDES    = -I"$(_TCLDIR)\include"
 
+!else # Building against Tcl sources
 
-#----------------------------------------------------------
-# Decode the checks requested.
-#----------------------------------------------------------
-
-!if "$(CHECKS)" == "" || [nmakehlp -f "$(CHECKS)" "none"]
-TCL_NO_DEPRECATED          = 0
-WARNINGS                   = -W3
-!else
-!if [nmakehlp -f $(CHECKS) "nodep"]
-!message *** Doing nodep check
-TCL_NO_DEPRECATED          = 1
+TCLSH          = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX:t=).exe
+!if !exist($(TCLSH))
+TCLSH          = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX:t=).exe
+!endif
+!if $(TCL_MAJOR_VERSION) == 8
+TCLSTUBLIB     = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib
 !else
-TCL_NO_DEPRECATED          = 0
+TCLSTUBLIB     = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub.lib
 !endif
-!if [nmakehlp -f $(CHECKS) "fullwarn"]
-!message *** Doing full warnings check
-WARNINGS                   = -W4
-!if [nmakehlp -l -warn:3]
-LINKERFLAGS                = $(LINKERFLAGS) -warn:3
+TCLIMPLIB      = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX:t=).lib
+# When building extensions, may be linking against Tcl that does not add
+# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
+!if !exist("$(TCLIMPLIB)")
+TCLIMPLIB      = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)t$(SUFX:t=).lib
 !endif
+TCL_LIBRARY    = $(_TCLDIR)\library
+TCLREGLIB      = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib
+TCLDDELIB      = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib
+TCLSCRIPTZIP   = $(_TCLDIR)\win\$(BUILDDIRTOP)\$(TCL_ZIP_FILE)
+TCLTOOLSDIR    = $(_TCLDIR)\tools
+TCL_INCLUDES   = -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
+
+!endif # TCLINSTALL
+
+!if !$(STATIC_BUILD) && "$(TCL_BUILD_FOR)" == "8"
+tcllibs = "$(TCLSTUBLIB)"
 !else
-WARNINGS                   = -W3
+tcllibs = "$(TCLSTUBLIB)" "$(TCLIMPLIB)"
 !endif
-!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]
-!message *** Doing 64bit portability warnings
-WARNINGS                   = $(WARNINGS) -Wp64
+
+!endif # $(DOING_TCL)
+
+# We need a tclsh that will run on the host machine as part of the build.
+# IX86 runs on all architectures.
+!ifndef TCLSH_NATIVE
+!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
+TCLSH_NATIVE   = $(TCLSH)
+!else
+!error You must explicitly set TCLSH_NATIVE for cross-compilation
 !endif
 !endif
 
-!if $(PGO) > 1
-!if [nmakehlp -l -ltcg:pgoptimize]
-LINKERFLAGS    = $(LINKERFLAGS:-ltcg=) -ltcg:pgoptimize
+# Do the same for Tk and Tk extensions that require the Tk libraries
+!if $(DOING_TK) || $(NEED_TK)
+WISHNAMEPREFIX = wish
+WISHNAME = $(WISHNAMEPREFIX)$(TK_VERSION)$(SUFX).exe
+TKLIBNAME8     = tk$(TK_VERSION)$(SUFX).$(EXT)
+TKLIBNAME9     = tcl9tk$(TK_VERSION)$(SUFX).$(EXT)
+!if $(TCL_MAJOR_VERSION) == 8 || "$(TCL_BUILD_FOR)" == "8"
+TKLIBNAME      = tk$(TK_VERSION)$(SUFX).$(EXT)
+TKIMPLIBNAME   = tk$(TK_VERSION)$(SUFX).lib
 !else
-MSG=^
-This compiler does not support profile guided optimization.
-!error $(MSG)
+TKLIBNAME      = tcl9tk$(TK_VERSION)$(SUFX).$(EXT)
+TKIMPLIBNAME   = tcl9tk$(TK_VERSION)$(SUFX).lib
 !endif
-!elseif $(PGO) > 0
-!if [nmakehlp -l -ltcg:pginstrument]
-LINKERFLAGS    = $(LINKERFLAGS:-ltcg=) -ltcg:pginstrument
+!if $(TK_MAJOR_VERSION) == 8
+TKSTUBLIBNAME  = tkstub$(TK_VERSION).lib
 !else
-MSG=^
-This compiler does not support profile guided optimization.
-!error $(MSG)
+TKSTUBLIBNAME  = tkstub.lib
+!endif
+
+!if $(DOING_TK)
+WISH           = $(OUT_DIR)\$(WISHNAME)
+TKSTUBLIB      = $(OUT_DIR)\$(TKSTUBLIBNAME)
+TKIMPLIB       = $(OUT_DIR)\$(TKIMPLIBNAME)
+TKLIB          = $(OUT_DIR)\$(TKLIBNAME)
+TK_INCLUDES     = -I"$(WIN_DIR)" -I"$(GENERICDIR)"
+TKSCRIPTZIP     = $(OUT_DIR)\$(TK_ZIP_FILE)
+
+!else # effectively NEED_TK
+
+!if $(TKINSTALL) # Building against installed Tk
+WISH           = $(_TKDIR)\bin\$(WISHNAME)
+TKSTUBLIB      = $(_TKDIR)\lib\$(TKSTUBLIBNAME)
+TKIMPLIB       = $(_TKDIR)\lib\$(TKIMPLIBNAME)
+# When building extensions, may be linking against Tk that does not add
+# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
+!if !exist("$(TKIMPLIB)")
+TKIMPLIBNAME   = tk$(TK_VERSION)$(SUFX:t=).lib
+TKIMPLIB       = $(_TKDIR)\lib\$(TKIMPLIBNAME)
 !endif
+TK_INCLUDES     = -I"$(_TKDIR)\include"
+TKSCRIPTZIP     = $(_TKDIR)\lib\$(TK_ZIP_FILE)
+
+!else # Building against Tk sources
+
+WISH           = $(_TKDIR)\win\$(BUILDDIRTOP)\$(WISHNAME)
+TKSTUBLIB      = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSTUBLIBNAME)
+TKIMPLIB       = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
+# When building extensions, may be linking against Tk that does not add
+# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
+!if !exist("$(TKIMPLIB)")
+TKIMPLIBNAME   = tk$(TK_VERSION)$(SUFX:t=).lib
+TKIMPLIB       = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
 !endif
+TK_INCLUDES     = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
+TKSCRIPTZIP     = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TK_ZIP_FILE)
 
-#----------------------------------------------------------
-# Set our defines now armed with our options.
-#----------------------------------------------------------
+!endif # TKINSTALL
+
+tklibs = "$(TKSTUBLIB)" "$(TKIMPLIB)"
+
+!endif # $(DOING_TK)
+!endif # $(DOING_TK) || $(NEED_TK)
 
-OPTDEFINES     = -DTCL_CFGVAL_ENCODING=$(CFG_ENCODING) -DSTDC_HEADERS
+# Various output paths
+PRJIMPLIB      = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
+PRJLIBNAME8    = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
+# Even when building against Tcl 8, PRJLIBNAME9 must not have "t"
+PRJLIBNAME9    = tcl9$(PROJECT)$(VERSION)$(SUFX:t=).$(EXT)
+!if $(TCL_MAJOR_VERSION) == 8 || "$(TCL_BUILD_FOR)" == "8"
+PRJLIBNAME     = $(PRJLIBNAME8)
+!else
+PRJLIBNAME     = $(PRJLIBNAME9)
+!endif
+PRJLIB         = $(OUT_DIR)\$(PRJLIBNAME)
+
+!if $(TCL_MAJOR_VERSION) == 8
+PRJSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
+!else
+PRJSTUBLIBNAME = $(STUBPREFIX).lib
+!endif
+PRJSTUBLIB     = $(OUT_DIR)\$(PRJSTUBLIBNAME)
+
+# If extension parent makefile has not defined a resource definition file,
+# we will generate one from standard template.
+!if !$(DOING_TCL) && !$(DOING_TK) && !$(STATIC_BUILD)
+!ifdef RCFILE
+RESFILE = $(TMP_DIR)\$(RCFILE:.rc=.res)
+!else
+RESFILE = $(TMP_DIR)\$(PROJECT).res
+!endif
+!endif
+
+###################################################################
+# 11. Construct the paths for the installation directories
+# The following macros get defined in this section:
+# LIB_INSTALL_DIR - where libraries should be installed
+# BIN_INSTALL_DIR - where the executables should be installed
+# DOC_INSTALL_DIR - where documentation should be installed
+# SCRIPT_INSTALL_DIR - where scripts should be installed
+# INCLUDE_INSTALL_DIR - where C include files should be installed
+# DEMO_INSTALL_DIR - where demos should be installed
+# PRJ_INSTALL_DIR - where package will be installed (not set for Tcl and Tk)
+
+!if $(DOING_TCL) || $(DOING_TK)
+LIB_INSTALL_DIR                = $(_INSTALLDIR)\lib
+BIN_INSTALL_DIR                = $(_INSTALLDIR)\bin
+DOC_INSTALL_DIR                = $(_INSTALLDIR)\doc
+!if $(DOING_TCL)
+SCRIPT_INSTALL_DIR     = $(_INSTALLDIR)\lib\$(PROJECT)$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
+MODULE_INSTALL_DIR     = $(_INSTALLDIR)\lib\tcl$(TCL_MAJOR_VERSION)
+!else # DOING_TK
+SCRIPT_INSTALL_DIR     = $(_INSTALLDIR)\lib\$(PROJECT)$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
+!endif
+DEMO_INSTALL_DIR       = $(SCRIPT_INSTALL_DIR)\demos
+INCLUDE_INSTALL_DIR    = $(_INSTALLDIR)\include
+
+!else # extension other than Tk
+
+PRJ_INSTALL_DIR         = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
+!if $(MULTIPLATFORM_INSTALL)
+LIB_INSTALL_DIR                = $(PRJ_INSTALL_DIR)\$(PLATFORM_IDENTIFY)
+BIN_INSTALL_DIR                = $(PRJ_INSTALL_DIR)\$(PLATFORM_IDENTIFY)
+!else
+LIB_INSTALL_DIR                = $(PRJ_INSTALL_DIR)
+BIN_INSTALL_DIR                = $(PRJ_INSTALL_DIR)
+!endif
+DOC_INSTALL_DIR                = $(PRJ_INSTALL_DIR)
+SCRIPT_INSTALL_DIR     = $(PRJ_INSTALL_DIR)
+DEMO_INSTALL_DIR       = $(PRJ_INSTALL_DIR)\demos
+INCLUDE_INSTALL_DIR    = $(_INSTALLDIR)\..\include
+
+!endif
+
+###################################################################
+# 12. Set up actual options to be passed to the compiler and linker
+# Now we have all the information we need, set up the actual flags and
+# options that we will pass to the compiler and linker. The main
+# makefile should use these in combination with whatever other flags
+# and switches are specific to it.
+# The following macros are defined, names are for historical compatibility:
+# OPTDEFINES - /Dxxx C macro flags based on user-specified OPTS
+# COMPILERFLAGS - /Dxxx C macro flags independent of any configuration options
+# crt - Compiler switch that selects the appropriate C runtime
+# cdebug - Compiler switches related to debug AND optimizations
+# cwarn - Compiler switches that set warning levels
+# cflags - complete compiler switches (subsumes cdebug and cwarn)
+# ldebug - Linker switches controlling debug information and optimization
+# lflags - complete linker switches (subsumes ldebug) except subsystem type
+# dlllflags - complete linker switches to build DLLs (subsumes lflags)
+# conlflags - complete linker switches for console program (subsumes lflags)
+# guilflags - complete linker switches for GUI program (subsumes lflags)
+# baselibs - minimum Windows libraries required. Parent makefile can
+#    define PRJ_LIBS before including rules.rc if additional libs are needed
+
+OPTDEFINES     = /DSTDC_HEADERS /DUSE_NMAKE=1
+!if $(VCVERSION) > 1600
+OPTDEFINES     = $(OPTDEFINES) /DHAVE_STDINT_H=1
+!else
+OPTDEFINES     = $(OPTDEFINES) /DMP_NO_STDINT=1
+!endif
+!if $(VCVERSION) >= 1800
+OPTDEFINES     = $(OPTDEFINES) /DHAVE_INTTYPES_H=1 /DHAVE_STDBOOL_H=1
+!endif
 
 !if $(TCL_MEM_DEBUG)
-OPTDEFINES     = $(OPTDEFINES) -DTCL_MEM_DEBUG
+OPTDEFINES     = $(OPTDEFINES) /DTCL_MEM_DEBUG
 !endif
 !if $(TCL_COMPILE_DEBUG)
-OPTDEFINES     = $(OPTDEFINES) -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
+OPTDEFINES     = $(OPTDEFINES) /DTCL_COMPILE_DEBUG /DTCL_COMPILE_STATS
 !endif
-!if $(TCL_THREADS)
-OPTDEFINES     = $(OPTDEFINES) -DTCL_THREADS=1
-!if $(USE_THREAD_ALLOC)
-OPTDEFINES     = $(OPTDEFINES) -DUSE_THREAD_ALLOC=1
+!if $(TCL_THREADS) && $(TCL_VERSION) < 87
+OPTDEFINES     = $(OPTDEFINES) /DTCL_THREADS=1
+!if $(USE_THREAD_ALLOC) && $(TCL_VERSION) < 87
+OPTDEFINES     = $(OPTDEFINES) /DUSE_THREAD_ALLOC=1
 !endif
 !endif
 !if $(STATIC_BUILD)
-OPTDEFINES     = $(OPTDEFINES) -DSTATIC_BUILD
+OPTDEFINES     = $(OPTDEFINES) /DSTATIC_BUILD
+!elseif $(TCL_VERSION) > 86
+OPTDEFINES     = $(OPTDEFINES) /DTCL_WITH_EXTERNAL_TOMMATH
+!if "$(MACHINE)" == "AMD64" || "$(MACHINE)" == "ARM64"
+OPTDEFINES     = $(OPTDEFINES) /DMP_64BIT
+!endif
 !endif
 !if $(TCL_NO_DEPRECATED)
-OPTDEFINES     = $(OPTDEFINES) -DTCL_NO_DEPRECATED
+OPTDEFINES     = $(OPTDEFINES) /DTCL_NO_DEPRECATED
 !endif
 
+!if $(USE_STUBS)
+# Note we do not define USE_TCL_STUBS even when building tk since some
+# test targets in tk do not use stubs
+!if !$(DOING_TCL)
+USE_STUBS_DEFS  = /DUSE_TCL_STUBS /DUSE_TCLOO_STUBS
+!if $(NEED_TK)
+USE_STUBS_DEFS  = $(USE_STUBS_DEFS) /DUSE_TK_STUBS
+!endif
+!endif
+!endif # USE_STUBS
+
 !if !$(DEBUG)
-OPTDEFINES     = $(OPTDEFINES) -DNDEBUG
+OPTDEFINES     = $(OPTDEFINES) /DNDEBUG
 !if $(OPTIMIZING)
-OPTDEFINES     = $(OPTDEFINES) -DTCL_CFG_OPTIMIZED
+OPTDEFINES     = $(OPTDEFINES) /DTCL_CFG_OPTIMIZED
 !endif
 !endif
 !if $(PROFILE)
-OPTDEFINES     = $(OPTDEFINES) -DTCL_CFG_PROFILED
+OPTDEFINES     = $(OPTDEFINES) /DTCL_CFG_PROFILED
 !endif
-!if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64"
-OPTDEFINES     = $(OPTDEFINES) -DTCL_CFG_DO64BIT
+!if "$(MACHINE)" == "AMD64" || "$(MACHINE)" == "ARM64"
+OPTDEFINES     = $(OPTDEFINES) /DTCL_CFG_DO64BIT
 !endif
 !if $(VCVERSION) < 1300
-OPTDEFINES     = $(OPTDEFINES) -DNO_STRTOI64
+OPTDEFINES     = $(OPTDEFINES) /DNO_STRTOI64=1
 !endif
 
-#----------------------------------------------------------
-# Locate the Tcl headers to build against
-#----------------------------------------------------------
-
-!if "$(PROJECT)" == "tcl"
-
-_TCL_H          = ..\generic\tcl.h
-
-!else
+!if $(TCL_MAJOR_VERSION) == 8
+!if "$(_USE_64BIT_TIME_T)" == "1"
+OPTDEFINES     = $(OPTDEFINES) /D_USE_64BIT_TIME_T=1
+!endif
+!endif
+!if "$(TCL_BUILD_FOR)" == "8"
+OPTDEFINES     = $(OPTDEFINES) /DTCL_MAJOR_VERSION=8
+!endif
 
-# If INSTALLDIR set to tcl root dir then reset to the lib dir.
-!if exist("$(_INSTALLDIR)\include\tcl.h")
-_INSTALLDIR=$(_INSTALLDIR)\lib
+# Like the TEA system only set this non empty for non-Tk extensions
+# Note: some extensions use PACKAGE_NAME and others use PACKAGE_TCLNAME
+# so we pass both
+!if !$(DOING_TCL) && !$(DOING_TK)
+PKGNAMEFLAGS = /DPACKAGE_NAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
+       /DPACKAGE_TCLNAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
+       /DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
+       /DMODULE_SCOPE=extern
 !endif
 
-!if !defined(TCLDIR)
-!if exist("$(_INSTALLDIR)\..\include\tcl.h")
-TCLINSTALL     = 1
-_TCLDIR                = $(_INSTALLDIR)\..
-_TCL_H          = $(_INSTALLDIR)\..\include\tcl.h
-TCLDIR          = $(_INSTALLDIR)\..
+# crt picks the C run time based on selected OPTS
+!if $(MSVCRT)
+!if $(DEBUG) && !$(UNCHECKED)
+crt = -MDd
 !else
-MSG=^
-Failed to find tcl.h.  Set the TCLDIR macro.
-!error $(MSG)
+crt = -MD
 !endif
 !else
-_TCLDIR        = $(TCLDIR:/=\)
-!if exist("$(_TCLDIR)\include\tcl.h")
-TCLINSTALL     = 1
-_TCL_H          = $(_TCLDIR)\include\tcl.h
-!elseif exist("$(_TCLDIR)\generic\tcl.h")
-TCLINSTALL     = 0
-_TCL_H          = $(_TCLDIR)\generic\tcl.h
+!if $(DEBUG) && !$(UNCHECKED)
+crt = -MTd
 !else
-MSG =^
-Failed to find tcl.h.  The TCLDIR macro does not appear correct.
-!error $(MSG)
-!endif
+crt = -MT
 !endif
 !endif
 
-#--------------------------------------------------------------
-# Extract various version numbers from tcl headers
-# The generated file is then included in the makefile.
-#--------------------------------------------------------------
+# cdebug includes compiler options for debugging as well as optimization.
+!if $(DEBUG)
 
-!if [echo REM = This file is generated from rules.vc > versions.vc]
-!endif
-!if [echo TCL_MAJOR_VERSION = \>> versions.vc] \
-   && [nmakehlp -V "$(_TCL_H)" TCL_MAJOR_VERSION >> versions.vc]
-!endif
-!if [echo TCL_MINOR_VERSION = \>> versions.vc] \
-   && [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc]
-!endif
-!if [echo TCL_PATCH_LEVEL = \>> versions.vc] \
-   && [nmakehlp -V "$(_TCL_H)" TCL_PATCH_LEVEL >> versions.vc]
-!endif
+# In debugging mode, optimizations need to be disabled
+cdebug = -Zi -Od $(DEBUGFLAGS)
 
-# If building the tcl core then we need additional package versions
-!if "$(PROJECT)" == "tcl"
-!if [echo PKG_HTTP_VER = \>> versions.vc] \
-   && [nmakehlp -V ..\library\http\pkgIndex.tcl http >> versions.vc]
-!endif
-!if [echo PKG_TCLTEST_VER = \>> versions.vc] \
-   && [nmakehlp -V ..\library\tcltest\pkgIndex.tcl tcltest >> versions.vc]
+!else
+
+cdebug = $(OPTIMIZATIONS)
+!if $(SYMBOLS)
+cdebug = $(cdebug) -Zi
 !endif
-!if [echo PKG_MSGCAT_VER = \>> versions.vc] \
-   && [nmakehlp -V ..\library\msgcat\pkgIndex.tcl msgcat >> versions.vc]
+
+!endif # $(DEBUG)
+
+# cwarn includes default warning levels, also C4090 (buggy) and C4146 is useless.
+cwarn = $(WARNINGS) -wd4090 -wd4146
+
+!if "$(MACHINE)" == "AMD64" || "$(MACHINE)" == "ARM64"
+# Disable pointer<->int warnings related to cast between different sizes
+# There are a gadzillion of these due to use of ClientData and
+# clutter up compiler
+# output increasing chance of a real warning getting lost. So disable them.
+# Eventually some day, Tcl will be 64-bit clean.
+cwarn = $(cwarn) -wd4311 -wd4312
 !endif
-!if [echo PKG_PLATFORM_VER = \>> versions.vc] \
-   && [nmakehlp -V ..\library\platform\pkgIndex.tcl "platform " >> versions.vc]
+
+### Common compiler options that are architecture specific
+!if "$(MACHINE)" == "ARM"
+carch = /D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
+!else
+carch =
 !endif
-!if [echo PKG_SHELL_VER = \>> versions.vc] \
-   && [nmakehlp -V ..\library\platform\pkgIndex.tcl "platform::shell" >> versions.vc]
+
+# cpuid is only available on intel machines
+!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "AMD64"
+carch = $(carch) /DHAVE_CPUID=1
 !endif
-!if [echo PKG_DDE_VER = \>> versions.vc] \
-   && [nmakehlp -V ..\library\dde\pkgIndex.tcl "dde " >> versions.vc]
+
+!if $(DEBUG)
+# Turn warnings into errors
+cwarn = $(cwarn) -WX
 !endif
-!if [echo PKG_REG_VER =\>> versions.vc] \
-   && [nmakehlp -V ..\library\reg\pkgIndex.tcl registry >> versions.vc]
+
+INCLUDES = $(TCL_INCLUDES) $(TK_INCLUDES) $(PRJ_INCLUDES)
+!if !$(DOING_TCL) && !$(DOING_TK)
+INCLUDES = $(INCLUDES) -I"$(GENERICDIR)" -I"$(WIN_DIR)" -I"$(COMPATDIR)"
 !endif
+
+# These flags are defined roughly in the order of the pre-reform
+# rules.vc/makefile.vc to help visually compare that the pre- and
+# post-reform build logs
+
+# cflags contains generic flags used for building practically all object files
+cflags = -nologo -c $(COMPILERFLAGS) $(carch) $(cwarn) -Fp$(TMP_DIR)^\ $(cdebug)
+
+!if $(TCL_MAJOR_VERSION) == 8 && $(TCL_MINOR_VERSION) < 7
+cflags = $(cflags) -DTcl_Size=int
 !endif
 
-!include versions.vc
+# appcflags contains $(cflags) and flags for building the application
+# object files (e.g. tclsh, or wish) pkgcflags contains $(cflags) plus
+# flags used for building shared object files The two differ in the
+# BUILD_$(PROJECT) macro which should be defined only for the shared
+# library *implementation* and not for its caller interface
 
-#--------------------------------------------------------------
-# Setup tcl version dependent stuff headers
-#--------------------------------------------------------------
+appcflags_nostubs = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES)
+appcflags = $(appcflags_nostubs) $(USE_STUBS_DEFS)
+pkgcflags = $(appcflags) $(PKGNAMEFLAGS) /DBUILD_$(PROJECT)
+pkgcflags_nostubs = $(appcflags_nostubs) $(PKGNAMEFLAGS) /DBUILD_$(PROJECT)
 
-!if "$(PROJECT)" != "tcl"
+# stubscflags contains $(cflags) plus flags used for building a stubs
+# library for the package.  Note: /DSTATIC_BUILD is defined in
+# $(OPTDEFINES) only if the OPTS configuration indicates a static
+# library. However the stubs library is ALWAYS static hence included
+# here irrespective of the OPTS setting.
+#
+# TBD - tclvfs has a comment that stubs libs should not be compiled with -GL
+# without stating why. Tcl itself compiled stubs libs with this flag.
+# so we do not remove it from cflags. -GL may prevent extensions
+# compiled with one VC version to fail to link against stubs library
+# compiled with another VC version. Check for this and fix accordingly.
+stubscflags = $(cflags) $(PKGNAMEFLAGS) $(PRJ_DEFINES) $(OPTDEFINES) /Zl /GL- /DSTATIC_BUILD $(INCLUDES) $(USE_STUBS_DEFS)
 
-TCL_VERSION    = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
+# Link flags
 
-!if $(TCL_VERSION) < 81
-TCL_DOES_STUBS = 0
+!if $(DEBUG)
+ldebug = -debug -debugtype:cv
 !else
-TCL_DOES_STUBS = 1
+ldebug = -release -opt:ref -opt:icf,3
+!if $(SYMBOLS)
+ldebug = $(ldebug) -debug -debugtype:cv
+!endif
 !endif
 
-!if $(TCLINSTALL)
-TCLSH          = "$(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe"
-!if !exist($(TCLSH)) && $(TCL_THREADS)
-TCLSH           = "$(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe"
+# Note: Profiling is currently only possible with the Visual Studio Enterprise
+!if $(PROFILE)
+ldebug= $(ldebug) -profile
 !endif
-TCLSTUBLIB     = "$(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib"
-TCLIMPLIB      = "$(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib"
-TCL_LIBRARY    = $(_TCLDIR)\lib
-TCLREGLIB      = "$(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib"
-TCLDDELIB      = "$(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib"
-COFFBASE       = \must\have\tcl\sources\to\build\this\target
-TCLTOOLSDIR    = \must\have\tcl\sources\to\build\this\target
-TCL_INCLUDES    = -I"$(_TCLDIR)\include"
-!else
-TCLSH          = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe"
-!if !exist($(TCLSH)) && $(TCL_THREADS)
-TCLSH          = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe"
+
+### Declarations common to all linker versions
+lflags = -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)
+
+!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
+lflags = $(lflags) -nodefaultlib:libucrt.lib
 !endif
-TCLSTUBLIB     = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib"
-TCLIMPLIB      = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib"
-TCL_LIBRARY    = $(_TCLDIR)\library
-TCLREGLIB      = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib"
-TCLDDELIB      = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib"
-COFFBASE       = "$(_TCLDIR)\win\coffbase.txt"
-TCLTOOLSDIR    = $(_TCLDIR)\tools
-TCL_INCLUDES   = -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
+
+dlllflags = $(lflags) -dll
+conlflags = $(lflags) -subsystem:console
+guilflags = $(lflags) -subsystem:windows
+
+# Libraries that are required for every image.
+# Extensions should define any additional libraries with $(PRJ_LIBS)
+winlibs   = kernel32.lib advapi32.lib
+
+!if $(NEED_TK)
+winlibs = $(winlibs) gdi32.lib user32.lib uxtheme.lib
 !endif
 
+# Avoid 'unresolved external symbol __security_cookie' errors.
+# c.f. http://support.microsoft.com/?id=894573
+!if "$(MACHINE)" == "AMD64"
+!if $(VCVERSION) > 1399 && $(VCVERSION) < 1500
+winlibs   = $(winlibs) bufferoverflowU.lib
+!endif
 !endif
 
-#-------------------------------------------------------------------------
-# Locate the Tk headers to build against
-#-------------------------------------------------------------------------
+baselibs = $(winlibs) $(PRJ_LIBS)
 
-!if "$(PROJECT)" == "tk"
-_TK_H          = ..\generic\tk.h
-_INSTALLDIR    = $(_INSTALLDIR)\..
+!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
+baselibs   = $(baselibs) ucrt.lib
 !endif
 
-!ifdef PROJECT_REQUIRES_TK
-!if !defined(TKDIR)
-!if exist("$(_INSTALLDIR)\..\include\tk.h")
-TKINSTALL      = 1
-_TKDIR         = $(_INSTALLDIR)\..
-_TK_H          = $(_TKDIR)\include\tk.h
-TKDIR          = $(_TKDIR)
-!elseif exist("$(_TCLDIR)\include\tk.h")
-TKINSTALL      = 1
-_TKDIR         = $(_TCLDIR)
-_TK_H          = $(_TKDIR)\include\tk.h
-TKDIR          = $(_TKDIR)
+################################################################
+# 13. Define standard commands, common make targets and implicit rules
+
+CCPKGCMD = $(cc32) $(pkgcflags) -Fo$(TMP_DIR)^\
+CCAPPCMD = $(cc32) $(appcflags) -Fo$(TMP_DIR)^\
+CCSTUBSCMD = $(cc32) $(stubscflags) -Fo$(TMP_DIR)^\
+
+LIBCMD = $(lib32) -nologo $(LINKERFLAGS) -out:$@
+DLLCMD = $(link32) $(dlllflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
+
+CONEXECMD = $(link32) $(conlflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
+GUIEXECMD = $(link32) $(guilflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
+RESCMD  = $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" \
+           $(TCL_INCLUDES) /DSTATIC_BUILD=$(STATIC_BUILD) \
+           /DDEBUG=$(DEBUG) -d UNCHECKED=$(UNCHECKED) \
+           /DCOMMAVERSION=$(RCCOMMAVERSION) \
+           /DDOTVERSION=\"$(DOTVERSION)\" \
+           /DVERSION=\"$(VERSION)\" \
+           /DSUFX=\"$(SUFX)\" \
+           /DPROJECT=\"$(PROJECT)\" \
+           /DPRJLIBNAME=\"$(PRJLIBNAME)\"
+
+!ifndef DEFAULT_BUILD_TARGET
+DEFAULT_BUILD_TARGET = $(PROJECT)
 !endif
+
+default-target: $(DEFAULT_BUILD_TARGET)
+
+!if $(MULTIPLATFORM_INSTALL)
+default-pkgindex:
+       @echo if {[package vsatisfies [package provide Tcl] 9.0-]} { > $(OUT_DIR)\pkgIndex.tcl
+       @echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
+           [list load [file join $$dir $(PLATFORM_IDENTIFY) $(PRJLIBNAME9)]] >> $(OUT_DIR)\pkgIndex.tcl
+       @echo } else { >> $(OUT_DIR)\pkgIndex.tcl
+       @echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
+           [list load [file join $$dir $(PLATFORM_IDENTIFY) $(PRJLIBNAME8)]] >> $(OUT_DIR)\pkgIndex.tcl
+       @echo } >> $(OUT_DIR)\pkgIndex.tcl
 !else
-_TKDIR = $(TKDIR:/=\)
-!if exist("$(_TKDIR)\include\tk.h")
-TKINSTALL      = 1
-_TK_H          = $(_TKDIR)\include\tk.h
-!elseif exist("$(_TKDIR)\generic\tk.h")
-TKINSTALL      = 0
-_TK_H          = $(_TKDIR)\generic\tk.h
+default-pkgindex:
+       @echo if {[package vsatisfies [package provide Tcl] 9.0-]} { > $(OUT_DIR)\pkgIndex.tcl
+       @echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
+           [list load [file join $$dir $(PRJLIBNAME9)]] >> $(OUT_DIR)\pkgIndex.tcl
+       @echo } else { >> $(OUT_DIR)\pkgIndex.tcl
+       @echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
+           [list load [file join $$dir $(PRJLIBNAME8)]] >> $(OUT_DIR)\pkgIndex.tcl
+       @echo } >> $(OUT_DIR)\pkgIndex.tcl
+!endif
+
+default-pkgindex-tea:
+       @if exist $(ROOT)\pkgIndex.tcl.in nmakehlp -s << $(ROOT)\pkgIndex.tcl.in > $(OUT_DIR)\pkgIndex.tcl
+@PACKAGE_VERSION@    $(DOTVERSION)
+@PACKAGE_NAME@       $(PRJ_PACKAGE_TCLNAME)
+@PACKAGE_TCLNAME@    $(PRJ_PACKAGE_TCLNAME)
+@PKG_LIB_FILE@       $(PRJLIBNAME)
+@PKG_LIB_FILE8@      $(PRJLIBNAME8)
+@PKG_LIB_FILE9@      $(PRJLIBNAME9)
+<<
+
+default-install: default-install-binaries default-install-libraries
+!if $(SYMBOLS)
+default-install: default-install-pdbs
+!endif
+
+# Again to deal with historical brokenness, there is some confusion
+# in terminlogy. For extensions, the "install-binaries" was used to
+# locate target directory for *binary shared libraries* and thus
+# the appropriate macro is LIB_INSTALL_DIR since BIN_INSTALL_DIR is
+# for executables (exes). On the other hand the "install-libraries"
+# target is for *scripts* and should have been called "install-scripts".
+default-install-binaries: $(PRJLIB)
+       @echo Installing binaries to '$(LIB_INSTALL_DIR)'
+       @if not exist "$(LIB_INSTALL_DIR)" mkdir "$(LIB_INSTALL_DIR)"
+       @$(CPY) $(PRJLIB) "$(LIB_INSTALL_DIR)" >NUL
+
+# Alias for default-install-scripts
+default-install-libraries: default-install-scripts
+
+default-install-scripts: $(OUT_DIR)\pkgIndex.tcl
+       @echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
+       @if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)"
+       @echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
+       @$(CPY) $(OUT_DIR)\pkgIndex.tcl $(SCRIPT_INSTALL_DIR)
+
+default-install-stubs:
+       @echo Installing stubs library to '$(SCRIPT_INSTALL_DIR)'
+       @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
+       @$(CPY) $(PRJSTUBLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
+
+default-install-pdbs:
+       @echo Installing PDBs to '$(LIB_INSTALL_DIR)'
+       @if not exist "$(LIB_INSTALL_DIR)" mkdir "$(LIB_INSTALL_DIR)"
+       @$(CPY) "$(OUT_DIR)\*.pdb" "$(LIB_INSTALL_DIR)\"
+
+# "emacs font-lock highlighting fix
+
+default-install-docs-html:
+       @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
+       @if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
+       @if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.html" "$(DOCDIR)\*.css" "$(DOCDIR)\*.png") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
+
+default-install-docs-n:
+       @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
+       @if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
+       @if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.n") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
+
+default-install-demos:
+       @echo Installing demos to '$(DEMO_INSTALL_DIR)'
+       @if not exist "$(DEMO_INSTALL_DIR)" mkdir "$(DEMO_INSTALL_DIR)"
+       @if exist $(DEMODIR) $(CPYDIR) "$(DEMODIR)" "$(DEMO_INSTALL_DIR)"
+
+default-clean:
+       @echo Cleaning $(TMP_DIR)\* ...
+       @if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
+       @echo Cleaning $(WIN_DIR)\nmakehlp.obj, nmakehlp.exe ...
+       @if exist $(WIN_DIR)\nmakehlp.obj del $(WIN_DIR)\nmakehlp.obj
+       @if exist $(WIN_DIR)\nmakehlp.exe del $(WIN_DIR)\nmakehlp.exe
+       @if exist $(WIN_DIR)\nmakehlp.out del $(WIN_DIR)\nmakehlp.out
+       @echo Cleaning $(WIN_DIR)\nmhlp-out.txt ...
+       @if exist $(WIN_DIR)\nmhlp-out.txt del $(WIN_DIR)\nmhlp-out.txt
+       @echo Cleaning $(WIN_DIR)\_junk.pch ...
+       @if exist $(WIN_DIR)\_junk.pch del $(WIN_DIR)\_junk.pch
+       @echo Cleaning $(WIN_DIR)\vercl.x, vercl.i ...
+       @if exist $(WIN_DIR)\vercl.x del $(WIN_DIR)\vercl.x
+       @if exist $(WIN_DIR)\vercl.i del $(WIN_DIR)\vercl.i
+       @echo Cleaning $(WIN_DIR)\versions.vc, version.vc ...
+       @if exist $(WIN_DIR)\versions.vc del $(WIN_DIR)\versions.vc
+       @if exist $(WIN_DIR)\version.vc del $(WIN_DIR)\version.vc
+
+default-hose: default-clean
+       @echo Hosing $(OUT_DIR)\* ...
+       @if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
+
+# Only for backward compatibility
+default-distclean: default-hose
+
+default-setup:
+       @if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
+       @if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
+
+!if "$(TESTPAT)" != ""
+TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
+!endif
+
+default-test: default-setup $(PROJECT)
+       @set TCLLIBPATH=$(OUT_DIR:\=/)
+       @if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
+       cd "$(TESTDIR)" && $(DEBUGGER) $(TCLSH) all.tcl $(TESTFLAGS)
+
+default-shell: default-setup $(PROJECT)
+       @set TCLLIBPATH=$(OUT_DIR:\=/)
+       @if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
+       $(DEBUGGER) $(TCLSH)
+
+# Generation of Windows version resource
+!ifdef RCFILE
+
+# Note: don't use $** in below rule because there may be other dependencies
+# and only the "main" rc must be passed to the resource compiler
+$(TMP_DIR)\$(PROJECT).res: $(RCDIR)\$(PROJECT).rc
+       $(RESCMD) $(RCDIR)\$(PROJECT).rc
+
 !else
-MSG =^
-Failed to find tk.h. The TKDIR macro does not appear correct.
-!error $(MSG)
-!endif
-!endif
+
+# If parent makefile has not defined a resource definition file,
+# we will generate one from standard template.
+$(TMP_DIR)\$(PROJECT).res: $(TMP_DIR)\$(PROJECT).rc
+
+$(TMP_DIR)\$(PROJECT).rc:
+       @$(COPY) << $(TMP_DIR)\$(PROJECT).rc
+#include <winver.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION   COMMAVERSION
+ PRODUCTVERSION        COMMAVERSION
+ FILEFLAGSMASK 0x3fL
+#ifdef DEBUG
+ FILEFLAGS     VS_FF_DEBUG
+#else
+ FILEFLAGS     0x0L
+#endif
+ FILEOS                VOS_NT_WINDOWS32
+ FILETYPE      VFT_DLL
+ FILESUBTYPE   0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+       BLOCK "040904b0"
+       BEGIN
+           VALUE "FileDescription",  "Tcl extension " PROJECT
+           VALUE "OriginalFilename", PRJLIBNAME
+           VALUE "FileVersion",      DOTVERSION
+           VALUE "ProductName",      "Package " PROJECT " for Tcl"
+           VALUE "ProductVersion",   DOTVERSION
+       END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+       VALUE "Translation", 0x409, 1200
+    END
+END
+
+<<
+
+!endif # ifdef RCFILE
+
+!ifndef DISABLE_IMPLICIT_RULES
+DISABLE_IMPLICIT_RULES = 0
 !endif
 
-#-------------------------------------------------------------------------
-# Extract Tk version numbers
-#-------------------------------------------------------------------------
+!if !$(DISABLE_IMPLICIT_RULES)
+# Implicit rule definitions - only for building library objects. For stubs and
+# main application, the makefile should define explicit rules.
 
-!if defined(PROJECT_REQUIRES_TK) || "$(PROJECT)" == "tk"
+{$(ROOT)}.c{$(TMP_DIR)}.obj::
+       $(CCPKGCMD) @<<
+$<
+<<
+
+{$(WIN_DIR)}.c{$(TMP_DIR)}.obj::
+       $(CCPKGCMD) @<<
+$<
+<<
+
+{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
+       $(CCPKGCMD) @<<
+$<
+<<
+
+{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
+       $(CCPKGCMD) @<<
+$<
+<<
+
+{$(RCDIR)}.rc{$(TMP_DIR)}.res:
+       $(RESCMD) $<
+
+{$(WIN_DIR)}.rc{$(TMP_DIR)}.res:
+       $(RESCMD) $<
+
+{$(TMP_DIR)}.rc{$(TMP_DIR)}.res:
+       $(RESCMD) $<
+
+.SUFFIXES:
+.SUFFIXES:.c .rc
 
-!if [echo TK_MAJOR_VERSION = \>> versions.vc] \
-   && [nmakehlp -V $(_TK_H) TK_MAJOR_VERSION >> versions.vc]
 !endif
-!if [echo TK_MINOR_VERSION = \>> versions.vc] \
-   && [nmakehlp -V $(_TK_H) TK_MINOR_VERSION >> versions.vc]
+
+################################################################
+# 14. Sanity check selected options against Tcl build options
+# When building an extension, certain configuration options should
+# match the ones used when Tcl was built. Here we check and
+# warn on a mismatch.
+!if !$(DOING_TCL)
+
+!if $(TCLINSTALL) # Building against an installed Tcl
+!if exist("$(_TCLDIR)\lib\nmake\tcl.nmake")
+TCLNMAKECONFIG = "$(_TCLDIR)\lib\nmake\tcl.nmake"
 !endif
-!if [echo TK_PATCH_LEVEL = \>> versions.vc] \
-   && [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc]
+!else # !$(TCLINSTALL) - building against Tcl source
+!if exist("$(_TCLDIR)\win\$(BUILDDIRTOP)\tcl.nmake")
+TCLNMAKECONFIG = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcl.nmake"
 !endif
+!endif # TCLINSTALL
 
-!include versions.vc
-
-TK_DOTVERSION  = $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
-TK_VERSION     = $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)
+!if $(CONFIG_CHECK)
+!ifdef TCLNMAKECONFIG
+!include $(TCLNMAKECONFIG)
 
-!if "$(PROJECT)" != "tk"
-!if $(TKINSTALL)
-WISH           = "$(_TKDIR)\bin\wish$(TK_VERSION)$(SUFX).exe"
-TKSTUBLIB      = "$(_TKDIR)\lib\tkstub$(TK_VERSION).lib"
-TKIMPLIB       = "$(_TKDIR)\lib\tk$(TK_VERSION)$(SUFX).lib"
-TK_INCLUDES     = -I"$(_TKDIR)\include"
-!else
-WISH           = "$(_TKDIR)\win\$(BUILDDIRTOP)\wish$(TCL_VERSION)$(SUFX).exe"
-TKSTUBLIB      = "$(_TKDIR)\win\$(BUILDDIRTOP)\tkstub$(TCL_VERSION).lib"
-TKIMPLIB       = "$(_TKDIR)\win\$(BUILDDIRTOP)\tk$(TCL_VERSION)$(SUFX).lib"
-TK_INCLUDES     = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
+!if defined(CORE_MACHINE) && "$(CORE_MACHINE)" != "$(MACHINE)"
+!error ERROR: Build target ($(MACHINE)) does not match the Tcl library architecture ($(CORE_MACHINE)).
 !endif
+!if $(TCL_VERSION) < 87 && defined(CORE_USE_THREAD_ALLOC) && $(CORE_USE_THREAD_ALLOC) != $(USE_THREAD_ALLOC)
+!message WARNING: Value of USE_THREAD_ALLOC ($(USE_THREAD_ALLOC)) does not match its Tcl core value ($(CORE_USE_THREAD_ALLOC)).
+!endif
+!if defined(CORE_DEBUG) && $(CORE_DEBUG) != $(DEBUG)
+!message WARNING: Value of DEBUG ($(DEBUG)) does not match its Tcl library configuration ($(DEBUG)).
 !endif
-
 !endif
 
+!endif # TCLNMAKECONFIG
+
+!endif # !$(DOING_TCL)
+
+
 #----------------------------------------------------------
 # Display stats being used.
 #----------------------------------------------------------
 
+!if !$(DOING_TCL)
+!message *** Building against Tcl at '$(_TCLDIR)'
+!endif
+!if !$(DOING_TK) && $(NEED_TK)
+!message *** Building against Tk at '$(_TKDIR)'
+!endif
 !message *** Intermediate directory will be '$(TMP_DIR)'
 !message *** Output directory will be '$(OUT_DIR)'
+!message *** Installation, if selected, will be in '$(_INSTALLDIR)'
 !message *** Suffix for binaries will be '$(SUFX)'
-!message *** Optional defines are '$(OPTDEFINES)'
-!message *** Compiler version $(VCVER). Target machine is $(MACHINE)
-!message *** Host architecture is $(NATIVE_ARCH)
-!message *** Compiler options '$(COMPILERFLAGS) $(OPTIMIZATIONS) $(DEBUGFLAGS) $(WARNINGS)'
-!message *** Link options '$(LINKERFLAGS)'
+!message *** Compiler version $(VCVER). Target $(MACHINE), host $(NATIVE_ARCH).
 
-!endif
+!endif # ifdef _RULES_VC
diff --git a/autoconf/tea/win/targets.vc b/autoconf/tea/win/targets.vc
new file mode 100644 (file)
index 0000000..49ed7d4
--- /dev/null
@@ -0,0 +1,98 @@
+#------------------------------------------------------------- -*- makefile -*-
+# targets.vc --
+#
+# Part of the nmake based build system for Tcl and its extensions.
+# This file defines some standard targets for the convenience of extensions
+# and can be optionally included by the extension makefile.
+# See TIP 477 (https://core.tcl-lang.org/tips/doc/main/tip/477.md) for docs.
+
+$(PROJECT): setup pkgindex $(PRJLIB)
+
+!ifdef PRJ_STUBOBJS
+$(PROJECT): $(PRJSTUBLIB)
+$(PRJSTUBLIB): $(PRJ_STUBOBJS)
+       $(LIBCMD) $**
+
+$(PRJ_STUBOBJS):
+       $(CCSTUBSCMD) %s
+!endif # PRJ_STUBOBJS
+
+!ifdef PRJ_MANIFEST
+$(PROJECT): $(PRJLIB).manifest
+$(PRJLIB).manifest: $(PRJ_MANIFEST)
+       @nmakehlp -s << $** >$@
+@MACHINE@        $(MACHINE:IX86=X86)
+<<
+!endif
+
+!if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk"
+$(PRJLIB): $(PRJ_OBJS) $(RESFILE)
+!if $(STATIC_BUILD)
+       $(LIBCMD) $**
+!else
+       $(DLLCMD) $**
+       $(_VC_MANIFEST_EMBED_DLL)
+!endif
+       -@del $*.exp
+!endif
+
+!if "$(PRJ_HEADERS)" != "" && "$(PRJ_OBJS)" != ""
+$(PRJ_OBJS): $(PRJ_HEADERS)
+!endif
+
+# If parent makefile has defined stub objects, add their installation
+# to the default install
+!if "$(PRJ_STUBOBJS)" != ""
+default-install: default-install-stubs
+!endif
+
+# Unlike the other default targets, these cannot be in rules.vc because
+# the executed command depends on existence of macro PRJ_HEADERS_PUBLIC
+# that the parent makefile will not define until after including rules-ext.vc
+!if "$(PRJ_HEADERS_PUBLIC)" != ""
+default-install: default-install-headers
+default-install-headers:
+       @echo Installing headers to '$(INCLUDE_INSTALL_DIR)'
+       @for %f in ($(PRJ_HEADERS_PUBLIC)) do @$(COPY) %f "$(INCLUDE_INSTALL_DIR)"
+!endif
+
+!if "$(DISABLE_STANDARD_TARGETS)" == ""
+DISABLE_STANDARD_TARGETS = 0
+!endif
+
+!if "$(DISABLE_TARGET_setup)" == ""
+DISABLE_TARGET_setup = 0
+!endif
+!if "$(DISABLE_TARGET_install)" == ""
+DISABLE_TARGET_install = 0
+!endif
+!if "$(DISABLE_TARGET_clean)" == ""
+DISABLE_TARGET_clean = 0
+!endif
+!if "$(DISABLE_TARGET_test)" == ""
+DISABLE_TARGET_test = 0
+!endif
+!if "$(DISABLE_TARGET_shell)" == ""
+DISABLE_TARGET_shell = 0
+!endif
+
+!if !$(DISABLE_STANDARD_TARGETS)
+!if !$(DISABLE_TARGET_setup)
+setup: default-setup
+!endif
+!if !$(DISABLE_TARGET_install)
+install: default-install
+!endif
+!if !$(DISABLE_TARGET_clean)
+clean: default-clean
+realclean: hose
+hose: default-hose
+distclean: realclean default-distclean
+!endif
+!if !$(DISABLE_TARGET_test)
+test: default-test
+!endif
+!if !$(DISABLE_TARGET_shell)
+shell: default-shell
+!endif
+!endif # DISABLE_STANDARD_TARGETS
index e88c2cb981b5d6c0edfa1d979a7ff97027c991b4..bdc204f54c5275e9eda42fee2aaa8d9fd98c0265 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Ensure\sthat\sthe\sOPFS\sVFS's\sxOpen()\swrites\sback\sthe\sread-only\sflag\sto\sthe\soutput\sflags.\sResolves\sthe\sproblem\sreported\sin\s[forum:cf37d5ff1182c31081\s|\sforum\spost\scf37d5ff1182c31081].
-D 2024-10-17T12:14:34.534
+C Attempt\sto\sget\sthe\sTEA\sbuilder\sin\sthe\samalgamation-autoconf\starball\sworking\nusing\shints\sfrom\sJan\sNijtmans.
+D 2024-10-17T13:00:56.798
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -21,18 +21,20 @@ F autoconf/Makefile.msc 0a1fdef1f2c618815cf7c82c817a7369c1e07b3cfed490803db16fb4
 F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7
 F autoconf/README.txt 42cfd21d0b19dc7d5d85fb5c405c5f3c6a4c923021c39128f6ba685355d8fd56
 F autoconf/configure.ac ec7fa914c5e74ff212fe879f9bb6918e1234497e05facfb641f30c4d5893b277
-F autoconf/tea/Makefile.in 106a96f2f745d41a0f6193f1de98d7355830b65d45032c18cd7c90295ec24196
-F autoconf/tea/README.txt 94fa2472d3ee4139ab24b364d99a70445d0a25531dac3ce03af2055d581f76b4
+F autoconf/tea/Makefile.in ba0556fee8da09c066bad85a4457904e46ee2c2eabaa309c0e83a78f2f151a8e
+F autoconf/tea/README.txt 8912dfa3e6a8ce2219ecad8186f6e7f0c192df66dc0fe95995821e2fdc0bf22b
 F autoconf/tea/aclocal.m4 52c47aac44ce0ddb1f918b6993e8beb8eee88f43
 F autoconf/tea/configure.ac 0deb5d6c49c8119f75f436488219fc043127d72057af5dfba2c9ce096a5734bc
 F autoconf/tea/doc/sqlite3.n e1fe45d4f5286ee3d0ccc877aca2a0def488e9bb
 F autoconf/tea/license.terms 13bd403c9610fd2b76ece0ab50c4c5eda933d523
 F autoconf/tea/pkgIndex.tcl.in 55aec3c6d7e9a1de9b8d2fdc9c27fd055da3ac3a51b572195e2ae7300bcfd3a2
-F autoconf/tea/tclconfig/install-sh bdd5e293591621ae60d9824d86a4b1c5f22c3d00
-F autoconf/tea/tclconfig/tcl.m4 c6e5f2fc7178f40d087403daa044ef3b86a8e30793f3b121bdcbdf152c6a776a
-F autoconf/tea/win/makefile.vc 9b33af4214a5c8360549b96380f55ece1a2df76a51ab4c726296e5c43d8a2227
+F autoconf/tea/tclconfig/install-sh 2182b3705d92e25753411e2c28cf788c69e35a48fbb8aa332e342dfc6b95b80d
+F autoconf/tea/tclconfig/tcl.m4 284faa1d9cf66c1efb42817beb5c8a63626fb35bf903993d4f11fde75677cc1a
+F autoconf/tea/win/makefile.vc 55721106928894cb818164a8ce054da11d948948f5a92a54d262dd0a6a891d4d
 F autoconf/tea/win/nmakehlp.c b01f822eabbe1ed2b64e70882d97d48402b42d2689a1ea00342d1a1a7eaa19cb
-F autoconf/tea/win/rules.vc 7b3bb2ef32ade0f3f14d951231811678722725e3bca240dd9727ae0dfe10f6a5
+F autoconf/tea/win/rules-ext.vc fd5740d97aac8c41c97eaa0fbcc0c15a41b6f7075d5f9f593e147d7a284a247a
+F autoconf/tea/win/rules.vc 94a18c3e453535459b4a643983acca52fb8756e79055bd2ad4b0999d66484f4c
+F autoconf/tea/win/targets.vc 96a25a1fa6e9e9cfb348fd3760a5395b4ce8acafc8ed10f0412937ec200d5dbd
 F config.guess 883205ddf25b46f10c181818bf42c09da9888884af96f79e1719264345053bd6
 F config.sub c2d0260f17f3e4bc0b6808fccf1b291cb5e9126c14fc5890efc77b9fd0175559
 F configure 135e050689ea244477582e6d77cc7867dfcfe6e0f82e3eab3e47655a67035f8f x
@@ -2217,8 +2219,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P b7f7a5deeae61920dbfec7606cf9014de711f959a285b29e12673abfd2f88646
-R 556651a7ceaf11a031d680d31500bcba
-U stephan
-Z c682d4ab99e571cd5091abebe964c27a
+P 0a32624015f16fd881a4ecbb56b7833391028d327a95f4c899eee864ed7fe00d
+R b46e996d43b6a1f81a9ffde97ccc1ae3
+U drh
+Z 028f07783077affaca7a4d9f85e39602
 # Remove this line to create a well-formed Fossil manifest.
index 8b47ea3fc298fafccbe837fffe07c3f5c6fd5edb..d19ed52a88c20b65869395a50e09e38b3fa4c139 100644 (file)
@@ -1 +1 @@
-0a32624015f16fd881a4ecbb56b7833391028d327a95f4c899eee864ed7fe00d
+ad9d7bdef95a8da76da0f6db358b6ffb0a0aa9097df2ff52f042e16e62afa8f5