tms: updated the nmake build files and fixed the demo to run on vista master
authorPat Thoyts <patthoyts@users.sourceforge.net>
Mon, 8 Dec 2008 01:17:36 +0000 (01:17 +0000)
committerPat Thoyts <patthoyts@users.sourceforge.net>
Mon, 8 Dec 2008 01:22:38 +0000 (01:22 +0000)
  The mailslot enumerator may need to handle permissions issues - we should
  be able to enumerate our own mailslots but there may be others without read
  access whhich we must handle.
  Fnotify needs nicer failure handling (eg for non-existent paths)

Signed-off-by: Pat Thoyts <patthoyts@users.sourceforge.net>
demos/demo.tcl
pkgIndex.tcl.in [new file with mode: 0644]
win/makefile.vc
win/nmakehlp.c
win/rules.vc

index 70e64bb657eb9114b2f4d1869ee62c7743ed49ca..c538bb114eec84a2a974f2269e4a28195f8a436b 100644 (file)
@@ -1,14 +1,8 @@
-if {[info exists tcl_platform(debug)]} {
-    set dll [file join [file dirname [info script]] Debug tms02g.dll]
-} else {
-    set dll [file join [file dirname [info script]] Release tms02.dll]
-}
-load $dll
-
-#after 10
+# Demonstrate the TMS package using Mailslots and the Win32 File notification API
 
 package require tms
 package require tms::mailslot
