Tcl Extension Architecture (TEA) Sample Extension

Check-in [4115e0a088]
Login
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to tclconference@googlegroups.com
or submit via the online form by Sep 9.

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Final version of nmake files from tcl
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | vc-reform
Files: files | file ages | folders
SHA3-256:4115e0a0889edb7273cf9f476fa073cbdeea97591276dab206b57d217ffa4d2e
User & Date: apnadkarni 2017-12-09 13:10:50
Context
2017-12-09
13:30
TIP 477: New nmake build system check-in: 69bfd8f142 user: apnadkarni tags: trunk
13:10
Final version of nmake files from tcl Closed-Leaf check-in: 4115e0a088 user: apnadkarni tags: vc-reform
2017-11-20
04:18
Removed leftovre obsolete comment check-in: fdd8b59782 user: ashok tags: vc-reform
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to win/nmakehlp.c.

   156    156   	    }
   157    157   	    s = GetVersionFromFile(argv[2], argv[3], *(argv[1]+2) - '0');
   158    158   	    if (s && *s) {
   159    159   		printf("%s\n", s);
   160    160   		return 0;
   161    161   	    } else
   162    162   		return 1; /* Version not found. Return non-0 exit code */
   163         -		
          163  +
   164    164   	case 'Q':
   165    165   	    if (argc != 3) {
   166    166   		chars = snprintf(msg, sizeof(msg) - 1,
   167    167   		    "usage: %s -Q path\n"
   168    168   		    "Emit the fully qualified path\n"
   169    169   		    "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
   170    170   		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,

Changes to win/rules-ext.vc.

     1      1   # This file should only be included in makefiles for Tcl extensions,
     2      2   # NOT in the makefile for Tcl itself.
     3      3   
     4      4   !ifndef _RULES_EXT_VC
     5      5   
     6         -!if !exist("rules-ext.vc")
            6  +# We need to run from the directory the parent makefile is located in.
            7  +# nmake does not tell us what makefile was used to invoke it so parent
            8  +# makefile has to set the MAKEFILEVC macro or we just make a guess and
            9  +# warn if we think that is not the case.
           10  +!if "$(MAKEFILEVC)" == ""
           11  +
           12  +!if exist("$(PROJECT).vc")
           13  +MAKEFILEVC = $(PROJECT).vc
           14  +!elseif exist("makefile.vc")
           15  +MAKEFILEVC = makefile.vc
           16  +!endif
           17  +!endif # "$(MAKEFILEVC)" == ""
           18  +
           19  +!if !exist("$(MAKEFILEVC)")
     7     20   MSG = ^
     8         -You must run this makefile only from the directory it is in.^
     9         -Please `cd` to its location first.
    10         -!error $(MSG)
           21  +You must run nmake from the directory containing the project makefile.^
           22  +If you are doing that and getting this message, set the MAKEFILEVC^
           23  +macro to the name of the project makefile.
           24  +!message WARNING: $(MSG)
    11     25   !endif
    12     26   
    13     27   !if "$(PROJECT)" == "tcl"
    14     28   !error The rules-ext.vc file is not intended for Tcl itself.
    15     29   !endif
    16     30   
    17     31   # First locate the Tcl directory that we are working with.
................................................................................
    27     41   _RULESDIR=$(INSTALLDIR:/=\)
    28     42   !else
    29     43   _RULESDIR = ..\..\tcl
    30     44   !endif
    31     45   
    32     46   !endif # ifndef TCLDIR
    33     47   
    34         -# Now look for the rules.vc file under the Tcl root
    35         -!if exist("$(_RULESDIR)\lib\nmake\rules.vc") # Building against installed Tcl
           48  +# Now look for the targets.vc file under the Tcl root. Note we check this
           49  +# file and not rules.vc because the latter also exists on older systems.
           50  +!if exist("$(_RULESDIR)\lib\nmake\targets.vc") # Building against installed Tcl
    36     51   _RULESDIR = $(_RULESDIR)\lib\nmake
    37         -!elseif exist("$(_RULESDIR)\win\rules.vc")   # Building against Tcl sources
           52  +!elseif exist("$(_RULESDIR)\win\targets.vc")   # Building against Tcl sources
    38     53   _RULESDIR = $(_RULESDIR)\win
    39     54   !else
    40         -# If we have not located Tcl's rules file, most likely we are compiling
           55  +# If we have not located Tcl's targets file, most likely we are compiling
    41     56   # against an older version of Tcl and so must use our own support files.
    42     57   _RULESDIR = .
    43     58   !endif
    44     59   
    45     60   !if "$(_RULESDIR)" != "."
    46         -# Potentially using Tcl's support files. Need to compare the versions.
    47         -# We extract version numbers using the nmakehlp program. For this
    48         -# purpose, we use the version of nmakehlp that we have. 
    49         -!if [$(CC) -nologo nmakehlp.c -link -subsystem:console > nul]
           61  +# Potentially using Tcl's support files. If this extension has its own
           62  +# nmake support files, need to compare the versions and pick newer.
           63  +
           64  +!if exist("rules.vc") # The extension has its own copy
           65  +
           66  +# We extract version numbers using the nmakehlp program.
           67  +!if [$(CC) -nologo "$(_RULESDIR)\nmakehlp.c" -link -subsystem:console > nul]
    50     68   !endif
    51     69   
    52     70   !if [echo TCL_RULES_MAJOR = \> versions.vc] \
    53     71      && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MAJOR >> versions.vc]
    54     72   !endif
    55     73   !if [echo TCL_RULES_MINOR = \>> versions.vc] \
    56     74      && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MINOR >> versions.vc]
................................................................................
    64     82   !endif
    65     83   !include versions.vc
    66     84   # We have a newer version of the support files, use them
    67     85   !if ($(TCL_RULES_MAJOR) != $(OUR_RULES_MAJOR)) || ($(TCL_RULES_MINOR) < $(OUR_RULES_MINOR))
    68     86   _RULESDIR = .
    69     87   !endif
    70     88   
    71         -!endif # $(_RULESDIR) != "."
           89  +!endif # if exist("rules.vc")
           90  +
           91  +!endif # if $(_RULESDIR) != "."
    72     92   
    73     93   # Let rules.vc know what copy of nmakehlp.c to use.
    74     94   NMAKEHLPC = $(_RULESDIR)\nmakehlp.c
    75     95   
    76     96   # Get rid of our internal defines before calling rules.vc
    77     97   !undef TCL_RULES_MAJOR
    78     98   !undef TCL_RULES_MINOR
    79     99   !undef OUR_RULES_MAJOR
    80    100   !undef OUR_RULES_MINOR
    81    101   
          102  +!if exist("$(_RULESDIR)\rules.vc")
    82    103   !message *** Using $(_RULESDIR)\rules.vc
    83    104   !include "$(_RULESDIR)\rules.vc"
          105  +!else
          106  +!error *** Could not locate rules.vc in $(_RULESDIR)
          107  +!endif
    84    108   
    85    109   !endif # _RULES_EXT_VC

