Tcl Extension Architecture (TEA) Sample Extension

Check-in [15a1576b19]
Login
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to [email protected]
or submit via the online form by Sep 9.

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

Overview
Comment:Updated to nmake rules 1.1
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 15a1576b19ee49e077f9dc6c4f5d453e124ad8365f8df73ecb4a6b48662ae7b3
User & Date: apnadkarni 2017-12-27 04:24:20
Context
2018-01-04
04:06
Update to latest TEA. check-in: 13e7233e84 user: stu tags: trunk
2017-12-27
04:24
Updated to nmake rules 1.1 check-in: 15a1576b19 user: apnadkarni tags: trunk
2017-12-22
14:12
convert all win/*.vc files to crlf style check-in: c0e7395994 user: jan.nijtmans tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to win/nmakehlp.c.

    35     35   
    36     36   /* ISO hack for dumb VC++ */
    37     37   #ifdef _MSC_VER
    38     38   #define   snprintf	_snprintf
    39     39   #endif
    40     40   
    41     41   
    42         -
    43     42   /* protos */
    44     43   
    45     44   static int CheckForCompilerFeature(const char *option);
    46     45   static int CheckForLinkerFeature(const char **options, int count);
    47     46   static int IsIn(const char *string, const char *substring);
    48     47   static int SubstituteFile(const char *substs, const char *filename);
    49     48   static int QualifyPath(const char *path);
           49  +static int LocateDependency(const char *keyfile);
    50     50   static const char *GetVersionFromFile(const char *filename, const char *match, int numdots);
    51     51   static DWORD WINAPI ReadFromPipe(LPVOID args);
    52     52   
    53     53   /* globals */
    54     54   
    55     55   #define CHUNK	25
    56     56   #define STATICBUFFERSIZE    1000
................................................................................
   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,
   171    171   		    &dwWritten, NULL);
   172    172   		return 2;
   173    173   	    }
   174    174   	    return QualifyPath(argv[2]);
          175  +
          176  +	case 'L':
          177  +	    if (argc != 3) {
          178  +		chars = snprintf(msg, sizeof(msg) - 1,
          179  +		    "usage: %s -L keypath\n"
          180  +		    "Emit the fully qualified path of directory containing keypath\n"
          181  +		    "exitcodes: 0 == success, 1 == not found, 2 == error\n", argv[0]);
          182  +		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
          183  +		    &dwWritten, NULL);
          184  +		return 2;
          185  +	    }
          186  +	    return LocateDependency(argv[2]);
   175    187   	}
   176    188       }
   177    189       chars = snprintf(msg, sizeof(msg) - 1,
   178    190   	    "usage: %s -c|-f|-l|-Q|-s|-V ...\n"
   179    191   	    "This is a little helper app to equalize shell differences between WinNT and\n"
   180    192   	    "Win9x and get nmake.exe to accomplish its job.\n",
   181    193   	    argv[0]);