+package require tms::fnotify
 
 proc every {ms body} {uplevel \#0 $body; after $ms [info level 0]}
 
@@ -27,7 +21,11 @@ foreach slotname $slotnames {
 
 set slot [lindex $slots 0]
 
-puts "Mailslots: [tms::mailslot names]"
+if {[catch {tms::mailslot names} err]} {
+    puts "Mailslots: (unable to read mailslot names)"
+} else {
+    puts "Mailslots: $err"
+}
 puts "$slot configure [$slot configure]"
 
 puts [list conf -buffersize: [catch {$slot configure -buffersize} err] $err]
@@ -46,20 +44,22 @@ proc OnNotify {obj} {
     flush stdout
 }
 
-lappend fn [tms::fnotify create -path /temp -command OnNotify -flags create]
-lappend fn [tms::fnotify create -path /temp -command OnNotify -flags delete]
-lappend fn [tms::fnotify create -path /temp -command OnNotify -flags modify]
-lappend fn [tms::fnotify create -path /temp -command OnNotify -flags access]
-lappend fn [tms::fnotify create -path /temp -command OnNotify -flags rename]
-after 1500 {
-    set fname c:/temp/xyzzy.tmp
-    set f [open $fname w]; puts $f okokok; close $f
-    puts "wrote file"; flush stdout
-    set f [open $fname r]; read $f; close $f
-    puts "read file"; flush stdout
-    file rename $fname [string map {.tmp .bak} $fname]
-    puts "renamed file"; flush stdout
-    after 250 [list file delete [string map {.tmp .bak} $fname]]
+if {[info exists env(TEMP)]} {
+    lappend fn [tms::fnotify create -path $env(TEMP) -command OnNotify -flags create]
+    lappend fn [tms::fnotify create -path $env(TEMP) -command OnNotify -flags delete]
+    lappend fn [tms::fnotify create -path $env(TEMP) -command OnNotify -flags modify]
+    lappend fn [tms::fnotify create -path $env(TEMP) -command OnNotify -flags access]
+    lappend fn [tms::fnotify create -path $env(TEMP) -command OnNotify -flags rename]
+    after 1500 {
+        set fname [file join $env(TEMP) xyzzy.tmp]
+        set f [open $fname w]; puts $f okokok; close $f
+        puts "wrote file"; flush stdout
+        set f [open $fname r]; read $f; close $f
+        puts "read file"; flush stdout
+        file rename $fname [string map {.tmp .bak} $fname]
+        puts "renamed file"; flush stdout
+        after 250 [list file delete [string map {.tmp .bak} $fname]]
+    }
 }
 
 every 1000 [list tms::mailslot sendto [lindex $slotnames 0] tick]
diff --git a/pkgIndex.tcl.in b/pkgIndex.tcl.in
new file mode 100644 (file)
index 0000000..cc105a1
--- /dev/null
@@ -0,0 +1 @@
+package ifneeded @PACKAGE_NAME@ @PACKAGE_VERSION@ [list load [file join $dir @PKG_LIB_FILE@]]
\ No newline at end of file
index 5cb6e50ef39580ef80e0e7cca655f7b782c2244b..7aa6e432068561c86131525cc6a427fc465d3846 100644 (file)
@@ -232,7 +232,7 @@ cdebug      = -Zi $(OPTIMIZATIONS)
 !else
 cdebug = -Zi
 !endif
-!else if "$(MACHINE)" == "IA64"
+!else if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64"
 ### Warnings are too many, can't support warnings into errors.
 cdebug = -Zi -Od $(DEBUGFLAGS)
 !else
@@ -240,16 +240,9 @@ cdebug     = -Zi -WX $(DEBUGFLAGS)
 !endif
 
 ### Declarations common to all compiler options
-cwarn = -D _CRT_SECURE_NO_DEPRECATE -D _CRT_NONSTDC_NO_DEPRECATE
+cwarn = $(WARNINGS) -D _CRT_SECURE_NO_DEPRECATE -D _CRT_NONSTDC_NO_DEPRECATE
 cflags = -nologo -c $(COMPILERFLAGS) $(cwarn) -Fp$(TMP_DIR)^\
 
-# Warning level
-!if $(FULLWARNINGS)
-cflags = $(cflags) -W4
-!else
-cflags = $(cflags) -W3
-!endif
-
 !if $(MSVCRT)
 !if $(DEBUG) && !$(UNCHECKED)
 crt = -MDd
@@ -266,7 +259,7 @@ crt = -MT
 
 !if !$(STATIC_BUILD)
 cflags = $(cflags) -DUSE_TCL_STUBS
-!if $(USES_TK)
+!if defined(TKSTUBLIB)
 cflags = $(cflags) -DUSE_TK_STUBS
 !endif
 !endif
@@ -276,15 +269,17 @@ BASE_CFLAGS       = $(cflags) $(cdebug) $(crt) $(INCLUDES)
 CON_CFLAGS     = $(cflags) $(cdebug) $(crt) -DCONSOLE
 TCL_CFLAGS     = -DPACKAGE_NAME="\"$(PROJECT)\"" \
                   -DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
-                 -DBUILD_$(PROJECT) \
                   $(BASE_CFLAGS) $(OPTDEFINES)
 
+### Stubs files should not be compiled with -GL
+STUB_CFLAGS     = $(cflags) $(cdebug:-GL=) $(TK_DEFINES)
+
 #---------------------------------------------------------------------
 # Link flags
 #---------------------------------------------------------------------
 
 !if $(DEBUG)
-ldebug = -debug:full -debugtype:cv
+ldebug = -debug
 !if $(MSVCRT)
 ldebug = $(ldebug) -nodefaultlib:msvcrt
 !endif
@@ -295,10 +290,6 @@ ldebug     = -debug -opt:ref -opt:icf,3
 ### Declarations common to all linker options
 lflags = -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)
 
-!if $(FULLWARNINGS)
-lflags = $(lflags) -warn:3
-!endif
-
 !if $(PROFILE)
 lflags = $(lflags) -profile
 !endif
@@ -320,7 +311,7 @@ conlflags = $(lflags) -subsystem:console
 guilflags = $(lflags) -subsystem:windows
 !if !$(STATIC_BUILD)
 baselibs  = $(TCLSTUBLIB)
-!if $(USES_TK)
+!if defined(TKSTUBLIB)
 baselibs  = $(baselibs) $(TKSTUBLIB)
 !endif
 !endif
@@ -344,22 +335,21 @@ TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
 #---------------------------------------------------------------------
 
 all:       setup $(PROJECT)
-$(PROJECT): setup $(PRJLIB)  $(PRJSTUBLIB)
+$(PROJECT): setup $(PRJLIB)  $(PRJSTUBLIB) pkgIndex
 install:    install-binaries install-libraries install-docs install-demos
+pkgIndex:   setup $(OUT_DIR)\pkgIndex.tcl
 
-!if "$(OS)" == "Windows_NT"  || "$(MSVCDIR)" == "IDE"
 test: setup $(PROJECT)
-       $(TCLSH) "$(ROOT)\tests\all.tcl" $(TESTFLAGS) -loadfile <<
-load [file normalize [file join [pwd] $(PRJLIB:\=/)]]
-<<
-!else
-test: setup $(PROJECT)
-        echo Please wait while the test results are collected
-       $(TCLSH) "$(ROOT)\tests\all.tcl" $(TESTFLAGS) -loadfile << >tests.log
-load [file normalize [file join [pwd] $(PRJLIB:\=/)]]
-<<
-        type tests.log | more
-!endif
+        @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
+       @set PATH=$(_TCLBINDIR);$(PATH)
+        @set TCLLIBPATH=$(OUT_DIR:\=/) $(LIBDIR:\=/)
+       $(DEBUGGER) $(TCLSH) "$(ROOT)/tests/all.tcl" $(TESTFLAGS)
+
+shell: setup $(PROJECT)
+        @set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
+       @set PATH=$(_TCLBINDIR);$(PATH)
+        @set TCLLIBPATH=$(OUT_DIR:\=/) $(LIBDIR:\=/)
+        $(DEBUGGER) $(TCLSH) $(SCRIPT)
 
 setup:
        @if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
@@ -419,6 +409,18 @@ $<
 .SUFFIXES:
 .SUFFIXES:.c .rc
 
+#-------------------------------------------------------------------------
+# Explicit dependency rules
+#
+#-------------------------------------------------------------------------
+
+$(OUT_DIR)\pkgIndex.tcl: $(ROOT)\pkgIndex.tcl.in
+       @nmakehlp -s << $** > $@
+@PACKAGE_VERSION@    $(DOTVERSION)
+@PACKAGE_NAME@       $(PROJECT)
+@PKG_LIB_FILE@       $(PRJLIBNAME)
+<<
+
 #---------------------------------------------------------------------
 # Installation. (EDIT)
 #
@@ -435,13 +437,11 @@ install-binaries:
        @$(CPY) $(PRJHEADERS) "$(SCRIPT_INSTALL_DIR)" > NUL
 
 
-install-libraries:
+install-libraries: pkgIndex
         @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 tms $(DOTVERSION) "load \[file join [list $$dir] $(PROJECT)$(VERSION).$(EXT)\]"
-<<
+       @$(CPY) $(OUT_DIR)\pkgIndex.tcl "$(SCRIPT_INSTALL_DIR)"
 
 install-docs:
        @echo Installing documentation files to '$(DOC_INSTALL_DIR)'
@@ -458,7 +458,10 @@ install-demos:
 
 clean:
        @if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
-       @if exist $(WINDIR)\version.vc del $(WINDIR)\version.vc
+       @if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc
+       @if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
+       @if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
+       @if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch
 
 realclean: clean
        @if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
index d02d1365537fc8800773aead5cf60569e92ae9d7..7be773f37fe097e2db8e77035fd617bcfb629d92 100644 (file)
@@ -11,7 +11,7 @@
  * this file, and for a DISCLAIMER OF ALL WARRANTIES.
  *
  * ----------------------------------------------------------------------------
- * RCS: @(#) $Id: nmakehlp.c,v 1.2 2007/04/03 15:38:53 pat Exp $
+ * RCS: @(#) $Id: nmakehlp.c,v 1.21 2007/12/14 02:27:11 patthoyts Exp $
  * ----------------------------------------------------------------------------
  */
 
 #pragma comment (lib, "kernel32.lib")
 #include <stdio.h>
 #include <math.h>
+
+/*
+ * This library is required for x64 builds with _some_ versions of MSVC
+ */
 #if defined(_M_IA64) || defined(_M_AMD64)
+#if _MSC_VER >= 1400 && _MSC_VER < 1500
 #pragma comment(lib, "bufferoverflowU")
 #endif
+#endif
 
 /* ISO hack for dumb VC++ */
 #ifdef _MSC_VER
@@ -38,6 +44,7 @@ int           CheckForCompilerFeature(const char *option);
 int            CheckForLinkerFeature(const char *option);
 int            IsIn(const char *string, const char *substring);
 int            GrepForDefine(const char *file, const char *string);
+int            SubstituteFile(const char *substs, const char *filename);
 const char *    GetVersionFromFile(const char *filename, const char *match);
 DWORD WINAPI   ReadFromPipe(LPVOID args);
 
@@ -133,6 +140,18 @@ main(
                return 2;
            }
            return GrepForDefine(argv[2], argv[3]);
+       case 's':
+           if (argc == 2) {
+               chars = snprintf(msg, sizeof(msg) - 1,
+                       "usage: %s -s <substitutions file> <file>\n"
+                       "Perform a set of string map type substutitions on a file\n"
+                       "exitcodes: 0\n",
+                       argv[0]);
+               WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
+                       &dwWritten, NULL);
+               return 2;
+           }
+           return SubstituteFile(argv[2], argv[3]);
        case 'V':
            if (argc != 4) {
                chars = snprintf(msg, sizeof(msg) - 1,
@@ -286,7 +305,9 @@ CheckForCompilerFeature(
     return !(strstr(Out.buffer, "D4002") != NULL
              || strstr(Err.buffer, "D4002") != NULL
              || strstr(Out.buffer, "D9002") != NULL
-             || strstr(Err.buffer, "D9002") != NULL);
+             || strstr(Err.buffer, "D9002") != NULL
+             || strstr(Out.buffer, "D2021") != NULL
+             || strstr(Err.buffer, "D2021") != NULL);
 }
 \f
 int
@@ -558,6 +579,141 @@ GetVersionFromFile(
     }
     return szResult;
 }
+\f
+/*
+ * List helpers for the SubstituteFile function
+ */
+
+typedef struct list_item_t {
+    struct list_item_t *nextPtr;
+    char * key;
+    char * value;
+} list_item_t;
+
+/* insert a list item into the list (list may be null) */
+static list_item_t *
+list_insert(list_item_t **listPtrPtr, const char *key, const char *value)
+{
+    list_item_t *itemPtr = malloc(sizeof(list_item_t));
+    if (itemPtr) {
+       itemPtr->key = strdup(key);
+       itemPtr->value = strdup(value);
+       itemPtr->nextPtr = NULL;
+
+       while(*listPtrPtr) {
+           listPtrPtr = &(*listPtrPtr)->nextPtr;
+       }
+       *listPtrPtr = itemPtr;
+    }
+    return itemPtr;
+}
+
+static void
+list_free(list_item_t **listPtrPtr)
+{
+    list_item_t *tmpPtr, *listPtr = *listPtrPtr;
+    while (listPtr) {
+       tmpPtr = listPtr;
+       listPtr = listPtr->nextPtr;
+       free(tmpPtr->key);
+       free(tmpPtr->value);
+       free(tmpPtr);
+    }
+}
+\f
+/*
+ * SubstituteFile --
+ *     As windows doesn't provide anything useful like sed and it's unreliable
+ *     to use the tclsh you are building against (consider x-platform builds -
+ *     eg compiling AMD64 target from IX86) we provide a simple substitution
+ *     option here to handle autoconf style substitutions.
+ *     The substitution file is whitespace and line delimited. The file should
+ *     consist of lines matching the regular expression:
+ *       \s*\S+\s+\S*$
+ *
+ *     Usage is something like:
+ *       nmakehlp -S << $** > $@
+ *        @PACKAGE_NAME@ $(PACKAGE_NAME)
+ *        @PACKAGE_VERSION@ $(PACKAGE_VERSION)
+ *        <<
+ */
+
+int
+SubstituteFile(
+    const char *substitutions,
+    const char *filename)
+{
+    size_t cbBuffer = 1024;
+    static char szBuffer[1024], szCopy[1024];
+    char *szResult = NULL;
+    list_item_t *substPtr = NULL;
+    FILE *fp, *sp;
+
+    fp = fopen(filename, "rt");
+    if (fp != NULL) {
+
+       /*
+        * Build a list of substutitions from the first filename
+        */
+
+       sp = fopen(substitutions, "rt");
+       if (sp != NULL) {
+           while (fgets(szBuffer, cbBuffer, sp) != NULL) {
+               char *ks, *ke, *vs, *ve;
+               ks = szBuffer;
+               while (ks && *ks && isspace(*ks)) ++ks;
+               ke = ks;
+               while (ke && *ke && !isspace(*ke)) ++ke;
+               vs = ke;
+               while (vs && *vs && isspace(*vs)) ++vs;
+               ve = vs;
+               while (ve && *ve && !(*ve == '\r' || *ve == '\n')) ++ve;
+               *ke = 0, *ve = 0;
+               list_insert(&substPtr, ks, vs);
+           }
+           fclose(sp);
+       }
+
+       /* debug: dump the list */
+#ifdef _DEBUG
+       {
+           int n = 0;
+           list_item_t *p = NULL;
+           for (p = substPtr; p != NULL; p = p->nextPtr, ++n) {
+               fprintf(stderr, "% 3d '%s' => '%s'\n", n, p->key, p->value);
+           }
+       }
+#endif
+       
+       /*
+        * Run the substitutions over each line of the input
+        */
+       
+       while (fgets(szBuffer, cbBuffer, fp) != NULL) {
+           list_item_t *p = NULL;
+           for (p = substPtr; p != NULL; p = p->nextPtr) {
+               char *m = strstr(szBuffer, p->key);
+               if (m) {
+                   char *cp, *op, *sp;
+                   cp = szCopy;
+                   op = szBuffer;
+                   while (op != m) *cp++ = *op++;
+                   sp = p->value;
+                   while (sp && *sp) *cp++ = *sp++;
+                   op += strlen(p->key);
+                   while (*op) *cp++ = *op++;
+                   *cp = 0;
+                   memcpy(szBuffer, szCopy, sizeof(szCopy));
+               }
+           }
+           printf(szBuffer);
+       }
+       
+       list_free(&substPtr);
+    }
+    fclose(fp);
+    return 0;
+}
 
 /*
  * Local variables:
index 7fe063718338a34df9b025435deb8a53ac9f6084..b740e686ecaa19278d94c37dd23cde8d562a6ec7 100644 (file)
@@ -14,7 +14,7 @@
 # Copyright (c) 2003-2005 Patrick Thoyts
 #
 #------------------------------------------------------------------------------
-# RCS: @(#) $Id: rules.vc,v 1.2 2007/04/03 15:38:53 pat Exp $
+# RCS: @(#) $Id: rules.vc,v 1.7 2007/09/06 21:12:38 patthoyts Exp $
 #------------------------------------------------------------------------------
 
 !ifndef _RULES_VC
@@ -34,17 +34,17 @@ _INSTALLDIR = $(INSTALLDIR:/=\)
 !endif
 
 !ifndef MACHINE
+!if "$(CPU)" == "" || "$(CPU)" == "i386"
 MACHINE                = IX86
+!else
+MACHINE         = $(CPU)
+!endif
 !endif
 
 !ifndef CFG_ENCODING
 CFG_ENCODING   = \"cp1252\"
 !endif
 
-!ifndef USES_TK
-USES_TK         = 0
-!endif
-
 #----------------------------------------------------------
 # Set the proper copy method to avoid overwrite questions
 # to the user when copying files and selecting the right
@@ -91,11 +91,11 @@ MKDIR   = mkdir
 !message *** Compiler has 'Optimizations'
 OPTIMIZING     = 1
 !else
-!message *** Compiler doesn't have 'Optimizations'
+!message *** Compiler does not have 'Optimizations'
 OPTIMIZING     = 0
 !endif
 
-OPTIMIZATIONS  =
+OPTIMIZATIONS   =
 
 !if [nmakehlp -c -Ot]
 OPTIMIZATIONS  = $(OPTIMIZATIONS) -Ot
@@ -148,7 +148,7 @@ OPTIMIZATIONS  = $(OPTIMIZATIONS) -YX
 !message *** Compiler has 'Pentium 0x0f fix'
 COMPILERFLAGS  = $(COMPILERFLAGSS) -QI0f
 !else
-!message *** Compiler doesn't have 'Pentium 0x0f fix'
+!message *** Compiler does not have 'Pentium 0x0f fix'
 !endif
 !endif
 
@@ -168,7 +168,7 @@ COMPILERFLAGS   = $(COMPILERFLAGS) -QIA64_Bx
 !message *** Linker has 'Win98 alignment problem'
 ALIGN98_HACK   = 1
 !else
-!message *** Linker doesn't have 'Win98 alignment problem'
+!message *** Linker does not have 'Win98 alignment problem'
 ALIGN98_HACK   = 0
 !endif
 !else
@@ -192,10 +192,10 @@ VCVER=0
 !if ![echo VCVERSION=_MSC_VER > vercl.x] \
     && ![cl -nologo -TC -P vercl.x $(ERRNULL)]
 !include vercl.i
-!if $(VCVERSION) >= 1400
+!if $(VCVERSION) >= 1500
+VCVER=9
+!elseif $(VCVERSION) >= 1400
 VCVER=8
-_VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1
-_VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
 !elseif $(VCVERSION) >= 1300
 VCVER=7
 !elseif $(VCVERSION) >= 1200
@@ -203,6 +203,12 @@ VCVER=6
 !endif
 !endif
 
+# Since MSVC8 we must deal with manifest resources.
+!if $(VCVERSION) >= 1400
+_VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1
+_VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
+!endif
+
 #----------------------------------------------------------
 # Decode the options requested.
 #----------------------------------------------------------
@@ -390,7 +396,7 @@ TCL_COMPILE_DEBUG   = 0
 
 !if "$(CHECKS)" == "" || [nmakehlp -f "$(CHECKS)" "none"]
 TCL_NO_DEPRECATED          = 0
-FULLWARNINGS               = 0
+WARNINGS                   = -W3
 !else
 !if [nmakehlp -f $(CHECKS) "nodep"]
 !message *** Doing nodep check
@@ -400,12 +406,18 @@ TCL_NO_DEPRECATED     = 0
 !endif
 !if [nmakehlp -f $(CHECKS) "fullwarn"]
 !message *** Doing full warnings check
-FULLWARNINGS               = 1
+WARNINGS                   = -W4
+!if [nmakehlp -l -warn:3]
+LINKERFLAGS                = $(LINKERFLAGS) -warn:3
+!endif
 !else
-FULLWARNINGS               = 0
+WARNINGS                   = -W3
+!endif
+!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]
+!message *** Doing 64bit portability warnings
+WARNINGS                   = $(WARNINGS) -Wp64
 !endif
 !endif
-
 
 #----------------------------------------------------------
 # Set our defines now armed with our options.
@@ -443,16 +455,20 @@ OPTDEFINES        = $(OPTDEFINES) -DTCL_CFG_OPTIMIZED
 !if $(PROFILE)
 OPTDEFINES     = $(OPTDEFINES) -DTCL_CFG_PROFILED
 !endif
-!if "$(MACHINE)" == "IA64"
+!if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64"
 OPTDEFINES     = $(OPTDEFINES) -DTCL_CFG_DO64BIT
 !endif
 
 
 #----------------------------------------------------------
-# Get common info used when building extensions.
+# Locate the Tcl headers to build against
 #----------------------------------------------------------
 
-!if "$(PROJECT)" != "tcl"
+!if "$(PROJECT)" == "tcl"
+
+_TCL_H          = ..\generic\tcl.h
+
+!else
 
 # If INSTALLDIR set to tcl root dir then reset to the lib dir.
 !if exist("$(_INSTALLDIR)\include\tcl.h")
@@ -484,39 +500,101 @@ Failed to find tcl.h.  The TCLDIR macro does not appear correct.
 !error $(MSG)
 !endif
 !endif
+!endif
 
-!if [echo REM = This file is generated from rules.vc > version.vc]
+#--------------------------------------------------------------
+# Extract various version numbers from tcl headers
+# The generated file is then included in the makefile.
+#--------------------------------------------------------------
+
+!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 exist("$(_TCL_H)")
-!if [echo TCL_DOTVERSION = \>> version.vc] \
-   && [nmakehlp -V "$(_TCL_H)" TCL_VERSION >> version.vc]
+!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
+
+# 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]
+!endif
+!if [echo PKG_MSGCAT_VER = \>> versions.vc] \
+   && [nmakehlp -V ..\library\msgcat\pkgIndex.tcl msgcat >> versions.vc]
+!endif
+!if [echo PKG_PLATFORM_VER = \>> versions.vc] \
+   && [nmakehlp -V ..\library\platform\pkgIndex.tcl "platform " >> versions.vc]
+!endif
+!if [echo PKG_SHELL_VER = \>> versions.vc] \
+   && [nmakehlp -V ..\library\platform\pkgIndex.tcl "platform::shell" >> versions.vc]
+!endif
+!endif
+
+!include versions.vc
+
+#--------------------------------------------------------------
+# Setup tcl version dependent stuff headers
+#--------------------------------------------------------------
+
+!if "$(PROJECT)" != "tcl"
+
+TCL_VERSION    = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
+
+!if $(TCL_VERSION) < 81
+TCL_DOES_STUBS = 0
+!else
+TCL_DOES_STUBS = 1
 !endif
-!include version.vc
-TCL_VERSION    = $(TCL_DOTVERSION:.=)
 
 !if $(TCLINSTALL)
-TCLSH          = "$(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe"
+_TCLBINDIR      = "$(_TCLDIR)\bin"
+TCLSH          = "$(_TCLBINDIR)\tclsh$(TCL_VERSION)$(SUFX).exe"
+!if !exist($(TCLSH)) && $(TCL_THREADS)
+TCLSH           = "$(_TCLBINDIR)\tclsh$(TCL_VERSION)t$(SUFX).exe"
+!endif
 TCLSTUBLIB     = "$(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib"
 TCLIMPLIB      = "$(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib"
 TCL_LIBRARY    = $(_TCLDIR)\lib
+TCLREGLIB      = "$(_TCLDIR)\lib\tclreg11$(SUFX:t=).lib"
+TCLDDELIB      = "$(_TCLDIR)\lib\tcldde12$(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"
+_TCLBINDIR      = $(_TCLDIR)\win\$(BUILDDIRTOP)
+TCLSH          = "$(_TCLBINDIR)\tclsh$(TCL_VERSION)$(SUFX).exe"
+!if !exist($(TCLSH)) && $(TCL_THREADS)
+TCLSH          = "$(_TCLBINDIR)\tclsh$(TCL_VERSION)t$(SUFX).exe"
+!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)\tclreg11$(SUFX:t=).lib"
+TCLDDELIB      = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde12$(SUFX:t=).lib"
+COFFBASE       = "$(_TCLDIR)\win\coffbase.txt"
+TCLTOOLSDIR    = $(_TCLDIR)\tools
 TCL_INCLUDES   = -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
 !endif
 
 !endif
 
-#----------------------------------------------------------
-# Optionally check for Tk info for building extensions.
-#----------------------------------------------------------
+#-------------------------------------------------------------------------
+# Locate the Tk headers to build against
+#-------------------------------------------------------------------------
 
-!if $(USES_TK)
+!if "$(PROJECT)" == "tk"
+_TK_H          = ..\generic\tk.h
+!endif
 
+!ifdef PROJECT_REQUIRES_TK
 !if !defined(TKDIR)
 !if exist("$(_INSTALLDIR)\..\include\tk.h")
 TKINSTALL      = 1
@@ -528,10 +606,6 @@ TKINSTALL      = 1
 _TKDIR         = $(_TCLDIR)
 _TK_H          = $(_TKDIR)\include\tk.h
 TKDIR          = $(_TKDIR)
-!else
-MSG =^
-Failed to find tk.h. Set the TKDIR macro.
-!error $(MSG)
 !endif
 !else
 _TKDIR = $(TKDIR:/=\)
@@ -547,27 +621,52 @@ Failed to find tk.h. The TKDIR macro does not appear correct.
 !error $(MSG)
 !endif
 !endif
+!endif
+
+#-------------------------------------------------------------------------
+# Extract Tk version numbers
+#-------------------------------------------------------------------------
+
+!if defined(PROJECT_REQUIRES_TK) || "$(PROJECT)" == "tk"
 
-TK_DOTVERSION = 8.4
-!if exist("$(_TK_H)")
-!if [echo TK_DOTVERSION = \>> version.vc] \
-   && [nmakehlp -V "$(_TK_H)" TK_VERSION >> version.vc]
+!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]
 !endif
-!include version.vc
-TK_VERSION = $(TK_DOTVERSION:.=)
+!if [echo TK_PATCH_LEVEL = \>> versions.vc] \
+   && [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc]
+!endif
+
+!include versions.vc
+
+TK_DOTVERSION  = $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
+TK_VERSION     = $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)
 
+!if "$(PROJECT)" != "tk"
 !if $(TKINSTALL)
-WISH           = "$(_TKDIR)\bin\wish$(TK_VERSION)$(SUFX).exe"
+_TKBINDIR       = $(_TKDIR)\bin
+WISH           = "$(_TKBINDIR)\wish$(TK_VERSION)$(SUFX).exe"
+!if !exist($(WISH)) && $(TCL_THREADS)
+WISH           = "$(_TKBINDIR)\wish$(TK_VERSION)t$(SUFX).exe"
+!endif
 TKSTUBLIB      = "$(_TKDIR)\lib\tkstub$(TK_VERSION).lib"
+TK_LIBRARY     = $(_TKDIR)\lib
 TKIMPLIB       = "$(_TKDIR)\lib\tk$(TK_VERSION)$(SUFX).lib"
 TK_INCLUDES     = -I"$(_TKDIR)\include"
 !else
-WISH           = "$(_TKDIR)\win\$(BUILDDIRTOP)\wish$(TCL_VERSION)$(SUFX).exe"
+_TKBINDIR       = $(_TKDIR)\win\$(BUILDDIRTOP)
+WISH           = "$(_TKBINDIR)\wish$(TCL_VERSION)$(SUFX).exe"
+!if !exist($(WISH)) && $(TCL_THREADS)
+WISH           = "$(_TKBINDIR)\wish$(TCL_VERSION)t$(SUFX).exe"
+!endif
 TKSTUBLIB      = "$(_TKDIR)\win\$(BUILDDIRTOP)\tkstub$(TCL_VERSION).lib"
 TKIMPLIB       = "$(_TKDIR)\win\$(BUILDDIRTOP)\tk$(TCL_VERSION)$(SUFX).lib"
+TK_LIBRARY     = $(_TKDIR)\library
 TK_INCLUDES     = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
 !endif
+!endif
 
 !endif
 
@@ -579,8 +678,8 @@ TK_INCLUDES     = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
 !message *** Output directory will be '$(OUT_DIR)'
 !message *** Suffix for binaries will be '$(SUFX)'
 !message *** Optional defines are '$(OPTDEFINES)'
-!message *** Compiler version $(VCVER)
-!message *** Compiler options '$(OPTIMIZATIONS) $(DEBUGFLAGS)'
+!message *** Compiler version $(VCVER). Target machine is $(MACHINE)
+!message *** Compiler options '$(COMPILERFLAGS) $(OPTIMIZATIONS) $(DEBUGFLAGS) $(WARNINGS)'
 !message *** Link options '$(LINKERFLAGS)'
 
 !endif