Changes to win/rules.vc.

     1      1   #------------------------------------------------------------- -*- makefile -*-
     2      2   # rules.vc --
     3      3   #
     4         -#	Microsoft Visual C++ makefile include for decoding the commandline
     5         -#	macros.  This file does not need editing to build Tcl.
            4  +# Part of the nmake based build system for Tcl and its extensions.
            5  +# This file does all the hard work in terms of parsing build options,
            6  +# compiler switches, defining common targets and macros. The Tcl makefile
            7  +# directly includes this. Extensions include it via "rules-ext.vc".
            8  +#
            9  +# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
           10  +# detailed documentation.
     6     11   #
     7     12   # See the file "license.terms" for information on usage and redistribution
     8     13   # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
     9     14   #
    10     15   # Copyright (c) 2001-2003 David Gravereaux.
    11     16   # Copyright (c) 2003-2008 Patrick Thoyts
    12     17   # Copyright (c) 2017      Ashok P. Nadkarni
    13     18   #------------------------------------------------------------------------------
    14     19   
    15     20   !ifndef _RULES_VC
    16     21   _RULES_VC = 1
    17     22   
    18     23   # The following macros define the version of the rules.vc nmake build system
           24  +# For modifications that are not backward-compatible, you *must* change
           25  +# the major version.
    19     26   RULES_VERSION_MAJOR = 1
    20     27   RULES_VERSION_MINOR = 0
    21     28   
    22     29   # The PROJECT macro must be defined by parent makefile.
    23         -# Also special case Tcl and Tk to save some typing later
    24         -!ifndef PROJECT
           30  +!if "$(PROJECT)" == ""
    25     31   !error *** Error: Macro PROJECT not defined! Please define it before including rules.vc
    26     32   !endif
           33  +
           34  +!if "$(PRJ_PACKAGE_TCLNAME)" == ""
           35  +PRJ_PACKAGE_TCLNAME = $(PROJECT)
           36  +!endif
           37  +
           38  +# Also special case Tcl and Tk to save some typing later
    27     39   DOING_TCL = 0
    28     40   DOING_TK  = 0
    29     41   !if "$(PROJECT)" == "tcl"
    30     42   DOING_TCL = 1
    31     43   !elseif "$(PROJECT)" == "tk"
    32     44   DOING_TK = 1
    33     45   !endif
    34     46   
    35         -!ifndef PROJECT_REQUIRES_TK
    36         -PROJECT_REQUIRES_TK = 0
           47  +!ifndef NEED_TK
           48  +# Backwards compatibility
           49  +!ifdef PROJECT_REQUIRES_TK
           50  +NEED_TK = $(PROJECT_REQUIRES_TK)
           51  +!else
           52  +NEED_TK = 0
           53  +!endif
           54  +!endif
           55  +
           56  +!ifndef NEED_TCL_SOURCE
           57  +NEED_TCL_SOURCE = 0
           58  +!endif
           59  +
           60  +!ifdef NEED_TK_SOURCE
           61  +!if $(NEED_TK_SOURCE)
           62  +NEED_TK = 1
           63  +!endif
           64  +!else
           65  +NEED_TK_SOURCE = 0
    37     66   !endif
    38     67   
    39     68   ################################################################
    40     69   # Nmake is a pretty weak environment in syntax and capabilities
    41     70   # so this file is necessarily verbose. It's broken down into
    42     71   # the following parts.
    43     72   #
................................................................................
    66     95   #
    67     96   # One final note about the macro names used. They are as they are
    68     97   # for historical reasons. We would like legacy extensions to
    69     98   # continue to work with this make include file so be wary of
    70     99   # changing them for consistency or clarity.
    71    100   
    72    101   # 0. Sanity check compiler environment
          102  +
    73    103   # Check to see we are configured to build with MSVC (MSDEVDIR, MSVCDIR or
    74    104   # VCINSTALLDIR) or with the MS Platform SDK (MSSDK or WindowsSDKDir)
    75    105   
    76    106   !if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(VCINSTALLDIR) && !defined(MSSDK) && !defined(WINDOWSSDKDIR)
    77    107   MSG = ^
    78    108   Visual C++ compiler environment not initialized.
    79    109   !error $(MSG)
    80    110   !endif
          111  +
          112  +# We need to run from the directory the parent makefile is located in.
          113  +# nmake does not tell us what makefile was used to invoke it so parent
          114  +# makefile has to set the MAKEFILEVC macro or we just make a guess and
          115  +# warn if we think that is not the case.
          116  +!if "$(MAKEFILEVC)" == ""
          117  +
          118  +!if exist("$(PROJECT).vc")
          119  +MAKEFILEVC = $(PROJECT).vc
          120  +!elseif exist("makefile.vc")
          121  +MAKEFILEVC = makefile.vc
          122  +!endif
          123  +!endif # "$(MAKEFILEVC)" == ""
          124  +
          125  +!if !exist("$(MAKEFILEVC)")
          126  +MSG = ^
          127  +You must run nmake from the directory containing the project makefile.^
          128  +If you are doing that and getting this message, set the MAKEFILEVC^
          129  +macro to the name of the project makefile.
          130  +!message WARNING: $(MSG)
          131  +!endif
          132  +
    81    133   
    82    134   ################################################################
    83    135   # 1. Define external programs being used
    84    136   
    85    137   #----------------------------------------------------------
    86    138   # Set the proper copy method to avoid overwrite questions
    87    139   # to the user when copying files and selecting the right
    88    140   # "delete all" method.
    89    141   #----------------------------------------------------------
    90    142   
    91    143   RMDIR	= rmdir /S /Q
    92         -ERRNULL  = 2>NUL
    93    144   CPY	= xcopy /i /y >NUL
          145  +CPYDIR  = xcopy /e /i /y >NUL
    94    146   COPY	= copy /y >NUL
    95    147   MKDIR   = mkdir
    96    148   
    97    149   ######################################################################
    98    150   # 2. Figure out our build environment in terms of what we're building.
    99    151   #
   100    152   # (a) Tcl itself
................................................................................
   107    159   #
   108    160   # The fragment will set the following macros:
   109    161   # ROOT - root of this module sources
   110    162   # COMPATDIR - source directory that holds compatibility sources
   111    163   # DOCDIR - source directory containing documentation files
   112    164   # GENERICDIR - platform-independent source directory
   113    165   # WINDIR - Windows-specific source directory
          166  +# TESTDIR - directory containing test files
   114    167   # TOOLSDIR - directory containing build tools
   115    168   # _TCLDIR - root of the Tcl installation OR the Tcl sources. Not set
   116    169   #    when building Tcl itself.
   117    170   # _INSTALLDIR - native form of the installation path. For Tcl
   118    171   #    this will be the root of the Tcl installation. For extensions
   119    172   #    this will be the lib directory under the root.
   120    173   # TCLINSTALL  - set to 1 if _TCLDIR refers to