................................................................................
   695    707       while ((p = strchr(szPath, '/')) && *p)
   696    708   	*p = '\\';
   697    709       PathCombine(szTmp, szCwd, szPath);
   698    710       PathCanonicalize(szCwd, szTmp);
   699    711       printf("%s\n", szCwd);
   700    712       return 0;
   701    713   }
          714  +
          715  +/*
          716  + * Implements LocateDependency for a single directory. See that command
          717  + * for an explanation.
          718  + * Returns 0 if found after printing the directory.
          719  + * Returns 1 if not found but no errors.
          720  + * Returns 2 on any kind of error
          721  + * Basically, these are used as exit codes for the process.
          722  + */
          723  +static int LocateDependencyHelper(const char *dir, const char *keypath)
          724  +{
          725  +    HANDLE hSearch;
          726  +    char path[MAX_PATH+1];
          727  +    int dirlen, keylen, ret;
          728  +    WIN32_FIND_DATA finfo;
          729  +
          730  +    if (dir == NULL || keypath == NULL)
          731  +	return 2; /* Have no real error reporting mechanism into nmake */
          732  +    dirlen = strlen(dir);
          733  +    if ((dirlen + 3) > sizeof(path))
          734  +	return 2;
          735  +    strncpy(path, dir, dirlen);
          736  +    strncpy(path+dirlen, "\\*", 3);	/* Including terminating \0 */
          737  +    keylen = strlen(keypath);
          738  +
          739  +#if 0 /* This function is not available in Visual C++ 6 */
          740  +    /*
          741  +     * Use numerics 0 -> FindExInfoStandard,
          742  +     * 1 -> FindExSearchLimitToDirectories, 
          743  +     * as these are not defined in Visual C++ 6
          744  +     */
          745  +    hSearch = FindFirstFileEx(path, 0, &finfo, 1, NULL, 0);
          746  +#else
          747  +    hSearch = FindFirstFile(path, &finfo);
          748  +#endif
          749  +    if (hSearch == INVALID_HANDLE_VALUE)
          750  +	return 1; /* Not found */
          751  +
          752  +    /* Loop through all subdirs checking if the keypath is under there */
          753  +    ret = 1; /* Assume not found */
          754  +    do {
          755  +	int sublen;
          756  +	/*
          757  +	 * We need to check it is a directory despite the 
          758  +	 * FindExSearchLimitToDirectories in the above call. See SDK docs
          759  +	 */
          760  +	if ((finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
          761  +	    continue;
          762  +	sublen = strlen(finfo.cFileName);
          763  +	if ((dirlen+1+sublen+1+keylen+1) > sizeof(path))
          764  +	    continue;		/* Path does not fit, assume not matched */
          765  +	strncpy(path+dirlen+1, finfo.cFileName, sublen);
          766  +	path[dirlen+1+sublen] = '\\';
          767  +	strncpy(path+dirlen+1+sublen+1, keypath, keylen+1);
          768  +	if (PathFileExists(path)) {
          769  +	    /* Found a match, print to stdout */
          770  +	    path[dirlen+1+sublen] = '\0';
          771  +	    QualifyPath(path);
          772  +	    ret = 0;
          773  +	    break;
          774  +	}
          775  +    } while (FindNextFile(hSearch, &finfo));
          776  +    FindClose(hSearch);
          777  +    return ret;
          778  +}
          779  +
          780  +/*
          781  + * LocateDependency --
          782  + *
          783  + *	Locates a dependency for a package.
          784  + *        keypath - a relative path within the package directory
          785  + *          that is used to confirm it is the correct directory.
          786  + *	The search path for the package directory is currently only
          787  + *      the parent and grandparent of the current working directory.
          788  + *      If found, the command prints 
          789  + *         name_DIRPATH=<full path of located directory>
          790  + *      and returns 0. If not found, does not print anything and returns 1.
          791  + */
          792  +static int LocateDependency(const char *keypath)
          793  +{
          794  +    int i, ret;
          795  +    static char *paths[] = {"..", "..\\..", "..\\..\\.."};
          796  +    
          797  +    for (i = 0; i < (sizeof(paths)/sizeof(paths[0])); ++i) {
          798  +	ret = LocateDependencyHelper(paths[i], keypath);
          799  +	if (ret == 0)
          800  +	    return ret;
          801  +    }
          802  +    return ret;
          803  +}
          804  +
   702    805   
   703    806   /*
   704    807    * Local variables:
   705    808    *   mode: c
   706    809    *   c-basic-offset: 4
   707    810    *   fill-column: 78
   708    811    *   indent-tabs-mode: t
   709    812    *   tab-width: 8
   710    813    * End:
   711    814    */

Changes to win/rules-ext.vc.

    23     23   macro to the name of the project makefile.
    24     24   !message WARNING: $(MSG)
    25     25   !endif
    26     26   
    27     27   !if "$(PROJECT)" == "tcl"
    28     28   !error The rules-ext.vc file is not intended for Tcl itself.
    29     29   !endif
           30  +
           31  +# We extract version numbers using the nmakehlp program. For now use
           32  +# the local copy of nmakehlp. Once we locate Tcl, we will use that
           33  +# one if it is newer.
           34  +!if [$(CC) -nologo "nmakehlp.c" -link -subsystem:console > nul]
           35  +!endif
    30     36   
    31     37   # First locate the Tcl directory that we are working with.
    32         -!ifdef TCLDIR
           38  +!if "$(TCLDIR)" != ""
    33     39   
    34     40   _RULESDIR = $(TCLDIR:/=\)
    35     41   
    36     42   !else
    37     43   
    38     44   # If an installation path is specified, that is also the Tcl directory.
    39         -# Also, tk never builds against an installed Tcl, it needs Tcl sources
           45  +# Also Tk never builds against an installed Tcl, it needs Tcl sources
    40     46   !if defined(INSTALLDIR) && "$(PROJECT)" != "tk"
    41     47   _RULESDIR=$(INSTALLDIR:/=\)
    42     48   !else
           49  +# Locate Tcl sources
           50  +!if [echo _RULESDIR = \> nmakehlp.out] \
           51  +   || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
    43     52   _RULESDIR = ..\..\tcl
           53  +!else
           54  +!include nmakehlp.out
    44     55   !endif
           56  +
           57  +!endif # defined(INSTALLDIR)....
    45     58   
    46     59   !endif # ifndef TCLDIR
    47     60   
    48     61   # Now look for the targets.vc file under the Tcl root. Note we check this
    49     62   # file and not rules.vc because the latter also exists on older systems.
    50     63   !if exist("$(_RULESDIR)\lib\nmake\targets.vc") # Building against installed Tcl
    51     64   _RULESDIR = $(_RULESDIR)\lib\nmake
................................................................................
    59     72   
    60     73   !if "$(_RULESDIR)" != "."
    61     74   # Potentially using Tcl's support files. If this extension has its own
    62     75   # nmake support files, need to compare the versions and pick newer.
    63     76   
    64     77   !if exist("rules.vc") # The extension has its own copy
    65     78   
    66         -# We extract version numbers using the nmakehlp program.
    67         -!if [$(CC) -nologo "$(_RULESDIR)\nmakehlp.c" -link -subsystem:console > nul]
    68         -!endif
    69         -
    70     79   !if [echo TCL_RULES_MAJOR = \> versions.vc] \
    71     80      && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MAJOR >> versions.vc]
    72     81   !endif
    73     82   !if [echo TCL_RULES_MINOR = \>> versions.vc] \
    74     83      && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MINOR >> versions.vc]
    75     84   !endif
    76     85   

