1#------------------------------------------------------------- -*- makefile -*- 2# rules.vc -- 3# 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-lang.org/tips/doc/main/tip/477.md) for 10# detailed documentation. 11# 12# See the file "license.terms" for information on usage and redistribution 13# of this file, and for a DISCLAIMER OF ALL WARRANTIES. 14# 15# Copyright (c) 2001-2003 David Gravereaux. 16# Copyright (c) 2003-2008 Patrick Thoyts 17# Copyright (c) 2017 Ashok P. Nadkarni 18#------------------------------------------------------------------------------ 19 20!ifndef _RULES_VC 21_RULES_VC = 1 22 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. 26RULES_VERSION_MAJOR = 1 27RULES_VERSION_MINOR = 9 28 29# The PROJECT macro must be defined by parent makefile. 30!if "$(PROJECT)" == "" 31!error *** Error: Macro PROJECT not defined! Please define it before including rules.vc 32!endif 33 34!if "$(PRJ_PACKAGE_TCLNAME)" == "" 35PRJ_PACKAGE_TCLNAME = $(PROJECT) 36!endif 37 38# Also special case Tcl and Tk to save some typing later 39DOING_TCL = 0 40DOING_TK = 0 41!if "$(PROJECT)" == "tcl" 42DOING_TCL = 1 43!elseif "$(PROJECT)" == "tk" 44DOING_TK = 1 45!endif 46 47!ifndef NEED_TK 48# Backwards compatibility 49!ifdef PROJECT_REQUIRES_TK 50NEED_TK = $(PROJECT_REQUIRES_TK) 51!else 52NEED_TK = 0 53!endif 54!endif 55 56!ifndef NEED_TCL_SOURCE 57NEED_TCL_SOURCE = 0 58!endif 59 60!ifdef NEED_TK_SOURCE 61!if $(NEED_TK_SOURCE) 62NEED_TK = 1 63!endif 64!else 65NEED_TK_SOURCE = 0 66!endif 67 68################################################################ 69# Nmake is a pretty weak environment in syntax and capabilities 70# so this file is necessarily verbose. It's broken down into 71# the following parts. 72# 73# 0. Sanity check that compiler environment is set up and initialize 74# any built-in settings from the parent makefile 75# 1. First define the external tools used for compiling, copying etc. 76# as this is independent of everything else. 77# 2. Figure out our build structure in terms of the directory, whether 78# we are building Tcl or an extension, etc. 79# 3. Determine the compiler and linker versions 80# 4. Build the nmakehlp helper application 81# 5. Determine the supported compiler options and features 82# 6. Parse the OPTS macro value for user-specified build configuration 83# 7. Parse the STATS macro value for statistics instrumentation 84# 8. Parse the CHECKS macro for additional compilation checks 85# 9. Extract Tcl, and possibly Tk, version numbers from the headers 86# 10. Based on this selected configuration, construct the output 87# directory and file paths 88# 11. Construct the paths where the package is to be installed 89# 12. Set up the actual options passed to compiler and linker based 90# on the information gathered above. 91# 13. Define some standard build targets and implicit rules. These may 92# be optionally disabled by the parent makefile. 93# 14. (For extensions only.) Compare the configuration of the target 94# Tcl and the extensions and warn against discrepancies. 95# 96# One final note about the macro names used. They are as they are 97# for historical reasons. We would like legacy extensions to 98# continue to work with this make include file so be wary of 99# changing them for consistency or clarity. 100 101# 0. Sanity check compiler environment 102 103# Check to see we are configured to build with MSVC (MSDEVDIR, MSVCDIR or 104# VCINSTALLDIR) or with the MS Platform SDK (MSSDK or WindowsSDKDir) 105 106!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(VCINSTALLDIR) && !defined(MSSDK) && !defined(WINDOWSSDKDIR) 107MSG = ^ 108Visual C++ compiler environment not initialized. 109!error $(MSG) 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") 119MAKEFILEVC = $(PROJECT).vc 120!elseif exist("makefile.vc") 121MAKEFILEVC = makefile.vc 122!endif 123!endif # "$(MAKEFILEVC)" == "" 124 125!if !exist("$(MAKEFILEVC)") 126MSG = ^ 127You must run nmake from the directory containing the project makefile.^ 128If you are doing that and getting this message, set the MAKEFILEVC^ 129macro to the name of the project makefile. 130!message WARNING: $(MSG) 131!endif 132 133 134################################################################ 135# 1. Define external programs being used 136 137#---------------------------------------------------------- 138# Set the proper copy method to avoid overwrite questions 139# to the user when copying files and selecting the right 140# "delete all" method. 141#---------------------------------------------------------- 142 143RMDIR = rmdir /S /Q 144CPY = xcopy /i /y >NUL 145CPYDIR = xcopy /e /i /y >NUL 146COPY = copy /y >NUL 147MKDIR = mkdir 148 149###################################################################### 150# 2. Figure out our build environment in terms of what we're building. 151# 152# (a) Tcl itself 153# (b) Tk 154# (c) a Tcl extension using libraries/includes from an *installed* Tcl 155# (d) a Tcl extension using libraries/includes from Tcl source directory 156# 157# This last is needed because some extensions still need 158# some Tcl interfaces that are not publicly exposed. 159# 160# The fragment will set the following macros: 161# ROOT - root of this module sources 162# COMPATDIR - source directory that holds compatibility sources 163# DOCDIR - source directory containing documentation files 164# GENERICDIR - platform-independent source directory 165# WIN_DIR - Windows-specific source directory 166# TESTDIR - directory containing test files 167# TOOLSDIR - directory containing build tools 168# _TCLDIR - root of the Tcl installation OR the Tcl sources. Not set 169# when building Tcl itself. 170# _INSTALLDIR - native form of the installation path. For Tcl 171# this will be the root of the Tcl installation. For extensions 172# this will be the lib directory under the root. 173# TCLINSTALL - set to 1 if _TCLDIR refers to 174# headers and libraries from an installed Tcl, and 0 if built against 175# Tcl sources. Not set when building Tcl itself. Yes, not very well 176# named. 177# _TCL_H - native path to the tcl.h file 178# 179# If Tk is involved, also sets the following 180# _TKDIR - native form Tk installation OR Tk source. Not set if building 181# Tk itself. 182# TKINSTALL - set 1 if _TKDIR refers to installed Tk and 0 if Tk sources 183# _TK_H - native path to the tk.h file 184 185# Root directory for sources and assumed subdirectories 186ROOT = $(MAKEDIR)\.. 187# The following paths CANNOT have spaces in them as they appear on the 188# left side of implicit rules. 189!ifndef COMPATDIR 190COMPATDIR = $(ROOT)\compat 191!endif 192!ifndef DOCDIR 193DOCDIR = $(ROOT)\doc 194!endif 195!ifndef GENERICDIR 196GENERICDIR = $(ROOT)\generic 197!endif 198!ifndef TOOLSDIR 199TOOLSDIR = $(ROOT)\tools 200!endif 201!ifndef TESTDIR 202TESTDIR = $(ROOT)\tests 203!endif 204!ifndef LIBDIR 205!if exist("$(ROOT)\library") 206LIBDIR = $(ROOT)\library 207!else 208LIBDIR = $(ROOT)\lib 209!endif 210!endif 211!ifndef DEMODIR 212!if exist("$(LIBDIR)\demos") 213DEMODIR = $(LIBDIR)\demos 214!else 215DEMODIR = $(ROOT)\demos 216!endif 217!endif # ifndef DEMODIR 218# Do NOT use WINDIR because it is Windows internal environment 219# variable to point to c:\windows! 220WIN_DIR = $(ROOT)\win 221 222!ifndef RCDIR 223!if exist("$(WIN_DIR)\rc") 224RCDIR = $(WIN_DIR)\rc 225!else 226RCDIR = $(WIN_DIR) 227!endif 228!endif 229RCDIR = $(RCDIR:/=\) 230 231# The target directory where the built packages and binaries will be installed. 232# INSTALLDIR is the (optional) path specified by the user. 233# _INSTALLDIR is INSTALLDIR using the backslash separator syntax 234!ifdef INSTALLDIR 235### Fix the path separators. 236_INSTALLDIR = $(INSTALLDIR:/=\) 237!else 238### Assume the normal default. 239_INSTALLDIR = $(HOMEDRIVE)\Tcl 240!endif 241 242!if $(DOING_TCL) 243 244# BEGIN Case 2(a) - Building Tcl itself 245 246# Only need to define _TCL_H 247_TCL_H = ..\generic\tcl.h 248 249# END Case 2(a) - Building Tcl itself 250 251!elseif $(DOING_TK) 252 253# BEGIN Case 2(b) - Building Tk 254 255TCLINSTALL = 0 # Tk always builds against Tcl source, not an installed Tcl 256!if "$(TCLDIR)" == "" 257!if [echo TCLDIR = \> nmakehlp.out] \ 258 || [nmakehlp -L generic\tcl.h >> nmakehlp.out] 259!error *** Could not locate Tcl source directory. 260!endif 261!include nmakehlp.out 262!endif # TCLDIR == "" 263 264_TCLDIR = $(TCLDIR:/=\) 265_TCL_H = $(_TCLDIR)\generic\tcl.h 266!if !exist("$(_TCL_H)") 267!error Could not locate tcl.h. Please set the TCLDIR macro to point to the Tcl *source* directory. 268!endif 269 270_TK_H = ..\generic\tk.h 271 272# END Case 2(b) - Building Tk 273 274!else 275 276# BEGIN Case 2(c) or (d) - Building an extension other than Tk 277 278# If command line has specified Tcl location through TCLDIR, use it 279# else default to the INSTALLDIR setting 280!if "$(TCLDIR)" != "" 281 282_TCLDIR = $(TCLDIR:/=\) 283!if exist("$(_TCLDIR)\include\tcl.h") # Case 2(c) with TCLDIR defined 284TCLINSTALL = 1 285_TCL_H = $(_TCLDIR)\include\tcl.h 286!elseif exist("$(_TCLDIR)\generic\tcl.h") # Case 2(d) with TCLDIR defined 287TCLINSTALL = 0 288_TCL_H = $(_TCLDIR)\generic\tcl.h 289!endif 290 291!else # # Case 2(c) for extensions with TCLDIR undefined 292 293# Need to locate Tcl depending on whether it needs Tcl source or not. 294# If we don't, check the INSTALLDIR for an installed Tcl first 295 296!if exist("$(_INSTALLDIR)\include\tcl.h") && !$(NEED_TCL_SOURCE) 297 298TCLINSTALL = 1 299TCLDIR = $(_INSTALLDIR)\.. 300# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions 301# later so the \.. accounts for the /lib 302_TCLDIR = $(_INSTALLDIR)\.. 303_TCL_H = $(_TCLDIR)\include\tcl.h 304 305!else # exist(...) && !$(NEED_TCL_SOURCE) 306 307!if [echo _TCLDIR = \> nmakehlp.out] \ 308 || [nmakehlp -L generic\tcl.h >> nmakehlp.out] 309!error *** Could not locate Tcl source directory. 310!endif 311!include nmakehlp.out 312TCLINSTALL = 0 313TCLDIR = $(_TCLDIR) 314_TCL_H = $(_TCLDIR)\generic\tcl.h 315 316!endif # exist(...) && !$(NEED_TCL_SOURCE) 317 318!endif # TCLDIR 319 320!ifndef _TCL_H 321MSG =^ 322Failed to find tcl.h. The TCLDIR macro is set incorrectly or is not set and default path does not contain tcl.h. 323!error $(MSG) 324!endif 325 326# Now do the same to locate Tk headers and libs if project requires Tk 327!if $(NEED_TK) 328 329!if "$(TKDIR)" != "" 330 331_TKDIR = $(TKDIR:/=\) 332!if exist("$(_TKDIR)\include\tk.h") 333TKINSTALL = 1 334_TK_H = $(_TKDIR)\include\tk.h 335!elseif exist("$(_TKDIR)\generic\tk.h") 336TKINSTALL = 0 337_TK_H = $(_TKDIR)\generic\tk.h 338!endif 339 340!else # TKDIR not defined 341 342# Need to locate Tcl depending on whether it needs Tcl source or not. 343# If we don't, check the INSTALLDIR for an installed Tcl first 344 345!if exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE) 346 347TKINSTALL = 1 348# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions 349# later so the \.. accounts for the /lib 350_TKDIR = $(_INSTALLDIR)\.. 351_TK_H = $(_TKDIR)\include\tk.h 352TKDIR = $(_TKDIR) 353 354!else # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE) 355 356!if [echo _TKDIR = \> nmakehlp.out] \ 357 || [nmakehlp -L generic\tk.h >> nmakehlp.out] 358!error *** Could not locate Tk source directory. 359!endif 360!include nmakehlp.out 361TKINSTALL = 0 362TKDIR = $(_TKDIR) 363_TK_H = $(_TKDIR)\generic\tk.h 364 365!endif # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE) 366 367!endif # TKDIR 368 369!ifndef _TK_H 370MSG =^ 371Failed to find tk.h. The TKDIR macro is set incorrectly or is not set and default path does not contain tk.h. 372!error $(MSG) 373!endif 374 375!endif # NEED_TK 376 377!if $(NEED_TCL_SOURCE) && $(TCLINSTALL) 378MSG = ^ 379*** Warning: This extension requires the source distribution of Tcl.^ 380*** Please set the TCLDIR macro to point to the Tcl sources. 381!error $(MSG) 382!endif 383 384!if $(NEED_TK_SOURCE) 385!if $(TKINSTALL) 386MSG = ^ 387*** Warning: This extension requires the source distribution of Tk.^ 388*** Please set the TKDIR macro to point to the Tk sources. 389!error $(MSG) 390!endif 391!endif 392 393 394# If INSTALLDIR set to Tcl installation root dir then reset to the 395# lib dir for installing extensions 396!if exist("$(_INSTALLDIR)\include\tcl.h") 397_INSTALLDIR=$(_INSTALLDIR)\lib 398!endif 399 400# END Case 2(c) or (d) - Building an extension 401!endif # if $(DOING_TCL) 402 403################################################################ 404# 3. Determine compiler version and architecture 405# In this section, we figure out the compiler version and the 406# architecture for which we are building. This sets the 407# following macros: 408# VCVERSION - the internal compiler version as 1200, 1400, 1910 etc. 409# This is also printed by the compiler in dotted form 19.10 etc. 410# VCVER - the "marketing version", for example Visual C++ 6 for internal 411# compiler version 1200. This is kept only for legacy reasons as it 412# does not make sense for recent Microsoft compilers. Only used for 413# output directory names. 414# ARCH - set to IX86 or AMD64 depending on 32- or 64-bit target 415# NATIVE_ARCH - set to IX86 or AMD64 for the host machine 416# MACHINE - same as $(ARCH) - legacy 417# _VC_MANIFEST_EMBED_{DLL,EXE} - commands for embedding a manifest if needed 418 419cc32 = $(CC) # built-in default. 420link32 = link 421lib32 = lib 422rc32 = $(RC) # built-in default. 423 424#---------------------------------------------------------------- 425# Figure out the compiler architecture and version by writing 426# the C macros to a file, preprocessing them with the C 427# preprocessor and reading back the created file 428 429_HASH=^# 430_VC_MANIFEST_EMBED_EXE= 431_VC_MANIFEST_EMBED_DLL= 432VCVER=0 433!if ![echo VCVERSION=_MSC_VER > vercl.x] \ 434 && ![echo $(_HASH)if defined(_M_IX86) >> vercl.x] \ 435 && ![echo ARCH=IX86 >> vercl.x] \ 436 && ![echo $(_HASH)elif defined(_M_AMD64) >> vercl.x] \ 437 && ![echo ARCH=AMD64 >> vercl.x] \ 438 && ![echo $(_HASH)endif >> vercl.x] \ 439 && ![$(cc32) -nologo -TC -P vercl.x 2>NUL] 440!include vercl.i 441!if $(VCVERSION) < 1900 442!if ![echo VCVER= ^\> vercl.vc] \ 443 && ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc] 444!include vercl.vc 445!endif 446!else 447# The simple calculation above does not apply to new Visual Studio releases 448# Keep the compiler version in its native form. 449VCVER = $(VCVERSION) 450!endif 451!endif 452 453!if ![del 2>NUL /q/f vercl.x vercl.i vercl.vc] 454!endif 455 456#---------------------------------------------------------------- 457# The MACHINE macro is used by legacy makefiles so set it as well 458!ifdef MACHINE 459!if "$(MACHINE)" == "x86" 460!undef MACHINE 461MACHINE = IX86 462!elseif "$(MACHINE)" == "x64" 463!undef MACHINE 464MACHINE = AMD64 465!endif 466!if "$(MACHINE)" != "$(ARCH)" 467!error Specified MACHINE macro $(MACHINE) does not match detected target architecture $(ARCH). 468!endif 469!else 470MACHINE=$(ARCH) 471!endif 472 473#--------------------------------------------------------------- 474# The PLATFORM_IDENTIFY macro matches the values returned by 475# the Tcl platform::identify command 476!if "$(MACHINE)" == "AMD64" 477PLATFORM_IDENTIFY = win32-x86_64 478!else 479PLATFORM_IDENTIFY = win32-ix86 480!endif 481 482# The MULTIPLATFORM macro controls whether binary extensions are installed 483# in platform-specific directories. Intended to be set/used by extensions. 484!ifndef MULTIPLATFORM_INSTALL 485MULTIPLATFORM_INSTALL = 0 486!endif 487 488#------------------------------------------------------------ 489# Figure out the *host* architecture by reading the registry 490 491!if ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i x86] 492NATIVE_ARCH=IX86 493!else 494NATIVE_ARCH=AMD64 495!endif 496 497# Since MSVC8 we must deal with manifest resources. 498!if $(VCVERSION) >= 1400 499_VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1 500_VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2 501!endif 502 503################################################################ 504# 4. Build the nmakehlp program 505# This is a helper app we need to overcome nmake's limiting 506# environment. We will call out to it to get various bits of 507# information about supported compiler options etc. 508# 509# Tcl itself will always use the nmakehlp.c program which is 510# in its own source. It will be kept updated there. 511# 512# Extensions built against an installed Tcl will use the installed 513# copy of Tcl's nmakehlp.c if there is one and their own version 514# otherwise. In the latter case, they would also be using their own 515# rules.vc. Note that older versions of Tcl do not install nmakehlp.c 516# or rules.vc. 517# 518# Extensions built against Tcl sources will use the one from the Tcl source. 519# 520# When building an extension using a sufficiently new version of Tcl, 521# rules-ext.vc will define NMAKEHLPC appropriately to point to the 522# copy of nmakehlp.c to be used. 523 524!ifndef NMAKEHLPC 525# Default to the one in the current directory (the extension's own nmakehlp.c) 526NMAKEHLPC = nmakehlp.c 527 528!if !$(DOING_TCL) 529!if $(TCLINSTALL) 530!if exist("$(_TCLDIR)\lib\nmake\nmakehlp.c") 531NMAKEHLPC = $(_TCLDIR)\lib\nmake\nmakehlp.c 532!endif 533!else # !$(TCLINSTALL) 534!if exist("$(_TCLDIR)\win\nmakehlp.c") 535NMAKEHLPC = $(_TCLDIR)\win\nmakehlp.c 536!endif 537!endif # $(TCLINSTALL) 538!endif # !$(DOING_TCL) 539 540!endif # NMAKEHLPC 541 542# We always build nmakehlp even if it exists since we do not know 543# what source it was built from. 544!if [$(cc32) -nologo "$(NMAKEHLPC)" -link -subsystem:console > nul] 545!endif 546 547################################################################ 548# 5. Test for compiler features 549# Visual C++ compiler options have changed over the years. Check 550# which options are supported by the compiler in use. 551# 552# The following macros are set: 553# OPTIMIZATIONS - the compiler flags to be used for optimized builds 554# DEBUGFLAGS - the compiler flags to be used for debug builds 555# LINKERFLAGS - Flags passed to the linker 556# 557# Note that these are the compiler settings *available*, not those 558# that will be *used*. The latter depends on the OPTS macro settings 559# which we have not yet parsed. 560# 561# Also note that some of the flags in OPTIMIZATIONS are not really 562# related to optimization. They are placed there only for legacy reasons 563# as some extensions expect them to be included in that macro. 564 565# -Op improves float consistency. Note only needed for older compilers 566# Newer compilers do not need or support this option. 567!if [nmakehlp -c -Op] 568FPOPTS = -Op 569!endif 570 571# Strict floating point semantics - present in newer compilers in lieu of -Op 572!if [nmakehlp -c -fp:strict] 573FPOPTS = $(FPOPTS) -fp:strict 574!endif 575 576!if "$(MACHINE)" == "IX86" 577### test for pentium errata 578!if [nmakehlp -c -QI0f] 579!message *** Compiler has 'Pentium 0x0f fix' 580FPOPTS = $(FPOPTS) -QI0f 581!else 582!message *** Compiler does not have 'Pentium 0x0f fix' 583!endif 584!endif 585 586### test for optimizations 587# /O2 optimization includes /Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy as per 588# documentation. Note we do NOT want /Gs as that inserts a _chkstk 589# stack probe at *every* function entry, not just those with more than 590# a page of stack allocation resulting in a performance hit. However, 591# /O2 documentation is misleading as its stack probes are simply the 592# default page size locals allocation probes and not what is implied 593# by an explicit /Gs option. 594 595OPTIMIZATIONS = $(FPOPTS) 596 597!if [nmakehlp -c -O2] 598OPTIMIZING = 1 599OPTIMIZATIONS = $(OPTIMIZATIONS) -O2 600!else 601# Legacy, really. All modern compilers support this 602!message *** Compiler does not have 'Optimizations' 603OPTIMIZING = 0 604!endif 605 606# Checks for buffer overflows in local arrays 607!if [nmakehlp -c -GS] 608OPTIMIZATIONS = $(OPTIMIZATIONS) -GS 609!endif 610 611# Link time optimization. Note that this option (potentially) makes 612# generated libraries only usable by the specific VC++ version that 613# created it. Requires /LTCG linker option 614!if [nmakehlp -c -GL] 615OPTIMIZATIONS = $(OPTIMIZATIONS) -GL 616CC_GL_OPT_ENABLED = 1 617!else 618# In newer compilers -GL and -YX are incompatible. 619!if [nmakehlp -c -YX] 620OPTIMIZATIONS = $(OPTIMIZATIONS) -YX 621!endif 622!endif # [nmakehlp -c -GL] 623 624DEBUGFLAGS = $(FPOPTS) 625 626# Run time error checks. Not available or valid in a release, non-debug build 627# RTC is for modern compilers, -GZ is legacy 628!if [nmakehlp -c -RTC1] 629DEBUGFLAGS = $(DEBUGFLAGS) -RTC1 630!elseif [nmakehlp -c -GZ] 631DEBUGFLAGS = $(DEBUGFLAGS) -GZ 632!endif 633 634#---------------------------------------------------------------- 635# Linker flags 636 637# LINKER_TESTFLAGS are for internal use when we call nmakehlp to test 638# if the linker supports a specific option. Without these flags link will 639# return "LNK1561: entry point must be defined" error compiling from VS-IDE: 640# They are not passed through to the actual application / extension 641# link rules. 642!ifndef LINKER_TESTFLAGS 643LINKER_TESTFLAGS = /DLL /NOENTRY /OUT:nmakehlp.out 644!endif 645 646LINKERFLAGS = 647 648# If compiler has enabled link time optimization, linker must too with -ltcg 649!ifdef CC_GL_OPT_ENABLED 650!if [nmakehlp -l -ltcg $(LINKER_TESTFLAGS)] 651LINKERFLAGS = $(LINKERFLAGS) -ltcg 652!endif 653!endif 654 655 656################################################################ 657# 6. Extract various version numbers from headers 658# For Tcl and Tk, version numbers are extracted from tcl.h and tk.h 659# respectively. For extensions, versions are extracted from the 660# configure.in or configure.ac from the TEA configuration if it 661# exists, and unset otherwise. 662# Sets the following macros: 663# TCL_MAJOR_VERSION 664# TCL_MINOR_VERSION 665# TCL_RELEASE_SERIAL 666# TCL_PATCH_LEVEL 667# TCL_PATCH_LETTER 668# TCL_VERSION 669# TK_MAJOR_VERSION 670# TK_MINOR_VERSION 671# TK_RELEASE_SERIAL 672# TK_PATCH_LEVEL 673# TK_PATCH_LETTER 674# TK_VERSION 675# DOTVERSION - set as (for example) 2.5 676# VERSION - set as (for example 25) 677#-------------------------------------------------------------- 678 679!if [echo REM = This file is generated from rules.vc > versions.vc] 680!endif 681!if [echo TCL_MAJOR_VERSION = \>> versions.vc] \ 682 && [nmakehlp -V "$(_TCL_H)" TCL_MAJOR_VERSION >> versions.vc] 683!endif 684!if [echo TCL_MINOR_VERSION = \>> versions.vc] \ 685 && [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc] 686!endif 687!if [echo TCL_RELEASE_SERIAL = \>> versions.vc] \ 688 && [nmakehlp -V "$(_TCL_H)" TCL_RELEASE_SERIAL >> versions.vc] 689!endif 690!if [echo TCL_PATCH_LEVEL = \>> versions.vc] \ 691 && [nmakehlp -V "$(_TCL_H)" TCL_PATCH_LEVEL >> versions.vc] 692!endif 693 694!if defined(_TK_H) 695!if [echo TK_MAJOR_VERSION = \>> versions.vc] \ 696 && [nmakehlp -V $(_TK_H) TK_MAJOR_VERSION >> versions.vc] 697!endif 698!if [echo TK_MINOR_VERSION = \>> versions.vc] \ 699 && [nmakehlp -V $(_TK_H) TK_MINOR_VERSION >> versions.vc] 700!endif 701!if [echo TK_RELEASE_SERIAL = \>> versions.vc] \ 702 && [nmakehlp -V "$(_TK_H)" TK_RELEASE_SERIAL >> versions.vc] 703!endif 704!if [echo TK_PATCH_LEVEL = \>> versions.vc] \ 705 && [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc] 706!endif 707!endif # _TK_H 708 709!include versions.vc 710 711TCL_VERSION = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION) 712TCL_DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION) 713!if [nmakehlp -f $(TCL_PATCH_LEVEL) "a"] 714TCL_PATCH_LETTER = a 715!elseif [nmakehlp -f $(TCL_PATCH_LEVEL) "b"] 716TCL_PATCH_LETTER = b 717!else 718TCL_PATCH_LETTER = . 719!endif 720 721!if defined(_TK_H) 722 723TK_VERSION = $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION) 724TK_DOTVERSION = $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION) 725!if [nmakehlp -f $(TK_PATCH_LEVEL) "a"] 726TK_PATCH_LETTER = a 727!elseif [nmakehlp -f $(TK_PATCH_LEVEL) "b"] 728TK_PATCH_LETTER = b 729!else 730TK_PATCH_LETTER = . 731!endif 732 733!endif 734 735# Set DOTVERSION and VERSION 736!if $(DOING_TCL) 737 738DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION) 739VERSION = $(TCL_VERSION) 740 741!elseif $(DOING_TK) 742 743DOTVERSION = $(TK_DOTVERSION) 744VERSION = $(TK_VERSION) 745 746!else # Doing a non-Tk extension 747 748# If parent makefile has not defined DOTVERSION, try to get it from TEA 749# first from a configure.in file, and then from configure.ac 750!ifndef DOTVERSION 751!if [echo DOTVERSION = \> versions.vc] \ 752 || [nmakehlp -V $(ROOT)\configure.in ^[$(PROJECT)^] >> versions.vc] 753!if [echo DOTVERSION = \> versions.vc] \ 754 || [nmakehlp -V $(ROOT)\configure.ac ^[$(PROJECT)^] >> versions.vc] 755!error *** Could not figure out extension version. Please define DOTVERSION in parent makefile before including rules.vc. 756!endif 757!endif 758!include versions.vc 759!endif # DOTVERSION 760VERSION = $(DOTVERSION:.=) 761 762!endif # $(DOING_TCL) ... etc. 763 764# Windows RC files have 3 version components. Ensure this irrespective 765# of how many components the package has specified. Basically, ensure 766# minimum 4 components by appending 4 0's and then pick out the first 4. 767# Also take care of the fact that DOTVERSION may have "a" or "b" instead 768# of "." separating the version components. 769DOTSEPARATED=$(DOTVERSION:a=.) 770DOTSEPARATED=$(DOTSEPARATED:b=.) 771!if [echo RCCOMMAVERSION = \> versions.vc] \ 772 || [for /f "tokens=1,2,3,4,5* delims=." %a in ("$(DOTSEPARATED).0.0.0.0") do echo %a,%b,%c,%d >> versions.vc] 773!error *** Could not generate RCCOMMAVERSION *** 774!endif 775!include versions.vc 776 777######################################################################## 778# 7. Parse the OPTS macro to work out the requested build configuration. 779# Based on this, we will construct the actual switches to be passed to the 780# compiler and linker using the macros defined in the previous section. 781# The following macros are defined by this section based on OPTS 782# STATIC_BUILD - 0 -> Tcl is to be built as a shared library 783# 1 -> build as a static library and shell 784# TCL_THREADS - legacy but always 1 on Windows since winsock requires it. 785# DEBUG - 1 -> debug build, 0 -> release builds 786# SYMBOLS - 1 -> generate PDB's, 0 -> no PDB's 787# PROFILE - 1 -> generate profiling info, 0 -> no profiling 788# PGO - 1 -> profile based optimization, 0 -> no 789# MSVCRT - 1 -> link to dynamic C runtime even when building static Tcl build 790# 0 -> link to static C runtime for static Tcl build. 791# Does not impact shared Tcl builds (STATIC_BUILD == 0) 792# Default: 1 for Tcl 8.7 and up, 0 otherwise. 793# TCL_USE_STATIC_PACKAGES - 1 -> statically link the registry and dde extensions 794# in the Tcl and Wish shell. 0 -> keep them as shared libraries. Does 795# not impact shared Tcl builds. Implied by STATIC_BUILD since Tcl 8.7. 796# USE_THREAD_ALLOC - 1 -> Use a shared global free pool for allocation. 797# 0 -> Use the non-thread allocator. 798# UNCHECKED - 1 -> when doing a debug build with symbols, use the release 799# C runtime, 0 -> use the debug C runtime. 800# USE_STUBS - 1 -> compile to use stubs interfaces, 0 -> direct linking 801# CONFIG_CHECK - 1 -> check current build configuration against Tcl 802# configuration (ignored for Tcl itself) 803# _USE_64BIT_TIME_T - forces a build using 64-bit time_t for 32-bit build 804# (CRT library should support this, not needed for Tcl 9.x) 805# TCL_UTF_MAX=4 - forces a build allowing 4-byte UTF-8 sequences internally. 806# (Not needed for Tcl 9.x) 807# Further, LINKERFLAGS are modified based on above. 808 809# Default values for all the above 810STATIC_BUILD = 0 811TCL_THREADS = 1 812DEBUG = 0 813SYMBOLS = 0 814PROFILE = 0 815PGO = 0 816MSVCRT = 1 817TCL_USE_STATIC_PACKAGES = 0 818USE_THREAD_ALLOC = 1 819UNCHECKED = 0 820CONFIG_CHECK = 1 821!if $(DOING_TCL) 822USE_STUBS = 0 823!else 824USE_STUBS = 1 825!endif 826 827# If OPTS is not empty AND does not contain "none" which turns off all OPTS 828# set the above macros based on OPTS content 829!if "$(OPTS)" != "" && ![nmakehlp -f "$(OPTS)" "none"] 830 831# OPTS are specified, parse them 832 833!if [nmakehlp -f $(OPTS) "static"] 834!message *** Doing static 835STATIC_BUILD = 1 836!endif 837 838!if [nmakehlp -f $(OPTS) "nostubs"] 839!message *** Not using stubs 840USE_STUBS = 0 841!endif 842 843!if [nmakehlp -f $(OPTS) "nomsvcrt"] 844!message *** Doing nomsvcrt 845MSVCRT = 0 846!else 847!if [nmakehlp -f $(OPTS) "msvcrt"] 848!message *** Doing msvcrt 849!else 850!if $(TCL_MAJOR_VERSION) == 8 && $(TCL_MINOR_VERSION) < 7 && $(STATIC_BUILD) 851MSVCRT = 0 852!endif 853!endif 854!endif # [nmakehlp -f $(OPTS) "nomsvcrt"] 855 856!if [nmakehlp -f $(OPTS) "staticpkg"] && $(STATIC_BUILD) 857!message *** Doing staticpkg 858TCL_USE_STATIC_PACKAGES = 1 859!endif 860 861!if [nmakehlp -f $(OPTS) "nothreads"] 862!message *** Compile explicitly for non-threaded tcl 863TCL_THREADS = 0 864USE_THREAD_ALLOC= 0 865!endif 866 867!if $(TCL_MAJOR_VERSION) == 8 868!if [nmakehlp -f $(OPTS) "time64bit"] 869!message *** Force 64-bit time_t 870_USE_64BIT_TIME_T = 1 871!endif 872 873!if [nmakehlp -f $(OPTS) "utfmax"] 874!message *** Force allowing 4-byte UTF-8 sequences internally 875TCL_UTF_MAX = 4 876!endif 877!endif 878 879# Yes, it's weird that the "symbols" option controls DEBUG and 880# the "pdbs" option controls SYMBOLS. That's historical. 881!if [nmakehlp -f $(OPTS) "symbols"] 882!message *** Doing symbols 883DEBUG = 1 884!else 885DEBUG = 0 886!endif 887 888!if [nmakehlp -f $(OPTS) "pdbs"] 889!message *** Doing pdbs 890SYMBOLS = 1 891!else 892SYMBOLS = 0 893!endif 894 895!if [nmakehlp -f $(OPTS) "profile"] 896!message *** Doing profile 897PROFILE = 1 898!else 899PROFILE = 0 900!endif 901 902!if [nmakehlp -f $(OPTS) "pgi"] 903!message *** Doing profile guided optimization instrumentation 904PGO = 1 905!elseif [nmakehlp -f $(OPTS) "pgo"] 906!message *** Doing profile guided optimization 907PGO = 2 908!else 909PGO = 0 910!endif 911 912!if [nmakehlp -f $(OPTS) "loimpact"] 913!message *** Warning: ignoring option "loimpact" - deprecated on modern Windows. 914!endif 915 916# TBD - should get rid of this option 917!if [nmakehlp -f $(OPTS) "thrdalloc"] 918!message *** Doing thrdalloc 919USE_THREAD_ALLOC = 1 920!endif 921 922!if [nmakehlp -f $(OPTS) "tclalloc"] 923USE_THREAD_ALLOC = 0 924!endif 925 926!if [nmakehlp -f $(OPTS) "unchecked"] 927!message *** Doing unchecked 928UNCHECKED = 1 929!else 930UNCHECKED = 0 931!endif 932 933!if [nmakehlp -f $(OPTS) "noconfigcheck"] 934CONFIG_CHECK = 1 935!else 936CONFIG_CHECK = 0 937!endif 938 939!endif # "$(OPTS)" != "" && ... parsing of OPTS 940 941# Set linker flags based on above 942 943!if $(PGO) > 1 944!if [nmakehlp -l -ltcg:pgoptimize $(LINKER_TESTFLAGS)] 945LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pgoptimize 946!else 947MSG=^ 948This compiler does not support profile guided optimization. 949!error $(MSG) 950!endif 951!elseif $(PGO) > 0 952!if [nmakehlp -l -ltcg:pginstrument $(LINKER_TESTFLAGS)] 953LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pginstrument 954!else 955MSG=^ 956This compiler does not support profile guided optimization. 957!error $(MSG) 958!endif 959!endif 960 961################################################################ 962# 8. Parse the STATS macro to configure code instrumentation 963# The following macros are set by this section: 964# TCL_MEM_DEBUG - 1 -> enables memory allocation instrumentation 965# 0 -> disables 966# TCL_COMPILE_DEBUG - 1 -> enables byte compiler logging 967# 0 -> disables 968 969# Default both are off 970TCL_MEM_DEBUG = 0 971TCL_COMPILE_DEBUG = 0 972 973!if "$(STATS)" != "" && ![nmakehlp -f "$(STATS)" "none"] 974 975!if [nmakehlp -f $(STATS) "memdbg"] 976!message *** Doing memdbg 977TCL_MEM_DEBUG = 1 978!else 979TCL_MEM_DEBUG = 0 980!endif 981 982!if [nmakehlp -f $(STATS) "compdbg"] 983!message *** Doing compdbg 984TCL_COMPILE_DEBUG = 1 985!else 986TCL_COMPILE_DEBUG = 0 987!endif 988 989!endif 990 991#################################################################### 992# 9. Parse the CHECKS macro to configure additional compiler checks 993# The following macros are set by this section: 994# WARNINGS - compiler switches that control the warnings level 995# TCL_NO_DEPRECATED - 1 -> disable support for deprecated functions 996# 0 -> enable deprecated functions 997 998# Defaults - Permit deprecated functions and warning level 3 999TCL_NO_DEPRECATED = 0 1000WARNINGS = -W3 1001 1002!if "$(CHECKS)" != "" && ![nmakehlp -f "$(CHECKS)" "none"] 1003 1004!if [nmakehlp -f $(CHECKS) "nodep"] 1005!message *** Doing nodep check 1006TCL_NO_DEPRECATED = 1 1007!endif 1008 1009!if [nmakehlp -f $(CHECKS) "fullwarn"] 1010!message *** Doing full warnings check 1011WARNINGS = -W4 1012!if [nmakehlp -l -warn:3 $(LINKER_TESTFLAGS)] 1013LINKERFLAGS = $(LINKERFLAGS) -warn:3 1014!endif 1015!endif 1016 1017!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64] 1018!message *** Doing 64bit portability warnings 1019WARNINGS = $(WARNINGS) -Wp64 1020!endif 1021 1022!endif 1023 1024 1025################################################################ 1026# 10. Construct output directory and file paths 1027# Figure-out how to name our intermediate and output directories. 1028# In order to avoid inadvertent mixing of object files built using 1029# different compilers, build configurations etc., 1030# 1031# Naming convention (suffixes): 1032# t = full thread support. (Not used for Tcl >= 8.7) 1033# s = static library (as opposed to an import library) 1034# g = linked to the debug enabled C run-time. 1035# x = special static build when it links to the dynamic C run-time. 1036# 1037# The following macros are set in this section: 1038# SUFX - the suffix to use for binaries based on above naming convention 1039# BUILDDIRTOP - the toplevel default output directory 1040# is of the form {Release,Debug}[_AMD64][_COMPILERVERSION] 1041# TMP_DIR - directory where object files are created 1042# OUT_DIR - directory where output executables are created 1043# Both TMP_DIR and OUT_DIR are defaulted only if not defined by the 1044# parent makefile (or command line). The default values are 1045# based on BUILDDIRTOP. 1046# STUBPREFIX - name of the stubs library for this project 1047# PRJIMPLIB - output path of the generated project import library 1048# PRJLIBNAME - name of generated project library 1049# PRJLIB - output path of generated project library 1050# PRJSTUBLIBNAME - name of the generated project stubs library 1051# PRJSTUBLIB - output path of the generated project stubs library 1052# RESFILE - output resource file (only if not static build) 1053 1054SUFX = tsgx 1055 1056!if $(DEBUG) 1057BUILDDIRTOP = Debug 1058!else 1059BUILDDIRTOP = Release 1060!endif 1061 1062!if "$(MACHINE)" != "IX86" 1063BUILDDIRTOP =$(BUILDDIRTOP)_$(MACHINE) 1064!endif 1065!if $(VCVER) > 6 1066BUILDDIRTOP =$(BUILDDIRTOP)_VC$(VCVER) 1067!endif 1068 1069!if !$(DEBUG) || $(TCL_VERSION) > 86 || $(DEBUG) && $(UNCHECKED) 1070SUFX = $(SUFX:g=) 1071!endif 1072 1073TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX 1074 1075!if !$(STATIC_BUILD) 1076TMP_DIRFULL = $(TMP_DIRFULL:Static=) 1077SUFX = $(SUFX:s=) 1078EXT = dll 1079TMP_DIRFULL = $(TMP_DIRFULL:X=) 1080SUFX = $(SUFX:x=) 1081!else 1082TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=) 1083EXT = lib 1084!if !$(MSVCRT) 1085TMP_DIRFULL = $(TMP_DIRFULL:X=) 1086SUFX = $(SUFX:x=) 1087!endif 1088!endif 1089 1090!if !$(TCL_THREADS) || $(TCL_VERSION) > 86 1091TMP_DIRFULL = $(TMP_DIRFULL:Threaded=) 1092SUFX = $(SUFX:t=) 1093!endif 1094 1095!ifndef TMP_DIR 1096TMP_DIR = $(TMP_DIRFULL) 1097!ifndef OUT_DIR 1098OUT_DIR = .\$(BUILDDIRTOP) 1099!endif 1100!else 1101!ifndef OUT_DIR 1102OUT_DIR = $(TMP_DIR) 1103!endif 1104!endif 1105 1106# Relative paths -> absolute 1107!if [echo OUT_DIR = \> nmakehlp.out] \ 1108 || [nmakehlp -Q "$(OUT_DIR)" >> nmakehlp.out] 1109!error *** Could not fully qualify path OUT_DIR=$(OUT_DIR) 1110!endif 1111!if [echo TMP_DIR = \>> nmakehlp.out] \ 1112 || [nmakehlp -Q "$(TMP_DIR)" >> nmakehlp.out] 1113!error *** Could not fully qualify path TMP_DIR=$(TMP_DIR) 1114!endif 1115!include nmakehlp.out 1116 1117# The name of the stubs library for the project being built 1118STUBPREFIX = $(PROJECT)stub 1119 1120# 1121# Set up paths to various Tcl executables and libraries needed by extensions 1122# 1123 1124# TIP 430. Unused for 8.6 but no harm defining it to allow a common rules.vc 1125TCLSCRIPTZIPNAME = libtcl$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)$(TCL_PATCH_LETTER)$(TCL_RELEASE_SERIAL).zip 1126TKSCRIPTZIPNAME = libtk$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)$(TK_PATCH_LETTER)$(TK_RELEASE_SERIAL).zip 1127 1128!if $(DOING_TCL) 1129TCLSHNAME = $(PROJECT)sh$(VERSION)$(SUFX).exe 1130TCLSH = $(OUT_DIR)\$(TCLSHNAME) 1131TCLIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib 1132TCLLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT) 1133TCLLIB = $(OUT_DIR)\$(TCLLIBNAME) 1134TCLSCRIPTZIP = $(OUT_DIR)\$(TCLSCRIPTZIPNAME) 1135 1136TCLSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib 1137TCLSTUBLIB = $(OUT_DIR)\$(TCLSTUBLIBNAME) 1138TCL_INCLUDES = -I"$(WIN_DIR)" -I"$(GENERICDIR)" 1139 1140!else # !$(DOING_TCL) 1141 1142!if $(TCLINSTALL) # Building against an installed Tcl 1143 1144# When building extensions, we need to locate tclsh. Depending on version 1145# of Tcl we are building against, this may or may not have a "t" suffix. 1146# Try various possibilities in turn. 1147TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX:t=).exe 1148!if !exist("$(TCLSH)") 1149TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX:t=).exe 1150!endif 1151 1152TCLSTUBLIB = $(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib 1153TCLIMPLIB = $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX:t=).lib 1154# When building extensions, may be linking against Tcl that does not add 1155# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility. 1156!if !exist("$(TCLIMPLIB)") 1157TCLIMPLIB = $(_TCLDIR)\lib\tcl$(TCL_VERSION)t$(SUFX:t=).lib 1158!endif 1159TCL_LIBRARY = $(_TCLDIR)\lib 1160TCLREGLIB = $(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib 1161TCLDDELIB = $(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib 1162TCLSCRIPTZIP = $(_TCLDIR)\lib\$(TCLSCRIPTZIPNAME) 1163TCLTOOLSDIR = \must\have\tcl\sources\to\build\this\target 1164TCL_INCLUDES = -I"$(_TCLDIR)\include" 1165 1166!else # Building against Tcl sources 1167 1168TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX:t=).exe 1169!if !exist($(TCLSH)) 1170TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX:t=).exe 1171!endif 1172TCLSTUBLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib 1173TCLIMPLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX:t=).lib 1174# When building extensions, may be linking against Tcl that does not add 1175# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility. 1176!if !exist("$(TCLIMPLIB)") 1177TCLIMPLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)t$(SUFX:t=).lib 1178!endif 1179TCL_LIBRARY = $(_TCLDIR)\library 1180TCLREGLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib 1181TCLDDELIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib 1182TCLSCRIPTZIP = $(_TCLDIR)\win\$(BUILDDIRTOP)\$(TCLSCRIPTZIPNAME) 1183TCLTOOLSDIR = $(_TCLDIR)\tools 1184TCL_INCLUDES = -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win" 1185 1186!endif # TCLINSTALL 1187 1188tcllibs = "$(TCLSTUBLIB)" "$(TCLIMPLIB)" 1189 1190!endif # $(DOING_TCL) 1191 1192# We need a tclsh that will run on the host machine as part of the build. 1193# IX86 runs on all architectures. 1194!ifndef TCLSH_NATIVE 1195!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)" 1196TCLSH_NATIVE = $(TCLSH) 1197!else 1198!error You must explicitly set TCLSH_NATIVE for cross-compilation 1199!endif 1200!endif 1201 1202# Do the same for Tk and Tk extensions that require the Tk libraries 1203!if $(DOING_TK) || $(NEED_TK) 1204WISHNAMEPREFIX = wish 1205WISHNAME = $(WISHNAMEPREFIX)$(TK_VERSION)$(SUFX).exe 1206TKLIBNAME8 = tk$(TK_VERSION)$(SUFX).$(EXT) 1207TKLIBNAME9 = tcl9tk$(TK_VERSION)$(SUFX).$(EXT) 1208!if $(TCL_MAJOR_VERSION) == 8 1209TKLIBNAME = tk$(TK_VERSION)$(SUFX).$(EXT) 1210TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX).lib 1211!else 1212TKLIBNAME = tcl9tk$(TK_VERSION)$(SUFX).$(EXT) 1213TKIMPLIBNAME = tcl9tk$(TK_VERSION)$(SUFX).lib 1214!endif 1215TKSTUBLIBNAME = tkstub$(TK_VERSION).lib 1216 1217!if $(DOING_TK) 1218WISH = $(OUT_DIR)\$(WISHNAME) 1219TKSTUBLIB = $(OUT_DIR)\$(TKSTUBLIBNAME) 1220TKIMPLIB = $(OUT_DIR)\$(TKIMPLIBNAME) 1221TKLIB = $(OUT_DIR)\$(TKLIBNAME) 1222TK_INCLUDES = -I"$(WIN_DIR)" -I"$(GENERICDIR)" 1223TKSCRIPTZIP = $(OUT_DIR)\$(TKSCRIPTZIPNAME) 1224 1225!else # effectively NEED_TK 1226 1227!if $(TKINSTALL) # Building against installed Tk 1228WISH = $(_TKDIR)\bin\$(WISHNAME) 1229TKSTUBLIB = $(_TKDIR)\lib\$(TKSTUBLIBNAME) 1230TKIMPLIB = $(_TKDIR)\lib\$(TKIMPLIBNAME) 1231# When building extensions, may be linking against Tk that does not add 1232# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility. 1233!if !exist("$(TKIMPLIB)") 1234TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX:t=).lib 1235TKIMPLIB = $(_TKDIR)\lib\$(TKIMPLIBNAME) 1236!endif 1237TK_INCLUDES = -I"$(_TKDIR)\include" 1238TKSCRIPTZIP = $(_TKDIR)\lib\$(TKSCRIPTZIPNAME) 1239 1240!else # Building against Tk sources 1241 1242WISH = $(_TKDIR)\win\$(BUILDDIRTOP)\$(WISHNAME) 1243TKSTUBLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSTUBLIBNAME) 1244TKIMPLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME) 1245# When building extensions, may be linking against Tk that does not add 1246# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility. 1247!if !exist("$(TKIMPLIB)") 1248TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX:t=).lib 1249TKIMPLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME) 1250!endif 1251TK_INCLUDES = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib" 1252TKSCRIPTZIP = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSCRIPTZIPNAME) 1253 1254!endif # TKINSTALL 1255 1256tklibs = "$(TKSTUBLIB)" "$(TKIMPLIB)" 1257 1258!endif # $(DOING_TK) 1259!endif # $(DOING_TK) || $(NEED_TK) 1260 1261# Various output paths 1262PRJIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib 1263PRJLIBNAME8 = $(PROJECT)$(VERSION)$(SUFX).$(EXT) 1264PRJLIBNAME9 = tcl9$(PROJECT)$(VERSION)$(SUFX).$(EXT) 1265!if $(TCL_MAJOR_VERSION) == 8 1266PRJLIBNAME = $(PRJLIBNAME8) 1267!else 1268PRJLIBNAME = $(PRJLIBNAME9) 1269!endif 1270PRJLIB = $(OUT_DIR)\$(PRJLIBNAME) 1271 1272PRJSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib 1273PRJSTUBLIB = $(OUT_DIR)\$(PRJSTUBLIBNAME) 1274 1275# If extension parent makefile has not defined a resource definition file, 1276# we will generate one from standard template. 1277!if !$(DOING_TCL) && !$(DOING_TK) && !$(STATIC_BUILD) 1278!ifdef RCFILE 1279RESFILE = $(TMP_DIR)\$(RCFILE:.rc=.res) 1280!else 1281RESFILE = $(TMP_DIR)\$(PROJECT).res 1282!endif 1283!endif 1284 1285################################################################### 1286# 11. Construct the paths for the installation directories 1287# The following macros get defined in this section: 1288# LIB_INSTALL_DIR - where libraries should be installed 1289# BIN_INSTALL_DIR - where the executables should be installed 1290# DOC_INSTALL_DIR - where documentation should be installed 1291# SCRIPT_INSTALL_DIR - where scripts should be installed 1292# INCLUDE_INSTALL_DIR - where C include files should be installed 1293# DEMO_INSTALL_DIR - where demos should be installed 1294# PRJ_INSTALL_DIR - where package will be installed (not set for Tcl and Tk) 1295 1296!if $(DOING_TCL) || $(DOING_TK) 1297LIB_INSTALL_DIR = $(_INSTALLDIR)\lib 1298BIN_INSTALL_DIR = $(_INSTALLDIR)\bin 1299DOC_INSTALL_DIR = $(_INSTALLDIR)\doc 1300!if $(DOING_TCL) 1301SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION) 1302MODULE_INSTALL_DIR = $(_INSTALLDIR)\lib\tcl$(TCL_MAJOR_VERSION) 1303!else # DOING_TK 1304SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION) 1305!endif 1306DEMO_INSTALL_DIR = $(SCRIPT_INSTALL_DIR)\demos 1307INCLUDE_INSTALL_DIR = $(_INSTALLDIR)\include 1308 1309!else # extension other than Tk 1310 1311PRJ_INSTALL_DIR = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION) 1312!if $(MULTIPLATFORM_INSTALL) 1313LIB_INSTALL_DIR = $(PRJ_INSTALL_DIR)\$(PLATFORM_IDENTIFY) 1314BIN_INSTALL_DIR = $(PRJ_INSTALL_DIR)\$(PLATFORM_IDENTIFY) 1315!else 1316LIB_INSTALL_DIR = $(PRJ_INSTALL_DIR) 1317BIN_INSTALL_DIR = $(PRJ_INSTALL_DIR) 1318!endif 1319DOC_INSTALL_DIR = $(PRJ_INSTALL_DIR) 1320SCRIPT_INSTALL_DIR = $(PRJ_INSTALL_DIR) 1321DEMO_INSTALL_DIR = $(PRJ_INSTALL_DIR)\demos 1322INCLUDE_INSTALL_DIR = $(_INSTALLDIR)\..\include 1323 1324!endif 1325 1326################################################################### 1327# 12. Set up actual options to be passed to the compiler and linker 1328# Now we have all the information we need, set up the actual flags and 1329# options that we will pass to the compiler and linker. The main 1330# makefile should use these in combination with whatever other flags 1331# and switches are specific to it. 1332# The following macros are defined, names are for historical compatibility: 1333# OPTDEFINES - /Dxxx C macro flags based on user-specified OPTS 1334# COMPILERFLAGS - /Dxxx C macro flags independent of any configuration opttions 1335# crt - Compiler switch that selects the appropriate C runtime 1336# cdebug - Compiler switches related to debug AND optimizations 1337# cwarn - Compiler switches that set warning levels 1338# cflags - complete compiler switches (subsumes cdebug and cwarn) 1339# ldebug - Linker switches controlling debug information and optimization 1340# lflags - complete linker switches (subsumes ldebug) except subsystem type 1341# dlllflags - complete linker switches to build DLLs (subsumes lflags) 1342# conlflags - complete linker switches for console program (subsumes lflags) 1343# guilflags - complete linker switches for GUI program (subsumes lflags) 1344# baselibs - minimum Windows libraries required. Parent makefile can 1345# define PRJ_LIBS before including rules.rc if additional libs are needed 1346 1347OPTDEFINES = /DSTDC_HEADERS /DUSE_NMAKE=1 1348!if $(VCVERSION) > 1600 1349OPTDEFINES = $(OPTDEFINES) /DHAVE_STDINT_H=1 1350!else 1351OPTDEFINES = $(OPTDEFINES) /DMP_NO_STDINT=1 1352!endif 1353!if $(VCVERSION) >= 1800 1354OPTDEFINES = $(OPTDEFINES) /DHAVE_INTTYPES_H=1 /DHAVE_STDBOOL_H=1 1355!endif 1356 1357!if $(TCL_MEM_DEBUG) 1358OPTDEFINES = $(OPTDEFINES) /DTCL_MEM_DEBUG 1359!endif 1360!if $(TCL_COMPILE_DEBUG) 1361OPTDEFINES = $(OPTDEFINES) /DTCL_COMPILE_DEBUG /DTCL_COMPILE_STATS 1362!endif 1363!if $(TCL_THREADS) && $(TCL_VERSION) < 87 1364OPTDEFINES = $(OPTDEFINES) /DTCL_THREADS=1 1365!if $(USE_THREAD_ALLOC) && $(TCL_VERSION) < 87 1366OPTDEFINES = $(OPTDEFINES) /DUSE_THREAD_ALLOC=1 1367!endif 1368!endif 1369!if $(STATIC_BUILD) 1370OPTDEFINES = $(OPTDEFINES) /DSTATIC_BUILD 1371!elseif $(TCL_VERSION) > 86 1372OPTDEFINES = $(OPTDEFINES) /DTCL_WITH_EXTERNAL_TOMMATH 1373!if "$(MACHINE)" == "AMD64" 1374OPTDEFINES = $(OPTDEFINES) /DMP_64BIT 1375!endif 1376!endif 1377!if $(TCL_NO_DEPRECATED) 1378OPTDEFINES = $(OPTDEFINES) /DTCL_NO_DEPRECATED 1379!endif 1380 1381!if $(USE_STUBS) 1382# Note we do not define USE_TCL_STUBS even when building tk since some 1383# test targets in tk do not use stubs 1384!if !$(DOING_TCL) 1385USE_STUBS_DEFS = /DUSE_TCL_STUBS /DUSE_TCLOO_STUBS 1386!if $(NEED_TK) 1387USE_STUBS_DEFS = $(USE_STUBS_DEFS) /DUSE_TK_STUBS 1388!endif 1389!endif 1390!endif # USE_STUBS 1391 1392!if !$(DEBUG) 1393OPTDEFINES = $(OPTDEFINES) /DNDEBUG 1394!if $(OPTIMIZING) 1395OPTDEFINES = $(OPTDEFINES) /DTCL_CFG_OPTIMIZED 1396!endif 1397!endif 1398!if $(PROFILE) 1399OPTDEFINES = $(OPTDEFINES) /DTCL_CFG_PROFILED 1400!endif 1401!if "$(MACHINE)" == "AMD64" 1402OPTDEFINES = $(OPTDEFINES) /DTCL_CFG_DO64BIT 1403!endif 1404!if $(VCVERSION) < 1300 1405OPTDEFINES = $(OPTDEFINES) /DNO_STRTOI64=1 1406!endif 1407 1408!if "$(TCL_MAJOR_VERSION)" == "8" 1409!if "$(_USE_64BIT_TIME_T)" == "1" 1410OPTDEFINES = $(OPTDEFINES) /D_USE_64BIT_TIME_T=1 1411!endif 1412!if "$(TCL_UTF_MAX)" == "4" 1413OPTDEFINES = $(OPTDEFINES) /DTCL_UTF_MAX=4 1414!endif 1415 1416# _ATL_XP_TARGETING - Newer SDK's need this to build for XP 1417COMPILERFLAGS = /D_ATL_XP_TARGETING 1418!endif 1419 1420# Like the TEA system only set this non empty for non-Tk extensions 1421# Note: some extensions use PACKAGE_NAME and others use PACKAGE_TCLNAME 1422# so we pass both 1423!if !$(DOING_TCL) && !$(DOING_TK) 1424PKGNAMEFLAGS = /DPACKAGE_NAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \ 1425 /DPACKAGE_TCLNAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \ 1426 /DPACKAGE_VERSION="\"$(DOTVERSION)\"" \ 1427 /DMODULE_SCOPE=extern 1428!endif 1429 1430# crt picks the C run time based on selected OPTS 1431!if $(MSVCRT) 1432!if $(DEBUG) && !$(UNCHECKED) 1433crt = -MDd 1434!else 1435crt = -MD 1436!endif 1437!else 1438!if $(DEBUG) && !$(UNCHECKED) 1439crt = -MTd 1440!else 1441crt = -MT 1442!endif 1443!endif 1444 1445# cdebug includes compiler options for debugging as well as optimization. 1446!if $(DEBUG) 1447 1448# In debugging mode, optimizations need to be disabled 1449cdebug = -Zi -Od $(DEBUGFLAGS) 1450 1451!else 1452 1453cdebug = $(OPTIMIZATIONS) 1454!if $(SYMBOLS) 1455cdebug = $(cdebug) -Zi 1456!endif 1457 1458!endif # $(DEBUG) 1459 1460# cwarn includes default warning levels. 1461cwarn = $(WARNINGS) 1462 1463!if "$(MACHINE)" == "AMD64" 1464# Disable pointer<->int warnings related to cast between different sizes 1465# There are a gadzillion of these due to use of ClientData and 1466# clutter up compiler 1467# output increasing chance of a real warning getting lost. So disable them. 1468# Eventually some day, Tcl will be 64-bit clean. 1469cwarn = $(cwarn) -wd4311 -wd4312 1470!endif 1471 1472### Common compiler options that are architecture specific 1473!if "$(MACHINE)" == "ARM" 1474carch = /D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE 1475!else 1476carch = 1477!endif 1478 1479!if $(DEBUG) 1480# Turn warnings into errors 1481cwarn = $(cwarn) -WX 1482!endif 1483 1484INCLUDES = $(TCL_INCLUDES) $(TK_INCLUDES) $(PRJ_INCLUDES) 1485!if !$(DOING_TCL) && !$(DOING_TK) 1486INCLUDES = $(INCLUDES) -I"$(GENERICDIR)" -I"$(WIN_DIR)" -I"$(COMPATDIR)" 1487!endif 1488 1489# These flags are defined roughly in the order of the pre-reform 1490# rules.vc/makefile.vc to help visually compare that the pre- and 1491# post-reform build logs 1492 1493# cflags contains generic flags used for building practically all object files 1494cflags = -nologo -c $(COMPILERFLAGS) $(carch) $(cwarn) -Fp$(TMP_DIR)^\ $(cdebug) 1495 1496# appcflags contains $(cflags) and flags for building the application 1497# object files (e.g. tclsh, or wish) pkgcflags contains $(cflags) plus 1498# flags used for building shared object files The two differ in the 1499# BUILD_$(PROJECT) macro which should be defined only for the shared 1500# library *implementation* and not for its caller interface 1501 1502appcflags_nostubs = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES) 1503appcflags = $(appcflags_nostubs) $(USE_STUBS_DEFS) 1504pkgcflags = $(appcflags) $(PKGNAMEFLAGS) /DBUILD_$(PROJECT) 1505pkgcflags_nostubs = $(appcflags_nostubs) $(PKGNAMEFLAGS) /DBUILD_$(PROJECT) 1506 1507# stubscflags contains $(cflags) plus flags used for building a stubs 1508# library for the package. Note: /DSTATIC_BUILD is defined in 1509# $(OPTDEFINES) only if the OPTS configuration indicates a static 1510# library. However the stubs library is ALWAYS static hence included 1511# here irrespective of the OPTS setting. 1512# 1513# TBD - tclvfs has a comment that stubs libs should not be compiled with -GL 1514# without stating why. Tcl itself compiled stubs libs with this flag. 1515# so we do not remove it from cflags. -GL may prevent extensions 1516# compiled with one VC version to fail to link against stubs library 1517# compiled with another VC version. Check for this and fix accordingly. 1518stubscflags = $(cflags) $(PKGNAMEFLAGS) $(PRJ_DEFINES) $(OPTDEFINES) /Zl /GL- /DSTATIC_BUILD $(INCLUDES) $(USE_STUBS_DEFS) 1519 1520# Link flags 1521 1522!if $(DEBUG) 1523ldebug = -debug -debugtype:cv 1524!else 1525ldebug = -release -opt:ref -opt:icf,3 1526!if $(SYMBOLS) 1527ldebug = $(ldebug) -debug -debugtype:cv 1528!endif 1529!endif 1530 1531# Note: Profiling is currently only possible with the Visual Studio Enterprise 1532!if $(PROFILE) 1533ldebug= $(ldebug) -profile 1534!endif 1535 1536### Declarations common to all linker versions 1537lflags = -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug) 1538 1539!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900 1540lflags = $(lflags) -nodefaultlib:libucrt.lib 1541!endif 1542 1543dlllflags = $(lflags) -dll 1544conlflags = $(lflags) -subsystem:console 1545guilflags = $(lflags) -subsystem:windows 1546 1547# Libraries that are required for every image. 1548# Extensions should define any additional libraries with $(PRJ_LIBS) 1549winlibs = kernel32.lib advapi32.lib 1550 1551!if $(NEED_TK) 1552winlibs = $(winlibs) gdi32.lib user32.lib uxtheme.lib 1553!endif 1554 1555# Avoid 'unresolved external symbol __security_cookie' errors. 1556# c.f. http://support.microsoft.com/?id=894573 1557!if "$(MACHINE)" == "AMD64" 1558!if $(VCVERSION) > 1399 && $(VCVERSION) < 1500 1559winlibs = $(winlibs) bufferoverflowU.lib 1560!endif 1561!endif 1562 1563baselibs = $(winlibs) $(PRJ_LIBS) 1564 1565!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900 1566baselibs = $(baselibs) ucrt.lib 1567!endif 1568 1569################################################################ 1570# 13. Define standard commands, common make targets and implicit rules 1571 1572CCPKGCMD = $(cc32) $(pkgcflags) -Fo$(TMP_DIR)^\ 1573CCAPPCMD = $(cc32) $(appcflags) -Fo$(TMP_DIR)^\ 1574CCSTUBSCMD = $(cc32) $(stubscflags) -Fo$(TMP_DIR)^\ 1575 1576LIBCMD = $(lib32) -nologo $(LINKERFLAGS) -out:$@ 1577DLLCMD = $(link32) $(dlllflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs) 1578 1579CONEXECMD = $(link32) $(conlflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs) 1580GUIEXECMD = $(link32) $(guilflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs) 1581RESCMD = $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" \ 1582 $(TCL_INCLUDES) \ 1583 /DDEBUG=$(DEBUG) -d UNCHECKED=$(UNCHECKED) \ 1584 /DCOMMAVERSION=$(RCCOMMAVERSION) \ 1585 /DDOTVERSION=\"$(DOTVERSION)\" \ 1586 /DVERSION=\"$(VERSION)\" \ 1587 /DSUFX=\"$(SUFX)\" \ 1588 /DPROJECT=\"$(PROJECT)\" \ 1589 /DPRJLIBNAME=\"$(PRJLIBNAME)\" 1590 1591!ifndef DEFAULT_BUILD_TARGET 1592DEFAULT_BUILD_TARGET = $(PROJECT) 1593!endif 1594 1595default-target: $(DEFAULT_BUILD_TARGET) 1596 1597!if $(MULTIPLATFORM_INSTALL) 1598default-pkgindex: 1599 @echo if {[package vsatisfies [package provide Tcl] 9.0-]} { > $(OUT_DIR)\pkgIndex.tcl 1600 @echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \ 1601 [list load [file join $$dir $(PLATFORM_IDENTIFY) $(PRJLIBNAME9)]] >> $(OUT_DIR)\pkgIndex.tcl 1602 @echo } else { >> $(OUT_DIR)\pkgIndex.tcl 1603 @echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \ 1604 [list load [file join $$dir $(PLATFORM_IDENTIFY) $(PRJLIBNAME8)]] >> $(OUT_DIR)\pkgIndex.tcl 1605 @echo } >> $(OUT_DIR)\pkgIndex.tcl 1606!else 1607default-pkgindex: 1608 @echo if {[package vsatisfies [package provide Tcl] 9.0-]} { > $(OUT_DIR)\pkgIndex.tcl 1609 @echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \ 1610 [list load [file join $$dir $(PRJLIBNAME9)]] >> $(OUT_DIR)\pkgIndex.tcl 1611 @echo } else { >> $(OUT_DIR)\pkgIndex.tcl 1612 @echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \ 1613 [list load [file join $$dir $(PRJLIBNAME8)]] >> $(OUT_DIR)\pkgIndex.tcl 1614 @echo } >> $(OUT_DIR)\pkgIndex.tcl 1615!endif 1616 1617default-pkgindex-tea: 1618 @if exist $(ROOT)\pkgIndex.tcl.in nmakehlp -s << $(ROOT)\pkgIndex.tcl.in > $(OUT_DIR)\pkgIndex.tcl 1619@PACKAGE_VERSION@ $(DOTVERSION) 1620@PACKAGE_NAME@ $(PRJ_PACKAGE_TCLNAME) 1621@PACKAGE_TCLNAME@ $(PRJ_PACKAGE_TCLNAME) 1622@PKG_LIB_FILE@ $(PRJLIBNAME) 1623@PKG_LIB_FILE8@ $(PRJLIBNAME8) 1624@PKG_LIB_FILE9@ $(PRJLIBNAME9) 1625<< 1626 1627default-install: default-install-binaries default-install-libraries 1628!if $(SYMBOLS) 1629default-install: default-install-pdbs 1630!endif 1631 1632# Again to deal with historical brokenness, there is some confusion 1633# in terminlogy. For extensions, the "install-binaries" was used to 1634# locate target directory for *binary shared libraries* and thus 1635# the appropriate macro is LIB_INSTALL_DIR since BIN_INSTALL_DIR is 1636# for executables (exes). On the other hand the "install-libraries" 1637# target is for *scripts* and should have been called "install-scripts". 1638default-install-binaries: $(PRJLIB) 1639 @echo Installing binaries to '$(LIB_INSTALL_DIR)' 1640 @if not exist "$(LIB_INSTALL_DIR)" mkdir "$(LIB_INSTALL_DIR)" 1641 @$(CPY) $(PRJLIB) "$(LIB_INSTALL_DIR)" >NUL 1642 1643# Alias for default-install-scripts 1644default-install-libraries: default-install-scripts 1645 1646default-install-scripts: $(OUT_DIR)\pkgIndex.tcl 1647 @echo Installing libraries to '$(SCRIPT_INSTALL_DIR)' 1648 @if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)" 1649 @echo Installing package index in '$(SCRIPT_INSTALL_DIR)' 1650 @$(CPY) $(OUT_DIR)\pkgIndex.tcl $(SCRIPT_INSTALL_DIR) 1651 1652default-install-stubs: 1653 @echo Installing stubs library to '$(SCRIPT_INSTALL_DIR)' 1654 @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)" 1655 @$(CPY) $(PRJSTUBLIB) "$(SCRIPT_INSTALL_DIR)" >NUL 1656 1657default-install-pdbs: 1658 @echo Installing PDBs to '$(LIB_INSTALL_DIR)' 1659 @if not exist "$(LIB_INSTALL_DIR)" mkdir "$(LIB_INSTALL_DIR)" 1660 @$(CPY) "$(OUT_DIR)\*.pdb" "$(LIB_INSTALL_DIR)\" 1661 1662# "emacs font-lock highlighting fix 1663 1664default-install-docs-html: 1665 @echo Installing documentation files to '$(DOC_INSTALL_DIR)' 1666 @if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)" 1667 @if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.html" "$(DOCDIR)\*.css" "$(DOCDIR)\*.png") do @$(COPY) %f "$(DOC_INSTALL_DIR)" 1668 1669default-install-docs-n: 1670 @echo Installing documentation files to '$(DOC_INSTALL_DIR)' 1671 @if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)" 1672 @if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.n") do @$(COPY) %f "$(DOC_INSTALL_DIR)" 1673 1674default-install-demos: 1675 @echo Installing demos to '$(DEMO_INSTALL_DIR)' 1676 @if not exist "$(DEMO_INSTALL_DIR)" mkdir "$(DEMO_INSTALL_DIR)" 1677 @if exist $(DEMODIR) $(CPYDIR) "$(DEMODIR)" "$(DEMO_INSTALL_DIR)" 1678 1679default-clean: 1680 @echo Cleaning $(TMP_DIR)\* ... 1681 @if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR) 1682 @echo Cleaning $(WIN_DIR)\nmakehlp.obj, nmakehlp.exe ... 1683 @if exist $(WIN_DIR)\nmakehlp.obj del $(WIN_DIR)\nmakehlp.obj 1684 @if exist $(WIN_DIR)\nmakehlp.exe del $(WIN_DIR)\nmakehlp.exe 1685 @if exist $(WIN_DIR)\nmakehlp.out del $(WIN_DIR)\nmakehlp.out 1686 @echo Cleaning $(WIN_DIR)\nmhlp-out.txt ... 1687 @if exist $(WIN_DIR)\nmhlp-out.txt del $(WIN_DIR)\nmhlp-out.txt 1688 @echo Cleaning $(WIN_DIR)\_junk.pch ... 1689 @if exist $(WIN_DIR)\_junk.pch del $(WIN_DIR)\_junk.pch 1690 @echo Cleaning $(WIN_DIR)\vercl.x, vercl.i ... 1691 @if exist $(WIN_DIR)\vercl.x del $(WIN_DIR)\vercl.x 1692 @if exist $(WIN_DIR)\vercl.i del $(WIN_DIR)\vercl.i 1693 @echo Cleaning $(WIN_DIR)\versions.vc, version.vc ... 1694 @if exist $(WIN_DIR)\versions.vc del $(WIN_DIR)\versions.vc 1695 @if exist $(WIN_DIR)\version.vc del $(WIN_DIR)\version.vc 1696 1697default-hose: default-clean 1698 @echo Hosing $(OUT_DIR)\* ... 1699 @if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR) 1700 1701# Only for backward compatibility 1702default-distclean: default-hose 1703 1704default-setup: 1705 @if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR) 1706 @if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR) 1707 1708!if "$(TESTPAT)" != "" 1709TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT) 1710!endif 1711 1712default-test: default-setup $(PROJECT) 1713 @set TCLLIBPATH=$(OUT_DIR:\=/) 1714 @if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)" 1715 cd "$(TESTDIR)" && $(DEBUGGER) $(TCLSH) all.tcl $(TESTFLAGS) 1716 1717default-shell: default-setup $(PROJECT) 1718 @set TCLLIBPATH=$(OUT_DIR:\=/) 1719 @if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)" 1720 $(DEBUGGER) $(TCLSH) 1721 1722# Generation of Windows version resource 1723!ifdef RCFILE 1724 1725# Note: don't use $** in below rule because there may be other dependencies 1726# and only the "main" rc must be passed to the resource compiler 1727$(TMP_DIR)\$(PROJECT).res: $(RCDIR)\$(PROJECT).rc 1728 $(RESCMD) $(RCDIR)\$(PROJECT).rc 1729 1730!else 1731 1732# If parent makefile has not defined a resource definition file, 1733# we will generate one from standard template. 1734$(TMP_DIR)\$(PROJECT).res: $(TMP_DIR)\$(PROJECT).rc 1735 1736$(TMP_DIR)\$(PROJECT).rc: 1737 @$(COPY) << $(TMP_DIR)\$(PROJECT).rc 1738#include <winver.h> 1739 1740VS_VERSION_INFO VERSIONINFO 1741 FILEVERSION COMMAVERSION 1742 PRODUCTVERSION COMMAVERSION 1743 FILEFLAGSMASK 0x3fL 1744#ifdef DEBUG 1745 FILEFLAGS VS_FF_DEBUG 1746#else 1747 FILEFLAGS 0x0L 1748#endif 1749 FILEOS VOS_NT_WINDOWS32 1750 FILETYPE VFT_DLL 1751 FILESUBTYPE 0x0L 1752BEGIN 1753 BLOCK "StringFileInfo" 1754 BEGIN 1755 BLOCK "040904b0" 1756 BEGIN 1757 VALUE "FileDescription", "Tcl extension " PROJECT 1758 VALUE "OriginalFilename", PRJLIBNAME 1759 VALUE "FileVersion", DOTVERSION 1760 VALUE "ProductName", "Package " PROJECT " for Tcl" 1761 VALUE "ProductVersion", DOTVERSION 1762 END 1763 END 1764 BLOCK "VarFileInfo" 1765 BEGIN 1766 VALUE "Translation", 0x409, 1200 1767 END 1768END 1769 1770<< 1771 1772!endif # ifdef RCFILE 1773 1774!ifndef DISABLE_IMPLICIT_RULES 1775DISABLE_IMPLICIT_RULES = 0 1776!endif 1777 1778!if !$(DISABLE_IMPLICIT_RULES) 1779# Implicit rule definitions - only for building library objects. For stubs and 1780# main application, the makefile should define explicit rules. 1781 1782{$(ROOT)}.c{$(TMP_DIR)}.obj:: 1783 $(CCPKGCMD) @<< 1784$< 1785<< 1786 1787{$(WIN_DIR)}.c{$(TMP_DIR)}.obj:: 1788 $(CCPKGCMD) @<< 1789$< 1790<< 1791 1792{$(GENERICDIR)}.c{$(TMP_DIR)}.obj:: 1793 $(CCPKGCMD) @<< 1794$< 1795<< 1796 1797{$(COMPATDIR)}.c{$(TMP_DIR)}.obj:: 1798 $(CCPKGCMD) @<< 1799$< 1800<< 1801 1802{$(RCDIR)}.rc{$(TMP_DIR)}.res: 1803 $(RESCMD) $< 1804 1805{$(WIN_DIR)}.rc{$(TMP_DIR)}.res: 1806 $(RESCMD) $< 1807 1808{$(TMP_DIR)}.rc{$(TMP_DIR)}.res: 1809 $(RESCMD) $< 1810 1811.SUFFIXES: 1812.SUFFIXES:.c .rc 1813 1814!endif 1815 1816################################################################ 1817# 14. Sanity check selected options against Tcl build options 1818# When building an extension, certain configuration options should 1819# match the ones used when Tcl was built. Here we check and 1820# warn on a mismatch. 1821!if !$(DOING_TCL) 1822 1823!if $(TCLINSTALL) # Building against an installed Tcl 1824!if exist("$(_TCLDIR)\lib\nmake\tcl.nmake") 1825TCLNMAKECONFIG = "$(_TCLDIR)\lib\nmake\tcl.nmake" 1826!endif 1827!else # !$(TCLINSTALL) - building against Tcl source 1828!if exist("$(_TCLDIR)\win\$(BUILDDIRTOP)\tcl.nmake") 1829TCLNMAKECONFIG = "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcl.nmake" 1830!endif 1831!endif # TCLINSTALL 1832 1833!if $(CONFIG_CHECK) 1834!ifdef TCLNMAKECONFIG 1835!include $(TCLNMAKECONFIG) 1836 1837!if defined(CORE_MACHINE) && "$(CORE_MACHINE)" != "$(MACHINE)" 1838!error ERROR: Build target ($(MACHINE)) does not match the Tcl library architecture ($(CORE_MACHINE)). 1839!endif 1840!if $(TCL_VERSION) < 87 && defined(CORE_USE_THREAD_ALLOC) && $(CORE_USE_THREAD_ALLOC) != $(USE_THREAD_ALLOC) 1841!message WARNING: Value of USE_THREAD_ALLOC ($(USE_THREAD_ALLOC)) does not match its Tcl core value ($(CORE_USE_THREAD_ALLOC)). 1842!endif 1843!if defined(CORE_DEBUG) && $(CORE_DEBUG) != $(DEBUG) 1844!message WARNING: Value of DEBUG ($(DEBUG)) does not match its Tcl library configuration ($(DEBUG)). 1845!endif 1846!endif 1847 1848!endif # TCLNMAKECONFIG 1849 1850!endif # !$(DOING_TCL) 1851 1852 1853#---------------------------------------------------------- 1854# Display stats being used. 1855#---------------------------------------------------------- 1856 1857!if !$(DOING_TCL) 1858!message *** Building against Tcl at '$(_TCLDIR)' 1859!endif 1860!if !$(DOING_TK) && $(NEED_TK) 1861!message *** Building against Tk at '$(_TKDIR)' 1862!endif 1863!message *** Intermediate directory will be '$(TMP_DIR)' 1864!message *** Output directory will be '$(OUT_DIR)' 1865!message *** Installation, if selected, will be in '$(_INSTALLDIR)' 1866!message *** Suffix for binaries will be '$(SUFX)' 1867!message *** Compiler version $(VCVER). Target $(MACHINE), host $(NATIVE_ARCH). 1868 1869!endif # ifdef _RULES_VC 1870