................................................................................
   141    194   !endif
   142    195   !ifndef GENERICDIR
   143    196   GENERICDIR	= $(ROOT)\generic
   144    197   !endif
   145    198   !ifndef TOOLSDIR
   146    199   TOOLSDIR	= $(ROOT)\tools
   147    200   !endif
          201  +!ifndef TESTDIR
          202  +TESTDIR	= $(ROOT)\tests
          203  +!endif
   148    204   !ifndef LIBDIR
          205  +!if exist("$(ROOT)\library")
   149    206   LIBDIR          = $(ROOT)\library
          207  +!else
          208  +LIBDIR          = $(ROOT)\lib
          209  +!endif
   150    210   !endif
   151    211   !ifndef DEMODIR
   152    212   !if exist("$(LIBDIR)\demos")
   153    213   DEMODIR		= $(LIBDIR)\demos
   154    214   !else
   155    215   DEMODIR		= $(ROOT)\demos
   156    216   !endif
   157    217   !endif # ifndef DEMODIR
   158    218   # Do NOT enclose WINDIR in a !ifndef because Windows always defines
   159    219   # WINDIR env var to point to c:\windows!
   160    220   # TBD - This is a potentially dangerous conflict, rename WINDIR to
   161    221   # something else
   162    222   WINDIR		= $(ROOT)\win
          223  +
   163    224   !ifndef RCDIR
          225  +!if exist("$(WINDIR)\rc")
   164    226   RCDIR           = $(WINDIR)\rc
          227  +!else
          228  +RCDIR           = $(WINDIR)
          229  +!endif
   165    230   !endif
   166    231   RCDIR = $(RCDIR:/=\)
   167    232   
   168    233   # The target directory where the built packages and binaries will be installed.
   169    234   # INSTALLDIR is the (optional) path specified by the user.
   170    235   # _INSTALLDIR is INSTALLDIR using the backslash separator syntax
   171    236   !ifdef INSTALLDIR
................................................................................
   186    251   # END Case 2(a) - Building Tcl itself
   187    252   
   188    253   !elseif $(DOING_TK)
   189    254   
   190    255   # BEGIN Case 2(b) - Building Tk
   191    256   
   192    257   TCLINSTALL = 0 # Tk always builds against Tcl source, not an installed Tcl
   193         -!ifndef TCLDIR
          258  +!if "$(TCLDIR)" == ""
   194    259   TCLDIR  = ../../tcl
   195    260   !endif
   196    261   _TCLDIR	= $(TCLDIR:/=\)
   197    262   _TCL_H  = $(_TCLDIR)\generic\tcl.h
   198    263   !if !exist("$(_TCL_H)")
   199    264   !error Could not locate tcl.h. Please set the TCLDIR macro to point to the Tcl *source* directory.
   200    265   !endif
................................................................................
   205    270   
   206    271   !else
   207    272   
   208    273   # BEGIN Case 2(c) or (d) - Building an extension other than Tk
   209    274   
   210    275   # If command line has specified Tcl location through TCLDIR, use it
   211    276   # else default to the INSTALLDIR setting
   212         -!ifdef TCLDIR
          277  +!if "$(TCLDIR)" != ""
   213    278   
   214    279   _TCLDIR	= $(TCLDIR:/=\)
   215    280   !if exist("$(_TCLDIR)\include\tcl.h") # Case 2(c) with TCLDIR defined
   216    281   TCLINSTALL	= 1
   217    282   _TCL_H          = $(_TCLDIR)\include\tcl.h
   218    283   !elseif exist("$(_TCLDIR)\generic\tcl.h") # Case 2(d) with TCLDIR defined
   219    284   TCLINSTALL	= 0
................................................................................
   241    306   !ifndef _TCL_H
   242    307   MSG =^
   243    308   Failed to find tcl.h. The TCLDIR macro is set incorrectly or is not set and default path does not contain tcl.h.
   244    309   !error $(MSG)
   245    310   !endif
   246    311   
   247    312   # Now do the same to locate Tk headers and libs if project requires Tk
   248         -!if $(PROJECT_REQUIRES_TK)
          313  +!if $(NEED_TK)
   249    314   
   250         -!ifdef TKDIR
          315  +!if "$(TKDIR)" != ""
   251    316   
   252    317   _TKDIR = $(TKDIR:/=\)
   253    318   !if exist("$(_TKDIR)\include\tk.h")
   254    319   TKINSTALL      = 1
   255    320   _TK_H          = $(_TKDIR)\include\tk.h
   256    321   !elseif exist("$(_TKDIR)\generic\tk.h")
   257    322   TKINSTALL      = 0
................................................................................
   276    341   
   277    342   !ifndef _TK_H
   278    343   MSG =^
   279    344   Failed to find tk.h. The TKDIR macro is set incorrectly or is not set and default path does not contain tk.h.
   280    345   !error $(MSG)
   281    346   !endif
   282    347   
   283         -!endif # PROJECT_REQUIRES_TK
          348  +!endif # NEED_TK
          349  +
          350  +!if $(NEED_TCL_SOURCE) && $(TCLINSTALL)
          351  +MSG = ^
          352  +*** Warning: This extension requires the source distribution of Tcl.^
          353  +*** Please set the TCLDIR macro to point to the Tcl sources.
          354  +!error $(MSG)
          355  +!endif
          356  +
          357  +!if $(NEED_TK_SOURCE)
          358  +!if $(TKINSTALL)
          359  +MSG = ^
          360  +*** Warning: This extension requires the source distribution of Tk.^
          361  +*** Please set the TKDIR macro to point to the Tk sources.
          362  +!error $(MSG)
          363  +!endif
          364  +!endif
          365  +
   284    366   
   285    367   # If INSTALLDIR set to tcl installation root dir then reset to the
   286    368   # lib dir for installing extensions 
   287    369   !if exist("$(_INSTALLDIR)\include\tcl.h")
   288    370   _INSTALLDIR=$(_INSTALLDIR)\lib
   289    371   !endif
   290    372   
................................................................................
   326    408   VCVER=0
   327    409   !if ![echo VCVERSION=_MSC_VER > vercl.x] \
   328    410       && ![echo $(_HASH)if defined(_M_IX86) >> vercl.x] \
   329    411       && ![echo ARCH=IX86 >> vercl.x] \
   330    412       && ![echo $(_HASH)elif defined(_M_AMD64) >> vercl.x] \
   331    413       && ![echo ARCH=AMD64 >> vercl.x] \
   332    414       && ![echo $(_HASH)endif >> vercl.x] \
   333         -    && ![$(cc32) -nologo -TC -P vercl.x $(ERRNULL)]
          415  +    && ![$(cc32) -nologo -TC -P vercl.x 2>NUL]
   334    416   !include vercl.i
   335    417   !if $(VCVERSION) < 1900
   336    418   !if ![echo VCVER= ^\> vercl.vc] \
   337    419       && ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc]
   338    420   !include vercl.vc
   339    421   !endif
   340    422   !else
   341    423   # The simple calculation above does not apply to new Visual Studio releases
   342    424   # Keep the compiler version in its native form.
   343    425   VCVER = $(VCVERSION)
   344    426   !endif
   345    427   !endif
   346    428   
   347         -!if ![del $(ERRNUL) /q/f vercl.x vercl.i vercl.vc]
          429  +!if ![del 2>NUL /q/f vercl.x vercl.i vercl.vc]
   348    430   !endif
   349    431   
   350    432   #----------------------------------------------------------------
   351    433   # The MACHINE macro is used by legacy makefiles so set it as well
   352    434   !ifdef MACHINE
   353    435   !if "$(MACHINE)" == "x86"
   354    436   !undef MACHINE