Changes to win/rules.vc.

    20     20   !ifndef _RULES_VC
    21     21   _RULES_VC = 1
    22     22   
    23     23   # The following macros define the version of the rules.vc nmake build system
    24     24   # For modifications that are not backward-compatible, you *must* change
    25     25   # the major version.
    26     26   RULES_VERSION_MAJOR = 1
    27         -RULES_VERSION_MINOR = 0
           27  +RULES_VERSION_MINOR = 1
    28     28   
    29     29   # The PROJECT macro must be defined by parent makefile.
    30     30   !if "$(PROJECT)" == ""
    31     31   !error *** Error: Macro PROJECT not defined! Please define it before including rules.vc
    32     32   !endif
    33     33   
    34     34   !if "$(PRJ_PACKAGE_TCLNAME)" == ""
................................................................................
   252    252   
   253    253   !elseif $(DOING_TK)
   254    254   
   255    255   # BEGIN Case 2(b) - Building Tk
   256    256   
   257    257   TCLINSTALL = 0 # Tk always builds against Tcl source, not an installed Tcl
   258    258   !if "$(TCLDIR)" == ""
   259         -TCLDIR  = ../../tcl
          259  +!if [echo TCLDIR = \> nmakehlp.out] \
          260  +   || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
          261  +!error *** Could not locate Tcl source directory.
   260    262   !endif
          263  +!include nmakehlp.out
          264  +!endif # TCLDIR == ""
          265  +
   261    266   _TCLDIR	= $(TCLDIR:/=\)
   262    267   _TCL_H  = $(_TCLDIR)\generic\tcl.h
   263    268   !if !exist("$(_TCL_H)")
   264    269   !error Could not locate tcl.h. Please set the TCLDIR macro to point to the Tcl *source* directory.
   265    270   !endif
   266    271   
   267    272   _TK_H = ..\generic\tk.h