................................................................................
   521    603   
   522    604   # LINKER_TESTFLAGS are for internal use when we call nmakehlp to test
   523    605   # if the linker supports a specific option. Without these flags link will
   524    606   # return "LNK1561: entry point must be defined" error compiling from VS-IDE:
   525    607   # They are not passed through to the actual application / extension
   526    608   # link rules.
   527    609   !ifndef LINKER_TESTFLAGS
   528         -LINKER_TESTFLAGS = /DLL /NOENTRY /OUT:nmhlp-out.txt
          610  +LINKER_TESTFLAGS = /DLL /NOENTRY /OUT:nmakehlp.out
   529    611   !endif
   530    612   
   531    613   LINKERFLAGS     =
   532    614   
   533    615   # If compiler has enabled link time optimization, linker must too with -ltcg
   534    616   !ifdef CC_GL_OPT_ENABLED
   535    617   !if [nmakehlp -l -ltcg $(LINKER_TESTFLAGS)]
................................................................................
   548    630   # DEBUG - 1 -> debug build, 0 -> release builds
   549    631   # SYMBOLS - 1 -> generate PDB's, 0 -> no PDB's
   550    632   # PROFILE - 1 -> generate profiling info, 0 -> no profiling
   551    633   # PGO     - 1 -> profile based optimization, 0 -> no
   552    634   # MSVCRT  - 1 -> link to dynamic C runtime even when building static Tcl build
   553    635   #           0 -> link to static C runtime for static Tcl build.
   554    636   #           Does not impact shared Tcl builds (STATIC_BUILD == 0)
   555         -# LOIMPACT - 1 -> Ask Windows loader to aggressively trim the working set.
   556         -#           Will reduce physical memory use at cost of performance.
   557    637   # TCL_USE_STATIC_PACKAGES - 1 -> statically link the registry and dde extensions
   558    638   #           in the Tcl shell. 0 -> keep them as shared libraries
   559    639   #           Does not impact shared Tcl builds.
   560    640   # USE_THREAD_ALLOC - 1 -> Use a shared global free pool for allocation.
   561    641   #           0 -> Use the non-thread allocator.
   562    642   # UNCHECKED - 1 -> when doing a debug build with symbols, use the release
   563    643   #           C runtime, 0 -> use the debug C runtime.
................................................................................
   570    650   STATIC_BUILD	= 0
   571    651   TCL_THREADS	= 1
   572    652   DEBUG		= 0
   573    653   SYMBOLS		= 0
   574    654   PROFILE		= 0
   575    655   PGO		= 0
   576    656   MSVCRT		= 1
   577         -LOIMPACT	= 0
   578    657   TCL_USE_STATIC_PACKAGES	= 0
   579    658   USE_THREAD_ALLOC = 1
   580    659   UNCHECKED	= 0
   581    660   CONFIG_CHECK    = 1
   582    661   !if $(DOING_TCL)
   583    662   USE_STUBS       = 0
   584    663   !else
................................................................................
   621    700   !message *** Doing staticpkg
   622    701   TCL_USE_STATIC_PACKAGES	= 1
   623    702   !else
   624    703   TCL_USE_STATIC_PACKAGES	= 0
   625    704   !endif
   626    705   
   627    706   !if [nmakehlp -f $(OPTS) "nothreads"]
   628         -!error Option "nothreads" no longer supported. Threads required for sockets, registry and dde to work.
          707  +!message *** Compile explicitly for non-threaded tcl
          708  +TCL_THREADS	= 0
          709  +USE_THREAD_ALLOC= 0
          710  +!else
          711  +TCL_THREADS	= 1
          712  +USE_THREAD_ALLOC= 1
   629    713   !endif
   630    714   
   631    715   !if [nmakehlp -f $(OPTS) "symbols"]
   632    716   !message *** Doing symbols
   633    717   DEBUG		= 1
   634    718   !else
   635    719   DEBUG		= 0
................................................................................
   656    740   !message *** Doing profile guided optimization
   657    741   PGO		= 2
   658    742   !else
   659    743   PGO		= 0
   660    744   !endif
   661    745   
   662    746   !if [nmakehlp -f $(OPTS) "loimpact"]
   663         -!message *** Doing loimpact
   664         -LOIMPACT	= 1
   665         -!else
   666         -LOIMPACT	= 0
          747  +!message *** Warning: ignoring option "loimpact" - deprecated on modern Windows.
   667    748   !endif
   668    749   
   669    750   # TBD - should get rid of this option
   670    751   !if [nmakehlp -f $(OPTS) "thrdalloc"]
   671    752   !message *** Doing thrdalloc
   672    753   USE_THREAD_ALLOC = 1
   673    754   !endif
   674    755   
   675         -# TBD - should get rid of this option
   676    756   !if [nmakehlp -f $(OPTS) "tclalloc"]
   677         -!message *** Doing tclalloc
   678    757   USE_THREAD_ALLOC = 0
   679    758   !endif
   680    759   
   681    760   !if [nmakehlp -f $(OPTS) "unchecked"]
   682    761   !message *** Doing unchecked
   683    762   UNCHECKED = 1
   684    763   !else
................................................................................
   774    853   WARNINGS		    = $(WARNINGS) -Wp64
   775    854   !endif
   776    855   
   777    856   !endif
   778    857   
   779    858   ################################################################
   780    859   # 9. Extract various version numbers
   781         -# For Tcl and Tk, version numbers are exctracted from tcl.h and tk.h
          860  +# For Tcl and Tk, version numbers are extracted from tcl.h and tk.h
   782    861   # respectively. For extensions, versions are extracted from the
   783    862   # configure.in or configure.ac from the TEA configuration if it
   784    863   # exists, and unset otherwise.
   785    864   # Sets the following macros:
   786    865   # TCL_MAJOR_VERSION
   787    866   # TCL_MINOR_VERSION
   788    867   # TCL_PATCH_LEVEL