................................................................................
   281    286   TCLINSTALL	= 1
   282    287   _TCL_H          = $(_TCLDIR)\include\tcl.h
   283    288   !elseif exist("$(_TCLDIR)\generic\tcl.h") # Case 2(d) with TCLDIR defined
   284    289   TCLINSTALL	= 0
   285    290   _TCL_H          = $(_TCLDIR)\generic\tcl.h
   286    291   !endif
   287    292   
   288         -!else  # TCLDIR is not defined
          293  +!else  #  # Case 2(c) for extensions with TCLDIR undefined
   289    294   
   290         -!if exist("$(_INSTALLDIR)\include\tcl.h") # Case 2(c) for extensions with TCLDIR undefined
          295  +# Need to locate Tcl depending on whether it needs Tcl source or not.
          296  +# If we don't, check the INSTALLDIR for an installed Tcl first
          297  +
          298  +!if exist("$(_INSTALLDIR)\include\tcl.h") && !$(NEED_TCL_SOURCE)
          299  +
   291    300   TCLINSTALL	= 1
   292    301   TCLDIR          = $(_INSTALLDIR)\..
   293    302   # NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
   294    303   # later so the \.. accounts for the /lib
   295    304   _TCLDIR		= $(_INSTALLDIR)\..
   296    305   _TCL_H          = $(_TCLDIR)\include\tcl.h
   297         -!elseif exist("..\..\tcl\generic\tcl.h")
          306  +
          307  +!else # exist(...) && ! $(NEED_TCL_SOURCE)
          308  +
          309  +!if [echo _TCLDIR = \> nmakehlp.out] \
          310  +   || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
          311  +!error *** Could not locate Tcl source directory.
          312  +!endif
          313  +!include nmakehlp.out
   298    314   TCLINSTALL      = 0
   299         -TCLDIR          = ..\..\tcl
   300         -_TCLDIR         = $(TCLDIR)
          315  +TCLDIR         = $(_TCLDIR)
   301    316   _TCL_H          = $(_TCLDIR)\generic\tcl.h
   302         -!endif
          317  +
          318  +!endif # exist(...) && ! $(NEED_TCL_SOURCE)
   303    319   
   304    320   !endif # TCLDIR
   305    321   
   306    322   !ifndef _TCL_H
   307    323   MSG =^
   308    324   Failed to find tcl.h. The TCLDIR macro is set incorrectly or is not set and default path does not contain tcl.h.
   309    325   !error $(MSG)
................................................................................
   321    337   !elseif exist("$(_TKDIR)\generic\tk.h")
   322    338   TKINSTALL      = 0
   323    339   _TK_H          = $(_TKDIR)\generic\tk.h
   324    340   !endif
   325    341   
   326    342   !else # TKDIR not defined
   327    343   
   328         -!if exist("$(_INSTALLDIR)\..\include\tk.h")
          344  +# Need to locate Tcl depending on whether it needs Tcl source or not.
          345  +# If we don't, check the INSTALLDIR for an installed Tcl first
          346  +
          347  +!if exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
          348  +
   329    349   TKINSTALL      = 1
          350  +# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
          351  +# later so the \.. accounts for the /lib
   330    352   _TKDIR         = $(_INSTALLDIR)\..
   331    353   _TK_H          = $(_TKDIR)\include\tk.h
   332    354   TKDIR          = $(_TKDIR)
   333         -!elseif exist("$(_TCLDIR)\include\tk.h")
   334         -TKINSTALL      = 1
   335         -_TKDIR         = $(_TCLDIR)
   336         -_TK_H          = $(_TKDIR)\include\tk.h
          355  +
          356  +!else # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
          357  +
          358  +!if [echo _TKDIR = \> nmakehlp.out] \
          359  +   || [nmakehlp -L generic\tk.h >> nmakehlp.out]
          360  +!error *** Could not locate Tk source directory.
          361  +!endif
          362  +!include nmakehlp.out
          363  +TKINSTALL      = 0
   337    364   TKDIR          = $(_TKDIR)
   338         -!endif
          365  +_TK_H          = $(_TKDIR)\generic\tk.h
          366  +
          367  +!endif # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
   339    368   
   340    369   !endif # TKDIR
   341    370   
   342    371   !ifndef _TK_H
   343    372   MSG =^
   344    373   Failed to find tk.h. The TKDIR macro is set incorrectly or is not set and default path does not contain tk.h.
   345    374   !error $(MSG)