................................................................................
   841    920   
   842    921   !else # Doing a non-Tk extension
   843    922   
   844    923   # If parent makefile has not defined DOTVERSION, try to get it from TEA
   845    924   # first from a configure.in file, and then from configure.ac
   846    925   !ifndef DOTVERSION
   847    926   !if [echo DOTVERSION = \> versions.vc] \
   848         -   || [nmakehlp -V $(ROOT)\configure.in AC_INIT >> versions.vc]
          927  +   || [nmakehlp -V $(ROOT)\configure.in ^[$(PROJECT)^] >> versions.vc]
   849    928   !if [echo DOTVERSION = \> versions.vc] \
   850         -   || [nmakehlp -V $(ROOT)\configure.ac AC_INIT >> versions.vc]
          929  +   || [nmakehlp -V $(ROOT)\configure.ac ^[$(PROJECT)^] >> versions.vc]
   851    930   !error *** Could not figure out extension version. Please define DOTVERSION in parent makefile before including rules.vc.
   852    931   !endif
   853    932   !endif
   854    933   !include versions.vc
   855    934   !endif # DOTVERSION
   856    935   VERSION         = $(DOTVERSION:.=)
   857    936   
................................................................................
   933   1012   OUT_DIR	    = .\$(BUILDDIRTOP)
   934   1013   !endif
   935   1014   !else
   936   1015   !ifndef OUT_DIR
   937   1016   OUT_DIR	    = $(TMP_DIR)
   938   1017   !endif
   939   1018   !endif
         1019  +
         1020  +# Relative paths -> absolute
         1021  +!if [echo OUT_DIR = \> nmakehlp.out] \
         1022  +   || [nmakehlp -Q "$(OUT_DIR)" >> nmakehlp.out]
         1023  +!error *** Could not fully qualify path OUT_DIR=$(OUT_DIR)
         1024  +!endif
         1025  +!if [echo TMP_DIR = \>> nmakehlp.out] \
         1026  +   || [nmakehlp -Q "$(TMP_DIR)" >> nmakehlp.out]
         1027  +!error *** Could not fully qualify path TMP_DIR=$(TMP_DIR)
         1028  +!endif
         1029  +!include nmakehlp.out
   940   1030   
   941   1031   # The name of the stubs library for the project being built
   942   1032   STUBPREFIX      = $(PROJECT)stub
   943   1033   
   944   1034   # Set up paths to various Tcl executables and libraries needed by extensions
   945   1035   !if $(DOING_TCL)
   946   1036   
................................................................................
   997   1087   TCLSH_NATIVE	= $(TCLSH)
   998   1088   !else
   999   1089   !error You must explicitly set TCLSH_NATIVE for cross-compilation
  1000   1090   !endif
  1001   1091   !endif
  1002   1092   
  1003   1093   # Do the same for Tk and Tk extensions that require the Tk libraries
  1004         -!if $(DOING_TK) || $(PROJECT_REQUIRES_TK)
         1094  +!if $(DOING_TK) || $(NEED_TK)
  1005   1095   WISHNAMEPREFIX = wish
  1006   1096   WISHNAME = $(WISHNAMEPREFIX)$(TK_VERSION)$(SUFX).exe
  1007   1097   TKLIBNAME	= $(PROJECT)$(TK_VERSION)$(SUFX).$(EXT)
  1008   1098   TKSTUBLIBNAME	= tkstub$(TK_VERSION).lib
  1009   1099   TKIMPLIBNAME	= tk$(TK_VERSION)$(SUFX).lib
  1010   1100   
  1011   1101   !if $(DOING_TK)
  1012   1102   WISH 		= $(OUT_DIR)\$(WISHNAME)
  1013   1103   TKSTUBLIB	= $(OUT_DIR)\$(TKSTUBLIBNAME)
  1014   1104   TKIMPLIB	= $(OUT_DIR)\$(TKIMPLIBNAME)
  1015   1105   TKLIB		= $(OUT_DIR)\$(TKLIBNAME)
  1016   1106   TK_INCLUDES    = -I"$(WINDIR)" -I"$(GENERICDIR)"
  1017   1107   
  1018         -!else # effectively PROJECT_REQUIRES_TK
         1108  +!else # effectively NEED_TK
  1019   1109   
  1020   1110   !if $(TKINSTALL) # Building against installed Tk
  1021   1111   WISH		= $(_TKDIR)\bin\$(WISHNAME)
  1022   1112   TKSTUBLIB	= $(_TKDIR)\lib\$(TKSTUBLIBNAME)
  1023   1113   TKIMPLIB	= $(_TKDIR)\lib\$(TKIMPLIBNAME)
  1024   1114   TK_INCLUDES     = -I"$(_TKDIR)\include"
  1025   1115   !else # Building against Tk sources
  1026   1116   WISH		= $(_TKDIR)\win\$(BUILDDIRTOP)\$(WISHNAME)
  1027   1117   TKSTUBLIB	= $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSTUBLIBNAME)
  1028   1118   TKIMPLIB	= $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
  1029   1119   TK_INCLUDES     = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
  1030   1120   !endif # TKINSTALL
         1121  +tklibs = "$(TKSTUBLIB)" "$(TKIMPLIB)"
  1031   1122   
  1032   1123   !endif # $(DOING_TK)
  1033         -!endif # $(DOING_TK) || $(PROJECT_REQUIRES_TK)
         1124  +!endif # $(DOING_TK) || $(NEED_TK)
  1034   1125   
  1035   1126   # Various output paths
  1036   1127   PRJIMPLIB	= $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
  1037   1128   PRJLIBNAME	= $(PROJECT)$(VERSION)$(SUFX).$(EXT)
  1038   1129   PRJLIB		= $(OUT_DIR)\$(PRJLIBNAME)
  1039   1130   
  1040   1131   PRJSTUBLIBNAME	= $(STUBPREFIX)$(VERSION).lib
  1041   1132   PRJSTUBLIB	= $(OUT_DIR)\$(PRJSTUBLIBNAME)
  1042   1133   
  1043   1134   # If extension parent makefile has not defined a resource definition file,
  1044   1135   # we will generate one from standard template.
  1045   1136   !if !$(DOING_TCL) && !$(DOING_TK) && !$(STATIC_BUILD)
  1046   1137   !ifdef RCFILE
  1047         -RESFILE = $(RCFILE:.rc=.res)
         1138  +RESFILE = $(TMP_DIR)\$(RCFILE:.rc=.res)
  1048   1139   !else
  1049   1140   RESFILE = $(TMP_DIR)\$(PROJECT).res
  1050   1141   !endif
  1051   1142   !endif
  1052   1143   
  1053   1144   ###################################################################
  1054   1145   # 11. Construct the paths for the installation directories
................................................................................
  1128   1219   !endif
  1129   1220   
  1130   1221   !if $(USE_STUBS)
  1131   1222   # Note we do not define USE_TCL_STUBS even when building tk since some
  1132   1223   # test targets in tk do not use stubs
  1133   1224   !if ! $(DOING_TCL)
  1134   1225   USE_STUBS_DEFS  = -DUSE_TCL_STUBS -DUSE_TCLOO_STUBS
  1135         -!if $(PROJECT_REQUIRES_TK)
         1226  +!if $(NEED_TK)
  1136   1227   USE_STUBS_DEFS  = $(USE_STUBS_DEFS) -DUSE_TK_STUBS
  1137   1228   !endif
  1138   1229   !endif
  1139   1230   !endif # USE_STUBS
  1140   1231   
  1141   1232   !if !$(DEBUG)
  1142   1233   OPTDEFINES	= $(OPTDEFINES) -DNDEBUG