................................................................................
   502    531   !endif # $(TCLINSTALL)
   503    532   !endif # !$(DOING_TCL)
   504    533   
   505    534   !endif # NMAKEHLPC
   506    535   
   507    536   # We always build nmakehlp even if it exists since we do not know
   508    537   # what source it was built from.
   509         -!message *** Using $(NMAKEHLPC)
   510    538   !if [$(cc32) -nologo "$(NMAKEHLPC)" -link -subsystem:console > nul]
   511    539   !endif
   512    540   
   513    541   ################################################################
   514    542   # 5. Test for compiler features
   515    543   # Visual C++ compiler options have changed over the years. Check
   516    544   # which options are supported by the compiler in use.
................................................................................
   557    585   # /O2 documentation is misleading as its stack probes are simply the
   558    586   # default page size locals allocation probes and not what is implied
   559    587   # by an explicit /Gs option.
   560    588   
   561    589   OPTIMIZATIONS = $(FPOPTS)
   562    590   
   563    591   !if [nmakehlp -c -O2]
   564         -!message *** Compiler has 'Optimizations'
   565    592   OPTIMIZING = 1
   566    593   OPTIMIZATIONS   = $(OPTIMIZATIONS) -O2
   567    594   !else
   568    595   # Legacy, really. All modern compilers support this
   569    596   !message *** Compiler does not have 'Optimizations'
   570    597   OPTIMIZING = 0
   571    598   !endif
................................................................................
  1044   1071   TCLSTUBLIB	= $(OUT_DIR)\$(TCLSTUBLIBNAME)
  1045   1072   TCL_INCLUDES    = -I"$(WINDIR)" -I"$(GENERICDIR)"
  1046   1073   
  1047   1074   !else # ! $(DOING_TCL)
  1048   1075   
  1049   1076   !if $(TCLINSTALL) # Building against an installed Tcl
  1050   1077   
         1078  +# When building extensions, we need to locate tclsh. Depending on version
         1079  +# of Tcl we are building against, this may or may not have a "t" suffix.
         1080  +# Try various possibilities in turn.
  1051   1081   TCLSH		= $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe
  1052   1082   !if !exist("$(TCLSH)") && $(TCL_THREADS)
  1053   1083   TCLSH           = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe
  1054   1084   !endif
         1085  +!if !exist("$(TCLSH)")
         1086  +TCLSH           = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX:t=).exe
         1087  +!endif
         1088  +
  1055   1089   TCLSTUBLIB	= $(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib
  1056   1090   TCLIMPLIB	= $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib
         1091  +# When building extensions, may be linking against Tcl that does not add
         1092  +# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
         1093  +!if !exist("$(TCLIMPLIB)")
         1094  +TCLIMPLIB	= $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX:t=).lib
         1095  +!endif
  1057   1096   TCL_LIBRARY	= $(_TCLDIR)\lib
  1058   1097   TCLREGLIB	= $(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib
  1059   1098   TCLDDELIB	= $(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib
  1060   1099   TCLTOOLSDIR	= \must\have\tcl\sources\to\build\this\target
  1061   1100   TCL_INCLUDES    = -I"$(_TCLDIR)\include"
  1062   1101   
  1063   1102   !else # Building against Tcl sources
  1064   1103   
  1065   1104   TCLSH		= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe
  1066   1105   !if !exist($(TCLSH)) && $(TCL_THREADS)
  1067   1106   TCLSH		= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe
  1068   1107   !endif
         1108  +!if !exist($(TCLSH))
         1109  +TCLSH		= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX:t=).exe
         1110  +!endif
  1069   1111   TCLSTUBLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib
  1070   1112   TCLIMPLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib
         1113  +# When building extensions, may be linking against Tcl that does not add
         1114  +# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
         1115  +!if !exist("$(TCLIMPLIB)")
         1116  +TCLIMPLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX:t=).lib
         1117  +!endif
  1071   1118   TCL_LIBRARY	= $(_TCLDIR)\library
  1072   1119   TCLREGLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib
  1073   1120   TCLDDELIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib
  1074   1121   TCLTOOLSDIR	= $(_TCLDIR)\tools
  1075   1122   TCL_INCLUDES	= -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
  1076   1123   
  1077   1124   !endif # TCLINSTALL