................................................................................
  1171   1262   !endif
  1172   1263   
  1173   1264   !if $(USE_WIDECHAR_API)
  1174   1265   COMPILERFLAGS = $(COMPILERFLAGS) /DUNICODE /D_UNICODE 
  1175   1266   !endif
  1176   1267   
  1177   1268   # Like the TEA system only set this non empty for non-Tk extensions
         1269  +# Note: some extensions use PACKAGE_NAME and others use PACKAGE_TCLNAME
         1270  +# so we pass both
  1178   1271   !if !$(DOING_TCL) && !$(DOING_TK)
  1179         -PKGNAMEFLAGS = -DPACKAGE_NAME="\"$(PROJECT)\"" \
         1272  +PKGNAMEFLAGS = -DPACKAGE_NAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
         1273  +               -DPACKAGE_TCLNAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
  1180   1274                  -DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
  1181   1275                  -DMODULE_SCOPE=extern 
  1182   1276   !endif
  1183   1277   
  1184   1278   # crt picks the C run time based on selected OPTS
  1185   1279   !if $(MSVCRT)
  1186   1280   !if $(DEBUG) && !$(UNCHECKED)
................................................................................
  1218   1312   # Disable pointer<->int warnings related to cast between different sizes
  1219   1313   # There are a gadzillion of these due to use of ClientData and
  1220   1314   # clutter up compiler
  1221   1315   # output increasing chance of a real warning getting lost. So disable them.
  1222   1316   # Eventually some day, Tcl will be 64-bit clean.
  1223   1317   cwarn = $(cwarn) -wd4311 -wd4312
  1224   1318   !endif
         1319  +
         1320  +### Common compiler options that are architecture specific
         1321  +!if "$(MACHINE)" == "ARM"
         1322  +carch = -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
         1323  +!else
         1324  +carch =
         1325  +!endif
  1225   1326   
  1226   1327   !if $(DEBUG)
  1227   1328   # Turn warnings into errors
  1228   1329   cwarn = $(cwarn) -WX
  1229   1330   !endif
         1331  +
         1332  +INCLUDES = $(TCL_INCLUDES) $(TK_INCLUDES) $(PRJ_INCLUDES)
         1333  +!if !$(DOING_TCL) && !$(DOING_TK)
         1334  +INCLUDES = $(INCLUDES) -I"$(GENERICDIR)" -I"$(WINDIR)" -I"$(COMPATDIR)"
         1335  +!endif
  1230   1336   
  1231   1337   # These flags are defined roughly in the order of the pre-reform
  1232   1338   # rules.vc/makefile.vc to help visually compare that the pre- and
  1233   1339   # post-reform build logs
  1234   1340   
  1235   1341   # cflags contains generic flags used for building practically all object files
  1236         -cflags = -nologo -c $(COMPILERFLAGS) $(cwarn) -Fp$(TMP_DIR)^\ $(cdebug)
         1342  +cflags = -nologo -c $(COMPILERFLAGS) $(carch) $(cwarn) -Fp$(TMP_DIR)^\ $(cdebug)
  1237   1343   
  1238   1344   # appcflags contains $(cflags) and flags for building the application
  1239   1345   # object files (e.g. tclsh, or wish) pkgcflags contains $(cflags) plus
  1240   1346   # flags used for building shared object files The two differ in the
  1241   1347   # BUILD_$(PROJECT) macro which should be defined only for the shared
  1242   1348   # library *implementation* and not for its caller interface
  1243   1349   
  1244         -appcflags = $(cflags) $(crt) $(TCL_INCLUDES) $(TK_INCLUDES) $(PRJ_INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES) $(USE_STUBS_DEFS)
  1245         -appcflags_nostubs = $(cflags) $(crt) $(TCL_INCLUDES) $(TK_INCLUDES) $(PRJ_INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES)
         1350  +appcflags = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES) $(USE_STUBS_DEFS)
         1351  +appcflags_nostubs = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES)
  1246   1352   pkgcflags = $(appcflags) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
  1247   1353   pkgcflags_nostubs = $(appcflags_nostubs) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
  1248   1354   
  1249   1355   # stubscflags contains $(cflags) plus flags used for building a stubs
  1250   1356   # library for the package.  Note: -DSTATIC_BUILD is defined in
  1251   1357   # $(OPTDEFINES) only if the OPTS configuration indicates a static
  1252   1358   # library. However the stubs library is ALWAYS static hence included
  1253   1359   # here irrespective of the OPTS setting.
  1254         -
  1255         -stubscflags = $(cflags) $(PRJ_DEFINES) $(OPTDEFINES) -Zl -DSTATIC_BUILD $(TCL_INCLUDES) $(TK_INCLUDES) $(PRJ_INCLUDES)
         1360  +#
         1361  +# TBD - tclvfs has a comment that stubs libs should not be compiled with -GL
         1362  +# without stating why. Tcl itself compiled stubs libs with this flag.
         1363  +# so we do not remove it from cflags. -GL may prevent extensions
         1364  +# compiled with one VC version to fail to link against stubs library
         1365  +# compiled with another VC version. Check for this and fix accordingly.
         1366  +stubscflags = $(cflags) $(PKGNAMEFLAGS) $(PRJ_DEFINES) $(OPTDEFINES) -Zl -DSTATIC_BUILD $(INCLUDES)
  1256   1367   
  1257   1368   # Link flags 
  1258   1369   
  1259   1370   !if $(DEBUG)
  1260   1371   ldebug	= -debug -debugtype:cv
  1261   1372   !else
  1262   1373   ldebug	= -release -opt:ref -opt:icf,3
................................................................................
  1285   1396   !if "$(MACHINE)" == "IX86" && !$(STATIC_BUILD)
  1286   1397   !if [nmakehlp -l -opt:nowin98 $(LINKER_TESTFLAGS)]
  1287   1398   # Align sections for PE size savings.
  1288   1399   lflags	= $(lflags) -opt:nowin98
  1289   1400   !endif
  1290   1401   !endif
  1291   1402   
  1292         -!if $(LOIMPACT)
  1293         -lflags	= $(lflags) -ws:aggressive
  1294         -!endif
  1295         -
  1296   1403   dlllflags = $(lflags) -dll
  1297   1404   conlflags = $(lflags) -subsystem:console
  1298   1405   guilflags = $(lflags) -subsystem:windows
  1299   1406   
  1300   1407   # Libraries that are required for every image.
  1301   1408   # Extensions should define any additional libraries with $(PRJ_LIBS)
  1302   1409   winlibs   = kernel32.lib advapi32.lib
         1410  +
         1411  +!if $(NEED_TK)
         1412  +winlibs = $(winlibs) gdi32.lib user32.lib uxtheme.lib
         1413  +!endif
  1303   1414   
  1304   1415   # Avoid 'unresolved external symbol __security_cookie' errors.
  1305   1416   # c.f. http://support.microsoft.com/?id=894573
  1306   1417   !if "$(MACHINE)" == "AMD64"
  1307   1418   !if $(VCVERSION) > 1399 && $(VCVERSION) < 1500
  1308   1419   winlibs   = $(winlibs) bufferoverflowU.lib
  1309   1420   !endif
................................................................................
  1312   1423   baselibs = $(winlibs) $(PRJ_LIBS)
  1313   1424   
  1314   1425   !if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
  1315   1426   baselibs   = $(baselibs) ucrt.lib
  1316   1427   !endif
  1317   1428   
  1318   1429   ################################################################
  1319         -# 3. Define standard commands, common make targets and implicit rules
         1430  +# 13. Define standard commands, common make targets and implicit rules
  1320   1431   
  1321         -MAKELIBCMD = $(lib32) -nologo $(LINKERFLAGS) -out:$@
  1322         -MAKEDLLCMD = $(link32) $(dlllflags) -out:$@ $(baselibs) $(tcllibs) 
         1432  +CCPKGCMD = $(cc32) $(pkgcflags) -Fo$(TMP_DIR)^\
         1433  +CCAPPCMD = $(cc32) $(appcflags) -Fo$(TMP_DIR)^\
         1434  +CCSTUBSCMD = $(cc32) $(stubscflags) -Fo$(TMP_DIR)^\
  1323   1435   
  1324         -!if $(STATIC_BUILD)
  1325         -MAKEBINCMD = $(MAKELIBCMD)
  1326         -!else
  1327         -MAKEBINCMD = $(MAKEDLLCMD)
  1328         -!endif
  1329         -MAKECONCMD = $(link32) $(conlflags) -out:$@ $(baselibs) $(tcllibs)
  1330         -MAKEGUICMD = $(link32) $(guilflags) -out:$@ $(baselibs) $(tcllibs)
  1331         -MAKERESCMD  = $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" \
         1436  +LIBCMD = $(lib32) -nologo $(LINKERFLAGS) -out:$@
         1437  +DLLCMD = $(link32) $(dlllflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
         1438  +
         1439  +CONEXECMD = $(link32) $(conlflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
         1440  +GUIEXECMD = $(link32) $(guilflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
         1441  +RESCMD  = $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" \
  1332   1442   	    $(TCL_INCLUDES) \
  1333   1443   	    -DDEBUG=$(DEBUG) -d UNCHECKED=$(UNCHECKED) \
  1334   1444   	    -DCOMMAVERSION=$(DOTVERSION:.=,),0 \
  1335   1445   	    -DDOTVERSION=\"$(DOTVERSION)\" \
  1336   1446   	    -DVERSION=\"$(VERSION)\" \
  1337   1447   	    -DSUFX=\"$(SUFX)\" \
  1338   1448               -DPROJECT=\"$(PROJECT)\" \
................................................................................
  1341   1451   !ifndef DEFAULT_BUILD_TARGET
  1342   1452   DEFAULT_BUILD_TARGET = $(PROJECT)
  1343   1453   !endif
  1344   1454   
  1345   1455   default-target: $(DEFAULT_BUILD_TARGET)
  1346   1456   
  1347   1457   default-pkgindex:
  1348         -	@echo package ifneeded $(PROJECT) $(DOTVERSION) \
  1349         -	    [list load [file join $$dir $(PRJLIBNAME)]] >> $(OUT_DIR)\pkgIndex.tcl
         1458  +	@echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
         1459  +	    [list load [file join $$dir $(PRJLIBNAME)]] > $(OUT_DIR)\pkgIndex.tcl
  1350   1460   
  1351   1461   default-pkgindex-tea:
  1352   1462   	@if exist $(ROOT)\pkgIndex.tcl.in nmakehlp -s << $(ROOT)\pkgIndex.tcl.in > $(OUT_DIR)\pkgIndex.tcl
  1353   1463   @PACKAGE_VERSION@    $(DOTVERSION)
  1354         -@PACKAGE_NAME@       $(PROJECT)
         1464  +@PACKAGE_NAME@       $(PRJ_PACKAGE_TCLNAME)
         1465  +@PACKAGE_TCLNAME@    $(PRJ_PACKAGE_TCLNAME)
  1355   1466   @PKG_LIB_FILE@       $(PRJLIBNAME)
  1356   1467   <<
  1357   1468   
  1358   1469   
  1359   1470   default-install: default-install-binaries default-install-libraries
  1360   1471   
  1361   1472   default-install-binaries: $(PRJLIB)
................................................................................
  1365   1476   
  1366   1477   default-install-libraries: $(OUT_DIR)\pkgIndex.tcl
  1367   1478   	@echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
  1368   1479   	@if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)"
  1369   1480   	@echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
  1370   1481   	@$(CPY) $(OUT_DIR)\pkgIndex.tcl $(SCRIPT_INSTALL_DIR)
  1371   1482   
         1483  +default-install-stubs:
         1484  +	@echo Installing stubs library to '$(SCRIPT_INSTALL_DIR)'
         1485  +	@if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
         1486  +	@$(CPY) $(PRJSTUBLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
         1487  +
         1488  +default-install-docs-html:
         1489  +	@echo Installing documentation files to '$(DOC_INSTALL_DIR)'
         1490  +	@if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
         1491  +	@if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.html" "$(DOCDIR)\*.css" "$(DOCDIR)\*.png") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
         1492  +
         1493  +default-install-docs-n:
         1494  +	@echo Installing documentation files to '$(DOC_INSTALL_DIR)'
         1495  +	@if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
         1496  +	@if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.n") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
         1497  +
         1498  +default-install-demos:
         1499  +	@echo Installing demos to '$(DEMO_INSTALL_DIR)'
         1500  +	@if not exist "$(DEMO_INSTALL_DIR)" mkdir "$(DEMO_INSTALL_DIR)"
         1501  +	@if exist $(DEMODIR) $(CPYDIR) "$(DEMODIR)" "$(DEMO_INSTALL_DIR)"
         1502  +
  1372   1503   default-clean:
  1373   1504   	@echo Cleaning $(TMP_DIR)\* ...
  1374   1505   	@if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
  1375   1506   	@echo Cleaning $(WINDIR)\nmakehlp.obj, nmakehlp.exe ...
  1376   1507   	@if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
  1377   1508   	@if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
         1509  +	@if exist $(WINDIR)\nmakehlp.out del $(WINDIR)\nmakehlp.out
         1510  +	@echo Cleaning $(WINDIR)\nmhlp-out.txt ...
         1511  +	@if exist $(WINDIR)\nmhlp-out.txt del $(WINDIR)\nmhlp-out.txt
  1378   1512   	@echo Cleaning $(WINDIR)\_junk.pch ...
  1379   1513   	@if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch
  1380   1514   	@echo Cleaning $(WINDIR)\vercl.x, vercl.i ...
  1381   1515   	@if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
  1382   1516   	@if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
  1383   1517   	@echo Cleaning $(WINDIR)\versions.vc, version.vc ...
  1384   1518   	@if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc
................................................................................
  1392   1526   	@if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
  1393   1527   	@if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
  1394   1528   
  1395   1529   default-setup:
  1396   1530   	@if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
  1397   1531   	@if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
  1398   1532   
  1399         -!ifndef RCFILE
         1533  +!if "$(TESTPAT)" != ""
         1534  +TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
         1535  +!endif
         1536  +
         1537  +default-test: default-setup $(PROJECT)
         1538  +	@set TCLLIBPATH=$(OUT_DIR:\=/)
         1539  +	@if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
         1540  +	cd "$(TESTDIR)" && $(DEBUGGER) $(TCLSH) all.tcl $(TESTFLAGS)
         1541  +
         1542  +default-shell: default-setup $(PROJECT)
         1543  +	@set TCLLIBPATH=$(OUT_DIR:\=/)
         1544  +	@if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
         1545  +	$(DEBUGGER) $(TCLSH)
         1546  +
         1547  +# Generation of Windows version resource 
         1548  +!ifdef RCFILE
         1549  +
         1550  +# Note: don't use $** in below rule because there may be other dependencies
         1551  +# and only the "master" rc must be passed to the resource compiler
         1552  +$(TMP_DIR)\$(PROJECT).res: $(RCDIR)\$(PROJECT).rc
         1553  +	$(RESCMD) $(RCDIR)\$(PROJECT).rc
         1554  +
         1555  +!else
         1556  +
  1400   1557   # If parent makefile has not defined a resource definition file,
  1401   1558   # we will generate one from standard template.
  1402   1559   $(TMP_DIR)\$(PROJECT).res: $(TMP_DIR)\$(PROJECT).rc
  1403   1560   
  1404   1561   $(TMP_DIR)\$(PROJECT).rc:
  1405   1562   	@$(COPY) << $(TMP_DIR)\$(PROJECT).rc
  1406   1563   #include <winver.h>
................................................................................
  1433   1590       BEGIN
  1434   1591           VALUE "Translation", 0x409, 1200
  1435   1592       END
  1436   1593   END
  1437   1594   
  1438   1595   <<
  1439   1596   
  1440         -!endif # ifndef RCFILE
         1597  +!endif # ifdef RCFILE
  1441   1598   
  1442   1599   !ifndef DISABLE_IMPLICIT_RULES
  1443   1600   DISABLE_IMPLICIT_RULES = 0
  1444   1601   !endif
  1445   1602   
  1446   1603   !if !$(DISABLE_IMPLICIT_RULES)
  1447   1604   # Implicit rule definitions - only for building library objects. For stubs and
  1448   1605   # main application, the master makefile should define explicit rules.
         1606  +
         1607  +{$(ROOT)}.c{$(TMP_DIR)}.obj::
         1608  +	$(CCPKGCMD) @<<
         1609  +$<
         1610  +<<
  1449   1611   
  1450   1612   {$(WINDIR)}.c{$(TMP_DIR)}.obj::
  1451         -	$(cc32) $(pkgcflags) -Fo$(TMP_DIR)\ @<<
         1613  +	$(CCPKGCMD) @<<
  1452   1614   $<
  1453   1615   <<
  1454   1616   
  1455   1617   {$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
  1456         -	$(cc32) $(pkgcflags) -Fo$(TMP_DIR)\ @<<
         1618  +	$(CCPKGCMD) @<<
  1457   1619   $<
  1458   1620   <<
  1459   1621   
  1460   1622   {$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
  1461         -	$(cc32) $(pkgcflags) -Fo$(TMP_DIR)\ @<<
         1623  +	$(CCPKGCMD) @<<
  1462   1624   $<
  1463   1625   <<
  1464   1626   
  1465   1627   {$(RCDIR)}.rc{$(TMP_DIR)}.res:
  1466         -	$(MAKERESCMD) $<
         1628  +	$(RESCMD) $<
  1467   1629   
  1468   1630   {$(WINDIR)}.rc{$(TMP_DIR)}.res:
  1469         -	$(MAKERESCMD) $<
         1631  +	$(RESCMD) $<
  1470   1632   
  1471   1633   {$(TMP_DIR)}.rc{$(TMP_DIR)}.res:
  1472         -	$(MAKERESCMD) $<
         1634  +	$(RESCMD) $<
  1473   1635   
  1474   1636   .SUFFIXES:
  1475   1637   .SUFFIXES:.c .rc
  1476   1638   
  1477   1639   !endif
  1478   1640   
  1479   1641   ################################################################

Changes to win/targets.vc.

     1      1   #------------------------------------------------------------- -*- makefile -*-
            2  +# targets.vc --
            3  +#
            4  +# Part of the nmake based build system for Tcl and its extensions.
            5  +# This file defines some standard targets for the convenience of extensions
            6  +# and can be optionally included by the extension makefile.
            7  +# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for docs.
     2      8   
     3      9   $(PROJECT): setup pkgindex $(PRJLIB)
           10  +
           11  +!ifdef PRJ_STUBOBJS
           12  +$(PROJECT): $(PRJSTUBLIB)
           13  +$(PRJSTUBLIB): $(PRJ_STUBOBJS)
           14  +	$(LIBCMD) $**
           15  +
           16  +$(PRJ_STUBOBJS):
           17  +	$(CCSTUBSCMD) %s
           18  +!endif # PRJ_STUBOBJS
           19  +
           20  +!ifdef PRJ_MANIFEST
           21  +$(PROJECT): $(PRJLIB).manifest
           22  +$(PRJLIB).manifest: $(PRJ_MANIFEST)
           23  +	@nmakehlp -s << $** >$@
           24  +@MACHINE@	  $(MACHINE:IX86=X86)
           25  +<<
           26  +!endif
     4     27   
     5     28   !if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk"
     6         -# MAKEBINCMD will do shared, static and debug links as appropriate
     7         -# _VC_MANIFEST_EMBED_DLL embeds the manifest for shared libraries
     8         -# and is a no-op for static libraries
     9     29   $(PRJLIB): $(PRJ_OBJS) $(RESFILE)
    10         -       $(MAKEBINCMD) $**
           30  +!if $(STATIC_BUILD)
           31  +       $(LIBCMD) $**
           32  +!else
           33  +       $(DLLCMD) $**
    11     34          $(_VC_MANIFEST_EMBED_DLL)
           35  +!endif
    12     36          -@del $*.exp
    13     37   !endif
    14     38   
           39  +!ifndef DISABLE_STANDARD_TARGETS
           40  +DISABLE_STANDARD_TARGETS = 0
           41  +!endif
           42  +
           43  +!if !$(DISABLE_STANDARD_TARGETS)
    15     44   setup: default-setup
    16     45   install: default-install
    17     46   clean: default-clean
    18     47   realclean: hose
    19     48   hose: default-hose
    20     49   distclean: realclean default-distclean
    21         -
           50  +test: default-test
           51  +shell: default-shell
           52  +!endif