................................................................................
  1107   1154   
  1108   1155   !else # effectively NEED_TK
  1109   1156   
  1110   1157   !if $(TKINSTALL) # Building against installed Tk
  1111   1158   WISH		= $(_TKDIR)\bin\$(WISHNAME)
  1112   1159   TKSTUBLIB	= $(_TKDIR)\lib\$(TKSTUBLIBNAME)
  1113   1160   TKIMPLIB	= $(_TKDIR)\lib\$(TKIMPLIBNAME)
         1161  +# When building extensions, may be linking against Tk that does not add
         1162  +# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
         1163  +!if !exist("$(TKIMPLIB)")
         1164  +TKIMPLIBNAME	= tk$(TK_VERSION)$(SUFX:t=).lib
         1165  +TKIMPLIB	= $(_TKDIR)\lib\$(TKIMPLIBNAME)
         1166  +!endif
  1114   1167   TK_INCLUDES     = -I"$(_TKDIR)\include"
  1115   1168   !else # Building against Tk sources
  1116   1169   WISH		= $(_TKDIR)\win\$(BUILDDIRTOP)\$(WISHNAME)
  1117   1170   TKSTUBLIB	= $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSTUBLIBNAME)
  1118   1171   TKIMPLIB	= $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
         1172  +# When building extensions, may be linking against Tk that does not add
         1173  +# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
         1174  +!if !exist("$(TKIMPLIB)")
         1175  +TKIMPLIBNAME	= tk$(TK_VERSION)$(SUFX:t=).lib
         1176  +TKIMPLIB	= $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
         1177  +!endif
  1119   1178   TK_INCLUDES     = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
  1120   1179   !endif # TKINSTALL
  1121   1180   tklibs = "$(TKSTUBLIB)" "$(TKIMPLIB)"
  1122   1181   
  1123   1182   !endif # $(DOING_TK)
  1124   1183   !endif # $(DOING_TK) || $(NEED_TK)
  1125   1184   
................................................................................
  1514   1573   	@echo Cleaning $(WINDIR)\vercl.x, vercl.i ...
  1515   1574   	@if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
  1516   1575   	@if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
  1517   1576   	@echo Cleaning $(WINDIR)\versions.vc, version.vc ...
  1518   1577   	@if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc
  1519   1578   	@if exist $(WINDIR)\version.vc del $(WINDIR)\version.vc
  1520   1579   
  1521         -default-hose:
         1580  +default-hose: default-clean
  1522   1581   	@echo Hosing $(OUT_DIR)\* ...
  1523   1582   	@if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
  1524   1583   
         1584  +# Only for backward compatibility
  1525   1585   default-distclean: default-hose
  1526         -	@if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
  1527         -	@if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
  1528   1586   
  1529   1587   default-setup:
  1530   1588   	@if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
  1531   1589   	@if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
  1532   1590   
  1533   1591   !if "$(TESTPAT)" != ""
  1534   1592   TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
................................................................................
  1675   1733   !endif # ! $(DOING_TCL)
  1676   1734   
  1677   1735   
  1678   1736   #----------------------------------------------------------
  1679   1737   # Display stats being used.
  1680   1738   #----------------------------------------------------------
  1681   1739   
         1740  +!if !$(DOING_TCL)
         1741  +!message *** Building against Tcl at '$(_TCLDIR)'
         1742  +!endif
         1743  +!if !$(DOING_TK) && $(NEED_TK)
         1744  +!message *** Building against Tk at '$(_TKDIR)'
         1745  +!endif
  1682   1746   !message *** Intermediate directory will be '$(TMP_DIR)'
  1683   1747   !message *** Output directory will be '$(OUT_DIR)'
         1748  +!message *** Installation, if selected, will be in '$(_INSTALLDIR)'
  1684   1749   !message *** Suffix for binaries will be '$(SUFX)'
  1685         -!message *** Optional defines are '$(OPTDEFINES)'
  1686         -!message *** Compiler version $(VCVER). Target machine is $(MACHINE)
  1687         -!message *** Host architecture is $(NATIVE_ARCH)
         1750  +!message *** Compiler version $(VCVER). Target $(MACHINE), host $(NATIVE_ARCH).
  1688   1751   
  1689   1752   !endif # ifdef _RULES_VC

Changes to win/targets.vc.

    32     32   !else
    33     33          $(DLLCMD) $**
    34     34          $(_VC_MANIFEST_EMBED_DLL)
    35     35   !endif
    36     36          [email protected] $*.exp
    37     37   !endif
    38     38   
    39         -!ifndef DISABLE_STANDARD_TARGETS
           39  +!if "$(PRJ_HEADERS)" != "" && "$(PRJ_OBJS)" != ""
           40  +$(PRJ_OBJS): $(PRJ_HEADERS)
           41  +!endif
           42  +
           43  +# If parent makefile has defined stub objects, add their installation
           44  +# to the default install
           45  +!if "$(PRJ_STUBOBJS)" != ""
           46  +default-install: default-install-stubs
           47  +!endif
           48  +
           49  +# Unlike the other default targets, these cannot be in rules.vc because
           50  +# the executed command depends on existence of macro PRJ_HEADERS_PUBLIC
           51  +# that the parent makefile will not define until after including rules-ext.vc
           52  +!if "$(PRJ_HEADERS_PUBLIC)" != ""
           53  +default-install: default-install-headers
           54  +default-install-headers:
           55  +	@echo Installing headers to '$(INCLUDE_INSTALL_DIR)'
           56  +	@for %f in ($(PRJ_HEADERS_PUBLIC)) do @$(COPY) %f "$(INCLUDE_INSTALL_DIR)"
           57  +!endif
           58  +
           59  +!if "$(DISABLE_STANDARD_TARGETS)" == ""
    40     60   DISABLE_STANDARD_TARGETS = 0
    41     61   !endif
           62  +
           63  +!if "$(DISABLE_TARGET_setup)" == ""
           64  +DISABLE_TARGET_setup = 0
           65  +!endif
           66  +!if "$(DISABLE_TARGET_install)" == ""
           67  +DISABLE_TARGET_install = 0
           68  +!endif
           69  +!if "$(DISABLE_TARGET_clean)" == ""
           70  +DISABLE_TARGET_clean = 0
           71  +!endif
           72  +!if "$(DISABLE_TARGET_test)" == ""
           73  +DISABLE_TARGET_test = 0
           74  +!endif
           75  +!if "$(DISABLE_TARGET_shell)" == ""
           76  +DISABLE_TARGET_shell = 0
           77  +!endif
    42     78   
    43     79   !if !$(DISABLE_STANDARD_TARGETS)
           80  +!if !$(DISABLE_TARGET_setup)
    44     81   setup: default-setup
           82  +!endif
           83  +!if !$(DISABLE_TARGET_install)
    45     84   install: default-install
           85  +!endif
           86  +!if !$(DISABLE_TARGET_clean)
    46     87   clean: default-clean
    47     88   realclean: hose
    48     89   hose: default-hose
    49     90   distclean: realclean default-distclean
           91  +!endif
           92  +!if !$(DISABLE_TARGET_test)
    50     93   test: default-test
           94  +!endif
           95  +!if !$(DISABLE_TARGET_shell)
    51     96   shell: default-shell
    52     97   !endif
           98  +!endif # DISABLE_STANDARD_TARGETS