1723 lines
53 KiB
Makefile
1723 lines
53 KiB
Makefile
#------------------------------------------------------------- -*- makefile -*-
|
|
# rules.vc --
|
|
#
|
|
# Part of the nmake based build system for Tcl and its extensions.
|
|
# This file does all the hard work in terms of parsing build options,
|
|
# compiler switches, defining common targets and macros. The Tcl makefile
|
|
# directly includes this. Extensions include it via "rules-ext.vc".
|
|
#
|
|
# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
|
|
# detailed documentation.
|
|
#
|
|
# See the file "license.terms" for information on usage and redistribution
|
|
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
|
#
|
|
# Copyright (c) 2001-2003 David Gravereaux.
|
|
# Copyright (c) 2003-2008 Patrick Thoyts
|
|
# Copyright (c) 2017 Ashok P. Nadkarni
|
|
#------------------------------------------------------------------------------
|
|
|
|
!ifndef _RULES_VC
|
|
_RULES_VC = 1
|
|
|
|
# The following macros define the version of the rules.vc nmake build system
|
|
# For modifications that are not backward-compatible, you *must* change
|
|
# the major version.
|
|
RULES_VERSION_MAJOR = 1
|
|
RULES_VERSION_MINOR = 0
|
|
|
|
# The PROJECT macro must be defined by parent makefile.
|
|
!if "$(PROJECT)" == ""
|
|
!error *** Error: Macro PROJECT not defined! Please define it before including rules.vc
|
|
!endif
|
|
|
|
!if "$(PRJ_PACKAGE_TCLNAME)" == ""
|
|
PRJ_PACKAGE_TCLNAME = $(PROJECT)
|
|
!endif
|
|
|
|
# Also special case Tcl and Tk to save some typing later
|
|
DOING_TCL = 0
|
|
DOING_TK = 0
|
|
!if "$(PROJECT)" == "tcl"
|
|
DOING_TCL = 1
|
|
!elseif "$(PROJECT)" == "tk"
|
|
DOING_TK = 1
|
|
!endif
|
|
|
|
!ifndef NEED_TK
|
|
# Backwards compatibility
|
|
!ifdef PROJECT_REQUIRES_TK
|
|
NEED_TK = $(PROJECT_REQUIRES_TK)
|
|
!else
|
|
NEED_TK = 0
|
|
!endif
|
|
!endif
|
|
|
|
!ifndef NEED_TCL_SOURCE
|
|
NEED_TCL_SOURCE = 0
|
|
!endif
|
|
|
|
!ifdef NEED_TK_SOURCE
|
|
!if $(NEED_TK_SOURCE)
|
|
NEED_TK = 1
|
|
!endif
|
|
!else
|
|
NEED_TK_SOURCE = 0
|
|
!endif
|
|
|
|
################################################################
|
|
# Nmake is a pretty weak environment in syntax and capabilities
|
|
# so this file is necessarily verbose. It's broken down into
|
|
# the following parts.
|
|
#
|
|
# 0. Sanity check that compiler environment is set up and initialize
|
|
# any built-in settings from the parent makefile
|
|
# 1. First define the external tools used for compiling, copying etc.
|
|
# as this is independent of everything else.
|
|
# 2. Figure out our build structure in terms of the directory, whether
|
|
# we are building Tcl or an extension, etc.
|
|
# 3. Determine the compiler and linker versions
|
|
# 4. Build the nmakehlp helper application
|
|
# 5. Determine the supported compiler options and features
|
|
# 6. Parse the OPTS macro value for user-specified build configuration
|
|
# 7. Parse the STATS macro value for statistics instrumentation
|
|
# 8. Parse the CHECKS macro for additional compilation checks
|
|
# 9. Extract Tcl, and possibly Tk, version numbers from the headers
|
|
# 10. Based on this selected configuration, construct the output
|
|
# directory and file paths
|
|
# 11. Construct the paths where the package is to be installed
|
|
# 12. Set up the actual options passed to compiler and linker based
|
|
# on the information gathered above.
|
|
# 13. Define some standard build targets and implicit rules. These may
|
|
# be optionally disabled by the parent makefile.
|
|
# 14. (For extensions only.) Compare the configuration of the target
|
|
# Tcl and the extensions and warn against discrepancies.
|
|
#
|
|
# One final note about the macro names used. They are as they are
|
|
# for historical reasons. We would like legacy extensions to
|
|
# continue to work with this make include file so be wary of
|
|
# changing them for consistency or clarity.
|
|
|
|
# 0. Sanity check compiler environment
|
|
|
|
# Check to see we are configured to build with MSVC (MSDEVDIR, MSVCDIR or
|
|
# VCINSTALLDIR) or with the MS Platform SDK (MSSDK or WindowsSDKDir)
|
|
|
|
!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(VCINSTALLDIR) && !defined(MSSDK) && !defined(WINDOWSSDKDIR)
|
|
MSG = ^
|
|
Visual C++ compiler environment not initialized.
|
|
!error $(MSG)
|
|
!endif
|
|
|
|
# We need to run from the directory the parent makefile is located in.
|
|
# nmake does not tell us what makefile was used to invoke it so parent
|
|
# makefile has to set the MAKEFILEVC macro or we just make a guess and
|
|
# warn if we think that is not the case.
|
|
!if "$(MAKEFILEVC)" == ""
|
|
|
|
!if exist("$(PROJECT).vc")
|
|
MAKEFILEVC = $(PROJECT).vc
|
|
!elseif exist("makefile.vc")
|
|
MAKEFILEVC = makefile.vc
|
|
!endif
|
|
!endif # "$(MAKEFILEVC)" == ""
|
|
|
|
!if !exist("$(MAKEFILEVC)")
|
|
MSG = ^
|
|
You must run nmake from the directory containing the project makefile.^
|
|
If you are doing that and getting this message, set the MAKEFILEVC^
|
|
macro to the name of the project makefile.
|
|
!message WARNING: $(MSG)
|
|
!endif
|
|
|
|
|
|
################################################################
|
|
# 1. Define external programs being used
|
|
|
|
#----------------------------------------------------------
|
|
# Set the proper copy method to avoid overwrite questions
|
|
# to the user when copying files and selecting the right
|
|
# "delete all" method.
|
|
#----------------------------------------------------------
|
|
|
|
RMDIR = rmdir /S /Q
|
|
CPY = xcopy /i /y >NUL
|
|
CPYDIR = xcopy /e /i /y >NUL
|
|
COPY = copy /y >NUL
|
|
MKDIR = mkdir
|
|
|
|
######################################################################
|
|
# 2. Figure out our build environment in terms of what we're building.
|
|
#
|
|
# (a) Tcl itself
|
|
# (b) Tk
|
|
# (c) a Tcl extension using libraries/includes from an *installed* Tcl
|
|
# (d) a Tcl extension using libraries/includes from Tcl source directory
|
|
#
|
|
# This last is needed because some extensions still need
|
|
# some Tcl interfaces that are not publicly exposed.
|
|
#
|
|
# The fragment will set the following macros:
|
|
# ROOT - root of this module sources
|
|
# COMPATDIR - source directory that holds compatibility sources
|
|
# DOCDIR - source directory containing documentation files
|
|
# GENERICDIR - platform-independent source directory
|
|
# WINDIR - Windows-specific source directory
|
|
# TESTDIR - directory containing test files
|
|
# TOOLSDIR - directory containing build tools
|
|
# _TCLDIR - root of the Tcl installation OR the Tcl sources. Not set
|
|
# when building Tcl itself.
|
|
# _INSTALLDIR - native form of the installation path. For Tcl
|
|
# this will be the root of the Tcl installation. For extensions
|
|
# this will be the lib directory under the root.
|
|
# TCLINSTALL - set to 1 if _TCLDIR refers to
|
|
# headers and libraries from an installed Tcl, and 0 if built against
|
|
# Tcl sources. Not set when building Tcl itself. Yes, not very well
|
|
# named.
|
|
# _TCL_H - native path to the tcl.h file
|
|
#
|
|
# If Tk is involved, also sets the following
|
|
# _TKDIR - native form Tk installation OR Tk source. Not set if building
|
|
# Tk itself.
|
|
# TKINSTALL - set 1 if _TKDIR refers to installed Tk and 0 if Tk sources
|
|
# _TK_H - native path to the tk.h file
|
|
|
|
# Root directory for sources and assumed subdirectories
|
|
ROOT = $(MAKEDIR)\..
|
|
# The following paths CANNOT have spaces in them as they appear on the
|
|
# left side of implicit rules.
|
|
!ifndef COMPATDIR
|
|
COMPATDIR = $(ROOT)\compat
|
|
!endif
|
|
!ifndef DOCDIR
|
|
DOCDIR = $(ROOT)\doc
|
|
!endif
|
|
!ifndef GENERICDIR
|
|
GENERICDIR = $(ROOT)\generic
|
|
!endif
|
|
!ifndef TOOLSDIR
|
|
TOOLSDIR = $(ROOT)\tools
|
|
!endif
|
|
!ifndef TESTDIR
|
|
TESTDIR = $(ROOT)\tests
|
|
!endif
|
|
!ifndef LIBDIR
|
|
!if exist("$(ROOT)\library")
|
|
LIBDIR = $(ROOT)\library
|
|
!else
|
|
LIBDIR = $(ROOT)\lib
|
|
!endif
|
|
!endif
|
|
!ifndef DEMODIR
|
|
!if exist("$(LIBDIR)\demos")
|
|
DEMODIR = $(LIBDIR)\demos
|
|
!else
|
|
DEMODIR = $(ROOT)\demos
|
|
!endif
|
|
!endif # ifndef DEMODIR
|
|
# Do NOT enclose WINDIR in a !ifndef because Windows always defines
|
|
# WINDIR env var to point to c:\windows!
|
|
# TBD - This is a potentially dangerous conflict, rename WINDIR to
|
|
# something else
|
|
WINDIR = $(ROOT)\win
|
|
|
|
!ifndef RCDIR
|
|
!if exist("$(WINDIR)\rc")
|
|
RCDIR = $(WINDIR)\rc
|
|
!else
|
|
RCDIR = $(WINDIR)
|
|
!endif
|
|
!endif
|
|
RCDIR = $(RCDIR:/=\)
|
|
|
|
# The target directory where the built packages and binaries will be installed.
|
|
# INSTALLDIR is the (optional) path specified by the user.
|
|
# _INSTALLDIR is INSTALLDIR using the backslash separator syntax
|
|
!ifdef INSTALLDIR
|
|
### Fix the path separators.
|
|
_INSTALLDIR = $(INSTALLDIR:/=\)
|
|
!else
|
|
### Assume the normal default.
|
|
_INSTALLDIR = $(HOMEDRIVE)\Tcl
|
|
!endif
|
|
|
|
!if $(DOING_TCL)
|
|
|
|
# BEGIN Case 2(a) - Building Tcl itself
|
|
|
|
# Only need to define _TCL_H
|
|
_TCL_H = ..\generic\tcl.h
|
|
|
|
# END Case 2(a) - Building Tcl itself
|
|
|
|
!elseif $(DOING_TK)
|
|
|
|
# BEGIN Case 2(b) - Building Tk
|
|
|
|
TCLINSTALL = 0 # Tk always builds against Tcl source, not an installed Tcl
|
|
!if "$(TCLDIR)" == ""
|
|
!if [echo TCLDIR = \> nmakehlp.out] \
|
|
|| [nmakehlp -L generic\tcl.h >> nmakehlp.out]
|
|
!error *** Could not locate Tcl source directory.
|
|
!endif
|
|
!include nmakehlp.out
|
|
!endif # TCLDIR == ""
|
|
|
|
_TCLDIR = $(TCLDIR:/=\)
|
|
_TCL_H = $(_TCLDIR)\generic\tcl.h
|
|
!if !exist("$(_TCL_H)")
|
|
!error Could not locate tcl.h. Please set the TCLDIR macro to point to the Tcl *source* directory.
|
|
!endif
|
|
|
|
_TK_H = ..\generic\tk.h
|
|
|
|
# END Case 2(b) - Building Tk
|
|
|
|
!else
|
|
|
|
# BEGIN Case 2(c) or (d) - Building an extension other than Tk
|
|
|
|
# If command line has specified Tcl location through TCLDIR, use it
|
|
# else default to the INSTALLDIR setting
|
|
!if "$(TCLDIR)" != ""
|
|
|
|
_TCLDIR = $(TCLDIR:/=\)
|
|
!if exist("$(_TCLDIR)\include\tcl.h") # Case 2(c) with TCLDIR defined
|
|
TCLINSTALL = 1
|
|
_TCL_H = $(_TCLDIR)\include\tcl.h
|
|
!elseif exist("$(_TCLDIR)\generic\tcl.h") # Case 2(d) with TCLDIR defined
|
|
TCLINSTALL = 0
|
|
_TCL_H = $(_TCLDIR)\generic\tcl.h
|
|
!endif
|
|
|
|
!else # # Case 2(c) for extensions with TCLDIR undefined
|
|
|
|
# Need to locate Tcl depending on whether it needs Tcl source or not.
|
|
# If we don't, check the INSTALLDIR for an installed Tcl first
|
|
|
|
!if exist("$(_INSTALLDIR)\include\tcl.h") && !$(NEED_TCL_SOURCE)
|
|
|
|
TCLINSTALL = 1
|
|
TCLDIR = $(_INSTALLDIR)\..
|
|
# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
|
|
# later so the \.. accounts for the /lib
|
|
_TCLDIR = $(_INSTALLDIR)\..
|
|
_TCL_H = $(_TCLDIR)\include\tcl.h
|
|
|
|
!else # exist(...) && ! $(NEED_TCL_SOURCE)
|
|
|
|
!if [echo _TCLDIR = \> nmakehlp.out] \
|
|
|| [nmakehlp -L generic\tcl.h >> nmakehlp.out]
|
|
!error *** Could not locate Tcl source directory.
|
|
!endif
|
|
!include nmakehlp.out
|
|
TCLINSTALL = 0
|
|
TCLDIR = $(_TCLDIR)
|
|
_TCL_H = $(_TCLDIR)\generic\tcl.h
|
|
|
|
!endif # exist(...) && ! $(NEED_TCL_SOURCE)
|
|
|
|
!endif # TCLDIR
|
|
|
|
!ifndef _TCL_H
|
|
MSG =^
|
|
Failed to find tcl.h. The TCLDIR macro is set incorrectly or is not set and default path does not contain tcl.h.
|
|
!error $(MSG)
|
|
!endif
|
|
|
|
# Now do the same to locate Tk headers and libs if project requires Tk
|
|
!if $(NEED_TK)
|
|
|
|
!if "$(TKDIR)" != ""
|
|
|
|
_TKDIR = $(TKDIR:/=\)
|
|
!if exist("$(_TKDIR)\include\tk.h")
|
|
TKINSTALL = 1
|
|
_TK_H = $(_TKDIR)\include\tk.h
|
|
!elseif exist("$(_TKDIR)\generic\tk.h")
|
|
TKINSTALL = 0
|
|
_TK_H = $(_TKDIR)\generic\tk.h
|
|
!endif
|
|
|
|
!else # TKDIR not defined
|
|
|
|
# Need to locate Tcl depending on whether it needs Tcl source or not.
|
|
# If we don't, check the INSTALLDIR for an installed Tcl first
|
|
|
|
!if exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
|
|
|
|
TKINSTALL = 1
|
|
# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
|
|
# later so the \.. accounts for the /lib
|
|
_TKDIR = $(_INSTALLDIR)\..
|
|
_TK_H = $(_TKDIR)\include\tk.h
|
|
TKDIR = $(_TKDIR)
|
|
|
|
!else # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
|
|
|
|
!if [echo _TKDIR = \> nmakehlp.out] \
|
|
|| [nmakehlp -L generic\tk.h >> nmakehlp.out]
|
|
!error *** Could not locate Tk source directory.
|
|
!endif
|
|
!include nmakehlp.out
|
|
TKINSTALL = 0
|
|
TKDIR = $(_TKDIR)
|
|
_TK_H = $(_TKDIR)\generic\tk.h
|
|
|
|
!endif # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
|
|
|
|
!endif # TKDIR
|
|
|
|
!ifndef _TK_H
|
|
MSG =^
|
|
Failed to find tk.h. The TKDIR macro is set incorrectly or is not set and default path does not contain tk.h.
|
|
!error $(MSG)
|
|
!endif
|
|
|
|
!endif # NEED_TK
|
|
|
|
!if $(NEED_TCL_SOURCE) && $(TCLINSTALL)
|
|
MSG = ^
|
|
*** Warning: This extension requires the source distribution of Tcl.^
|
|
*** Please set the TCLDIR macro to point to the Tcl sources.
|
|
!error $(MSG)
|
|
!endif
|
|
|
|
!if $(NEED_TK_SOURCE)
|
|
!if $(TKINSTALL)
|
|
MSG = ^
|
|
*** Warning: This extension requires the source distribution of Tk.^
|
|
*** Please set the TKDIR macro to point to the Tk sources.
|
|
!error $(MSG)
|
|
!endif
|
|
!endif
|
|
|
|
|
|
# If INSTALLDIR set to tcl installation root dir then reset to the
|
|
# lib dir for installing extensions
|
|
!if exist("$(_INSTALLDIR)\include\tcl.h")
|
|
_INSTALLDIR=$(_INSTALLDIR)\lib
|
|
!endif
|
|
|
|
# END Case 2(c) or (d) - Building an extension
|
|
!endif # if $(DOING_TCL)
|
|
|
|
################################################################
|
|
# 3. Determine compiler version and architecture
|
|
# In this section, we figure out the compiler version and the
|
|
# architecture for which we are building. This sets the
|
|
# following macros:
|
|
# VCVERSION - the internal compiler version as 1200, 1400, 1910 etc.
|
|
# This is also printed by the compiler in dotted form 19.10 etc.
|
|
# VCVER - the "marketing version", for example Visual C++ 6 for internal
|
|
# compiler version 1200. This is kept only for legacy reasons as it
|
|
# does not make sense for recent Microsoft compilers. Only used for
|
|
# output directory names.
|
|
# ARCH - set to IX86 or AMD64 depending on 32- or 64-bit target
|
|
# NATIVE_ARCH - set to IX86 or AMD64 for the host machine
|
|
# MACHINE - same as $(ARCH) - legacy
|
|
# _VC_MANIFEST_EMBED_{DLL,EXE} - commands for embedding a manifest if needed
|
|
# CFG_ENCODING - set to an character encoding.
|
|
# TBD - this is passed to compiler as TCL_CFGVAL_ENCODING but can't
|
|
# see where it is used
|
|
|
|
cc32 = $(CC) # built-in default.
|
|
link32 = link
|
|
lib32 = lib
|
|
rc32 = $(RC) # built-in default.
|
|
|
|
#----------------------------------------------------------------
|
|
# Figure out the compiler architecture and version by writing
|
|
# the C macros to a file, preprocessing them with the C
|
|
# preprocessor and reading back the created file
|
|
|
|
_HASH=^#
|
|
_VC_MANIFEST_EMBED_EXE=
|
|
_VC_MANIFEST_EMBED_DLL=
|
|
VCVER=0
|
|
!if ![echo VCVERSION=_MSC_VER > vercl.x] \
|
|
&& ![echo $(_HASH)if defined(_M_IX86) >> vercl.x] \
|
|
&& ![echo ARCH=IX86 >> vercl.x] \
|
|
&& ![echo $(_HASH)elif defined(_M_AMD64) >> vercl.x] \
|
|
&& ![echo ARCH=AMD64 >> vercl.x] \
|
|
&& ![echo $(_HASH)endif >> vercl.x] \
|
|
&& ![$(cc32) -nologo -TC -P vercl.x 2>NUL]
|
|
!include vercl.i
|
|
!if $(VCVERSION) < 1900
|
|
!if ![echo VCVER= ^\> vercl.vc] \
|
|
&& ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc]
|
|
!include vercl.vc
|
|
!endif
|
|
!else
|
|
# The simple calculation above does not apply to new Visual Studio releases
|
|
# Keep the compiler version in its native form.
|
|
VCVER = $(VCVERSION)
|
|
!endif
|
|
!endif
|
|
|
|
!if ![del 2>NUL /q/f vercl.x vercl.i vercl.vc]
|
|
!endif
|
|
|
|
#----------------------------------------------------------------
|
|
# The MACHINE macro is used by legacy makefiles so set it as well
|
|
!ifdef MACHINE
|
|
!if "$(MACHINE)" == "x86"
|
|
!undef MACHINE
|
|
MACHINE = IX86
|
|
!elseif "$(MACHINE)" == "x64"
|
|
!undef MACHINE
|
|
MACHINE = AMD64
|
|
!endif
|
|
!if "$(MACHINE)" != "$(ARCH)"
|
|
!error Specified MACHINE macro $(MACHINE) does not match detected target architecture $(ARCH).
|
|
!endif
|
|
!else
|
|
MACHINE=$(ARCH)
|
|
!endif
|
|
|
|
#------------------------------------------------------------
|
|
# Figure out the *host* architecture by reading the registry
|
|
|
|
!if ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i x86]
|
|
NATIVE_ARCH=IX86
|
|
!else
|
|
NATIVE_ARCH=AMD64
|
|
!endif
|
|
|
|
# Since MSVC8 we must deal with manifest resources.
|
|
!if $(VCVERSION) >= 1400
|
|
_VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1
|
|
_VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
|
|
!endif
|
|
|
|
!ifndef CFG_ENCODING
|
|
CFG_ENCODING = \"cp1252\"
|
|
!endif
|
|
|
|
################################################################
|
|
# 4. Build the nmakehlp program
|
|
# This is a helper app we need to overcome nmake's limiting
|
|
# environment. We will call out to it to get various bits of
|
|
# information about supported compiler options etc.
|
|
#
|
|
# Tcl itself will always use the nmakehlp.c program which is
|
|
# in its own source. This is the "master" copy and kept updated.
|
|
#
|
|
# Extensions built against an installed Tcl will use the installed
|
|
# copy of Tcl's nmakehlp.c if there is one and their own version
|
|
# otherwise. In the latter case, they would also be using their own
|
|
# rules.vc. Note that older versions of Tcl do not install nmakehlp.c
|
|
# or rules.vc.
|
|
#
|
|
# Extensions built against Tcl sources will use the one from the Tcl source.
|
|
#
|
|
# When building an extension using a sufficiently new version of Tcl,
|
|
# rules-ext.vc will define NMAKEHLPC appropriately to point to the
|
|
# copy of nmakehlp.c to be used.
|
|
|
|
!ifndef NMAKEHLPC
|
|
# Default to the one in the current directory (the extension's own nmakehlp.c)
|
|
NMAKEHLPC = nmakehlp.c
|
|
|
|
!if !$(DOING_TCL)
|
|
!if $(TCLINSTALL)
|
|
!if exist("$(_TCLDIR)\lib\nmake\nmakehlp.c")
|
|
NMAKEHLPC = $(_TCLDIR)\lib\nmake\nmakehlp.c
|
|
!endif
|
|
!else # ! $(TCLINSTALL)
|
|
!if exist("$(_TCLDIR)\win\nmakehlp.c")
|
|
NMAKEHLPC = $(_TCLDIR)\win\nmakehlp.c
|
|
!endif
|
|
!endif # $(TCLINSTALL)
|
|
!endif # !$(DOING_TCL)
|
|
|
|
!endif # NMAKEHLPC
|
|
|
|
# We always build nmakehlp even if it exists since we do not know
|
|
# what source it was built from.
|
|
!message *** Using $(NMAKEHLPC)
|
|
!if [$(cc32) -nologo "$(NMAKEHLPC)" -link -subsystem:console > nul]
|
|
!endif
|
|
|
|
################################################################
|
|
# 5. Test for compiler features
|
|
# Visual C++ compiler options have changed over the years. Check
|
|
# which options are supported by the compiler in use.
|
|
#
|
|
# The following macros are set:
|
|
# OPTIMIZATIONS - the compiler flags to be used for optimized builds
|
|
# DEBUGFLAGS - the compiler flags to be used for debug builds
|
|
# LINKERFLAGS - Flags passed to the linker
|
|
#
|
|
# Note that these are the compiler settings *available*, not those
|
|
# that will be *used*. The latter depends on the OPTS macro settings
|
|
# which we have not yet parsed.
|
|
#
|
|
# Also note that some of the flags in OPTIMIZATIONS are not really
|
|
# related to optimization. They are placed there only for legacy reasons
|
|
# as some extensions expect them to be included in that macro.
|
|
|
|
# -Op improves float consistency. Note only needed for older compilers
|
|
# Newer compilers do not need or support this option.
|
|
!if [nmakehlp -c -Op]
|
|
FPOPTS = -Op
|
|
!endif
|
|
|
|
# Strict floating point semantics - present in newer compilers in lieu of -Op
|
|
!if [nmakehlp -c -fp:strict]
|
|
FPOPTS = $(FPOPTS) -fp:strict
|
|
!endif
|
|
|
|
!if "$(MACHINE)" == "IX86"
|
|
### test for pentium errata
|
|
!if [nmakehlp -c -QI0f]
|
|
!message *** Compiler has 'Pentium 0x0f fix'
|
|
FPOPTS = $(FPOPTS) -QI0f
|
|
!else
|
|
!message *** Compiler does not have 'Pentium 0x0f fix'
|
|
!endif
|
|
!endif
|
|
|
|
### test for optimizations
|
|
# /O2 optimization includes /Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy as per
|
|
# documentation. Note we do NOT want /Gs as that inserts a _chkstk
|
|
# stack probe at *every* function entry, not just those with more than
|
|
# a page of stack allocation resulting in a performance hit. However,
|
|
# /O2 documentation is misleading as its stack probes are simply the
|
|
# default page size locals allocation probes and not what is implied
|
|
# by an explicit /Gs option.
|
|
|
|
OPTIMIZATIONS = $(FPOPTS)
|
|
|
|
!if [nmakehlp -c -O2]
|
|
!message *** Compiler has 'Optimizations'
|
|
OPTIMIZING = 1
|
|
OPTIMIZATIONS = $(OPTIMIZATIONS) -O2
|
|
!else
|
|
# Legacy, really. All modern compilers support this
|
|
!message *** Compiler does not have 'Optimizations'
|
|
OPTIMIZING = 0
|
|
!endif
|
|
|
|
# Checks for buffer overflows in local arrays
|
|
!if [nmakehlp -c -GS]
|
|
OPTIMIZATIONS = $(OPTIMIZATIONS) -GS
|
|
!endif
|
|
|
|
# Link time optimization. Note that this option (potentially) makes
|
|
# generated libraries only usable by the specific VC++ version that
|
|
# created it. Requires /LTCG linker option
|
|
!if [nmakehlp -c -GL]
|
|
OPTIMIZATIONS = $(OPTIMIZATIONS) -GL
|
|
CC_GL_OPT_ENABLED = 1
|
|
!else
|
|
# In newer compilers -GL and -YX are incompatible.
|
|
!if [nmakehlp -c -YX]
|
|
OPTIMIZATIONS = $(OPTIMIZATIONS) -YX
|
|
!endif
|
|
!endif # [nmakehlp -c -GL]
|
|
|
|
DEBUGFLAGS = $(FPOPTS)
|
|
|
|
# Run time error checks. Not available or valid in a release, non-debug build
|
|
# RTC is for modern compilers, -GZ is legacy
|
|
!if [nmakehlp -c -RTC1]
|
|
DEBUGFLAGS = $(DEBUGFLAGS) -RTC1
|
|
!elseif [nmakehlp -c -GZ]
|
|
DEBUGFLAGS = $(DEBUGFLAGS) -GZ
|
|
!endif
|
|
|
|
#----------------------------------------------------------------
|
|
# Linker flags
|
|
|
|
# LINKER_TESTFLAGS are for internal use when we call nmakehlp to test
|
|
# if the linker supports a specific option. Without these flags link will
|
|
# return "LNK1561: entry point must be defined" error compiling from VS-IDE:
|
|
# They are not passed through to the actual application / extension
|
|
# link rules.
|
|
!ifndef LINKER_TESTFLAGS
|
|
LINKER_TESTFLAGS = /DLL /NOENTRY /OUT:nmakehlp.out
|
|
!endif
|
|
|
|
LINKERFLAGS =
|
|
|
|
# If compiler has enabled link time optimization, linker must too with -ltcg
|
|
!ifdef CC_GL_OPT_ENABLED
|
|
!if [nmakehlp -l -ltcg $(LINKER_TESTFLAGS)]
|
|
LINKERFLAGS = $(LINKERFLAGS) -ltcg
|
|
!endif
|
|
!endif
|
|
|
|
########################################################################
|
|
# 6. Parse the OPTS macro to work out the requested build configuration.
|
|
# Based on this, we will construct the actual switches to be passed to the
|
|
# compiler and linker using the macros defined in the previous section.
|
|
# The following macros are defined by this section based on OPTS
|
|
# STATIC_BUILD - 0 -> Tcl is to be built as a shared library
|
|
# 1 -> build as a static library and shell
|
|
# TCL_THREADS - legacy but always 1 on Windows since winsock requires it.
|
|
# DEBUG - 1 -> debug build, 0 -> release builds
|
|
# SYMBOLS - 1 -> generate PDB's, 0 -> no PDB's
|
|
# PROFILE - 1 -> generate profiling info, 0 -> no profiling
|
|
# PGO - 1 -> profile based optimization, 0 -> no
|
|
# MSVCRT - 1 -> link to dynamic C runtime even when building static Tcl build
|
|
# 0 -> link to static C runtime for static Tcl build.
|
|
# Does not impact shared Tcl builds (STATIC_BUILD == 0)
|
|
# TCL_USE_STATIC_PACKAGES - 1 -> statically link the registry and dde extensions
|
|
# in the Tcl shell. 0 -> keep them as shared libraries
|
|
# Does not impact shared Tcl builds.
|
|
# USE_THREAD_ALLOC - 1 -> Use a shared global free pool for allocation.
|
|
# 0 -> Use the non-thread allocator.
|
|
# UNCHECKED - 1 -> when doing a debug build with symbols, use the release
|
|
# C runtime, 0 -> use the debug C runtime.
|
|
# USE_STUBS - 1 -> compile to use stubs interfaces, 0 -> direct linking
|
|
# CONFIG_CHECK - 1 -> check current build configuration against Tcl
|
|
# configuration (ignored for Tcl itself)
|
|
# Further, LINKERFLAGS are modified based on above.
|
|
|
|
# Default values for all the above
|
|
STATIC_BUILD = 0
|
|
TCL_THREADS = 1
|
|
DEBUG = 0
|
|
SYMBOLS = 0
|
|
PROFILE = 0
|
|
PGO = 0
|
|
MSVCRT = 1
|
|
TCL_USE_STATIC_PACKAGES = 0
|
|
USE_THREAD_ALLOC = 1
|
|
UNCHECKED = 0
|
|
CONFIG_CHECK = 1
|
|
!if $(DOING_TCL)
|
|
USE_STUBS = 0
|
|
!else
|
|
USE_STUBS = 1
|
|
!endif
|
|
|
|
# If OPTS is not empty AND does not contain "none" which turns off all OPTS
|
|
# set the above macros based on OPTS content
|
|
!if "$(OPTS)" != "" && ![nmakehlp -f "$(OPTS)" "none"]
|
|
|
|
# OPTS are specified, parse them
|
|
|
|
!if [nmakehlp -f $(OPTS) "static"]
|
|
!message *** Doing static
|
|
STATIC_BUILD = 1
|
|
!endif
|
|
|
|
!if [nmakehlp -f $(OPTS) "nostubs"]
|
|
!message *** Not using stubs
|
|
USE_STUBS = 0
|
|
!endif
|
|
|
|
!if [nmakehlp -f $(OPTS) "nomsvcrt"]
|
|
!message *** Doing nomsvcrt
|
|
MSVCRT = 0
|
|
!else
|
|
!if [nmakehlp -f $(OPTS) "msvcrt"]
|
|
!message *** Doing msvcrt
|
|
MSVCRT = 1
|
|
!else
|
|
!if !$(STATIC_BUILD)
|
|
MSVCRT = 1
|
|
!else
|
|
MSVCRT = 0
|
|
!endif
|
|
!endif
|
|
!endif # [nmakehlp -f $(OPTS) "nomsvcrt"]
|
|
|
|
!if [nmakehlp -f $(OPTS) "staticpkg"] && $(STATIC_BUILD)
|
|
!message *** Doing staticpkg
|
|
TCL_USE_STATIC_PACKAGES = 1
|
|
!else
|
|
TCL_USE_STATIC_PACKAGES = 0
|
|
!endif
|
|
|
|
!if [nmakehlp -f $(OPTS) "nothreads"]
|
|
!message *** Compile explicitly for non-threaded tcl
|
|
TCL_THREADS = 0
|
|
USE_THREAD_ALLOC= 0
|
|
!else
|
|
TCL_THREADS = 1
|
|
USE_THREAD_ALLOC= 1
|
|
!endif
|
|
|
|
!if [nmakehlp -f $(OPTS) "symbols"]
|
|
!message *** Doing symbols
|
|
DEBUG = 1
|
|
!else
|
|
DEBUG = 0
|
|
!endif
|
|
|
|
!if [nmakehlp -f $(OPTS) "pdbs"]
|
|
!message *** Doing pdbs
|
|
SYMBOLS = 1
|
|
!else
|
|
SYMBOLS = 0
|
|
!endif
|
|
|
|
!if [nmakehlp -f $(OPTS) "profile"]
|
|
!message *** Doing profile
|
|
PROFILE = 1
|
|
!else
|
|
PROFILE = 0
|
|
!endif
|
|
|
|
!if [nmakehlp -f $(OPTS) "pgi"]
|
|
!message *** Doing profile guided optimization instrumentation
|
|
PGO = 1
|
|
!elseif [nmakehlp -f $(OPTS) "pgo"]
|
|
!message *** Doing profile guided optimization
|
|
PGO = 2
|
|
!else
|
|
PGO = 0
|
|
!endif
|
|
|
|
!if [nmakehlp -f $(OPTS) "loimpact"]
|
|
!message *** Warning: ignoring option "loimpact" - deprecated on modern Windows.
|
|
!endif
|
|
|
|
# TBD - should get rid of this option
|
|
!if [nmakehlp -f $(OPTS) "thrdalloc"]
|
|
!message *** Doing thrdalloc
|
|
USE_THREAD_ALLOC = 1
|
|
!endif
|
|
|
|
!if [nmakehlp -f $(OPTS) "tclalloc"]
|
|
USE_THREAD_ALLOC = 0
|
|
!endif
|
|
|
|
!if [nmakehlp -f $(OPTS) "unchecked"]
|
|
!message *** Doing unchecked
|
|
UNCHECKED = 1
|
|
!else
|
|
UNCHECKED = 0
|
|
!endif
|
|
|
|
!if [nmakehlp -f $(OPTS) "noconfigcheck"]
|
|
CONFIG_CHECK = 1
|
|
!else
|
|
CONFIG_CHECK = 0
|
|
!endif
|
|
|
|
!endif # "$(OPTS)" != "" && ... parsing of OPTS
|
|
|
|
# Set linker flags based on above
|
|
|
|
!if $(PGO) > 1
|
|
!if [nmakehlp -l -ltcg:pgoptimize $(LINKER_TESTFLAGS)]
|
|
LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pgoptimize
|
|
!else
|
|
MSG=^
|
|
This compiler does not support profile guided optimization.
|
|
!error $(MSG)
|
|
!endif
|
|
!elseif $(PGO) > 0
|
|
!if [nmakehlp -l -ltcg:pginstrument $(LINKER_TESTFLAGS)]
|
|
LINKERFLAGS = $(LINKERFLAGS:-ltcg=) -ltcg:pginstrument
|
|
!else
|
|
MSG=^
|
|
This compiler does not support profile guided optimization.
|
|
!error $(MSG)
|
|
!endif
|
|
!endif
|
|
|
|
################################################################
|
|
# 7. Parse the STATS macro to configure code instrumentation
|
|
# The following macros are set by this section:
|
|
# TCL_MEM_DEBUG - 1 -> enables memory allocation instrumentation
|
|
# 0 -> disables
|
|
# TCL_COMPILE_DEBUG - 1 -> enables byte compiler logging
|
|
# 0 -> disables
|
|
|
|
# Default both are off
|
|
TCL_MEM_DEBUG = 0
|
|
TCL_COMPILE_DEBUG = 0
|
|
|
|
!if "$(STATS)" != "" && ![nmakehlp -f "$(STATS)" "none"]
|
|
|
|
!if [nmakehlp -f $(STATS) "memdbg"]
|
|
!message *** Doing memdbg
|
|
TCL_MEM_DEBUG = 1
|
|
!else
|
|
TCL_MEM_DEBUG = 0
|
|
!endif
|
|
|
|
!if [nmakehlp -f $(STATS) "compdbg"]
|
|
!message *** Doing compdbg
|
|
TCL_COMPILE_DEBUG = 1
|
|
!else
|
|
TCL_COMPILE_DEBUG = 0
|
|
!endif
|
|
|
|
!endif
|
|
|
|
####################################################################
|
|
# 8. Parse the CHECKS macro to configure additional compiler checks
|
|
# The following macros are set by this section:
|
|
# WARNINGS - compiler switches that control the warnings level
|
|
# TCL_NO_DEPRECATED - 1 -> disable support for deprecated functions
|
|
# 0 -> enable deprecated functions
|
|
|
|
# Defaults - Permit deprecated functions and warning level 3
|
|
TCL_NO_DEPRECATED = 0
|
|
WARNINGS = -W3
|
|
|
|
!if "$(CHECKS)" != "" && ![nmakehlp -f "$(CHECKS)" "none"]
|
|
|
|
!if [nmakehlp -f $(CHECKS) "nodep"]
|
|
!message *** Doing nodep check
|
|
TCL_NO_DEPRECATED = 1
|
|
!endif
|
|
|
|
!if [nmakehlp -f $(CHECKS) "fullwarn"]
|
|
!message *** Doing full warnings check
|
|
WARNINGS = -W4
|
|
!if [nmakehlp -l -warn:3 $(LINKER_TESTFLAGS)]
|
|
LINKERFLAGS = $(LINKERFLAGS) -warn:3
|
|
!endif
|
|
!endif
|
|
|
|
!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]
|
|
!message *** Doing 64bit portability warnings
|
|
WARNINGS = $(WARNINGS) -Wp64
|
|
!endif
|
|
|
|
!endif
|
|
|
|
################################################################
|
|
# 9. Extract various version numbers
|
|
# For Tcl and Tk, version numbers are extracted from tcl.h and tk.h
|
|
# respectively. For extensions, versions are extracted from the
|
|
# configure.in or configure.ac from the TEA configuration if it
|
|
# exists, and unset otherwise.
|
|
# Sets the following macros:
|
|
# TCL_MAJOR_VERSION
|
|
# TCL_MINOR_VERSION
|
|
# TCL_PATCH_LEVEL
|
|
# TCL_VERSION
|
|
# TK_MAJOR_VERSION
|
|
# TK_MINOR_VERSION
|
|
# TK_PATCH_LEVEL
|
|
# TK_VERSION
|
|
# DOTVERSION - set as (for example) 2.5
|
|
# VERSION - set as (for example 25)
|
|
#--------------------------------------------------------------
|
|
|
|
!if [echo REM = This file is generated from rules.vc > versions.vc]
|
|
!endif
|
|
!if [echo TCL_MAJOR_VERSION = \>> versions.vc] \
|
|
&& [nmakehlp -V "$(_TCL_H)" TCL_MAJOR_VERSION >> versions.vc]
|
|
!endif
|
|
!if [echo TCL_MINOR_VERSION = \>> versions.vc] \
|
|
&& [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc]
|
|
!endif
|
|
!if [echo TCL_PATCH_LEVEL = \>> versions.vc] \
|
|
&& [nmakehlp -V "$(_TCL_H)" TCL_PATCH_LEVEL >> versions.vc]
|
|
!endif
|
|
|
|
!if defined(_TK_H)
|
|
!if [echo TK_MAJOR_VERSION = \>> versions.vc] \
|
|
&& [nmakehlp -V $(_TK_H) TK_MAJOR_VERSION >> versions.vc]
|
|
!endif
|
|
!if [echo TK_MINOR_VERSION = \>> versions.vc] \
|
|
&& [nmakehlp -V $(_TK_H) TK_MINOR_VERSION >> versions.vc]
|
|
!endif
|
|
!if [echo TK_PATCH_LEVEL = \>> versions.vc] \
|
|
&& [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc]
|
|
!endif
|
|
!endif # _TK_H
|
|
|
|
!include versions.vc
|
|
|
|
TCL_VERSION = $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
|
|
TCL_DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
|
|
!if defined(_TK_H)
|
|
TK_VERSION = $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)
|
|
TK_DOTVERSION = $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
|
|
!endif
|
|
|
|
# Set DOTVERSION and VERSION
|
|
!if $(DOING_TCL)
|
|
|
|
DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
|
|
VERSION = $(TCL_VERSION)
|
|
|
|
!elseif $(DOING_TK)
|
|
|
|
DOTVERSION = $(TK_DOTVERSION)
|
|
VERSION = $(TK_VERSION)
|
|
|
|
!else # Doing a non-Tk extension
|
|
|
|
# If parent makefile has not defined DOTVERSION, try to get it from TEA
|
|
# first from a configure.in file, and then from configure.ac
|
|
!ifndef DOTVERSION
|
|
!if [echo DOTVERSION = \> versions.vc] \
|
|
|| [nmakehlp -V $(ROOT)\configure.in ^[$(PROJECT)^] >> versions.vc]
|
|
!if [echo DOTVERSION = \> versions.vc] \
|
|
|| [nmakehlp -V $(ROOT)\configure.ac ^[$(PROJECT)^] >> versions.vc]
|
|
!error *** Could not figure out extension version. Please define DOTVERSION in parent makefile before including rules.vc.
|
|
!endif
|
|
!endif
|
|
!include versions.vc
|
|
!endif # DOTVERSION
|
|
VERSION = $(DOTVERSION:.=)
|
|
|
|
!endif # $(DOING_TCL) ... etc.
|
|
|
|
################################################################
|
|
# 10. Construct output directory and file paths
|
|
# Figure-out how to name our intermediate and output directories.
|
|
# In order to avoid inadvertent mixing of object files built using
|
|
# different compilers, build configurations etc.,
|
|
#
|
|
# Naming convention (suffixes):
|
|
# t = full thread support.
|
|
# s = static library (as opposed to an import library)
|
|
# g = linked to the debug enabled C run-time.
|
|
# x = special static build when it links to the dynamic C run-time.
|
|
#
|
|
# The following macros are set in this section:
|
|
# SUFX - the suffix to use for binaries based on above naming convention
|
|
# BUILDDIRTOP - the toplevel default output directory
|
|
# is of the form {Release,Debug}[_AMD64][_COMPILERVERSION]
|
|
# TMP_DIR - directory where object files are created
|
|
# OUT_DIR - directory where output executables are created
|
|
# Both TMP_DIR and OUT_DIR are defaulted only if not defined by the
|
|
# parent makefile (or command line). The default values are
|
|
# based on BUILDDIRTOP.
|
|
# STUBPREFIX - name of the stubs library for this project
|
|
# PRJIMPLIB - output path of the generated project import library
|
|
# PRJLIBNAME - name of generated project library
|
|
# PRJLIB - output path of generated project library
|
|
# PRJSTUBLIBNAME - name of the generated project stubs library
|
|
# PRJSTUBLIB - output path of the generated project stubs library
|
|
# RESFILE - output resource file (only if not static build)
|
|
|
|
SUFX = tsgx
|
|
|
|
!if $(DEBUG)
|
|
BUILDDIRTOP = Debug
|
|
!else
|
|
BUILDDIRTOP = Release
|
|
!endif
|
|
|
|
!if "$(MACHINE)" != "IX86"
|
|
BUILDDIRTOP =$(BUILDDIRTOP)_$(MACHINE)
|
|
!endif
|
|
!if $(VCVER) > 6
|
|
BUILDDIRTOP =$(BUILDDIRTOP)_VC$(VCVER)
|
|
!endif
|
|
|
|
!if !$(DEBUG) || $(DEBUG) && $(UNCHECKED)
|
|
SUFX = $(SUFX:g=)
|
|
!endif
|
|
|
|
TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX
|
|
|
|
!if !$(STATIC_BUILD)
|
|
TMP_DIRFULL = $(TMP_DIRFULL:Static=)
|
|
SUFX = $(SUFX:s=)
|
|
EXT = dll
|
|
TMP_DIRFULL = $(TMP_DIRFULL:X=)
|
|
SUFX = $(SUFX:x=)
|
|
!else
|
|
TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=)
|
|
EXT = lib
|
|
!if !$(MSVCRT)
|
|
TMP_DIRFULL = $(TMP_DIRFULL:X=)
|
|
SUFX = $(SUFX:x=)
|
|
!endif
|
|
!endif
|
|
|
|
!if !$(TCL_THREADS)
|
|
TMP_DIRFULL = $(TMP_DIRFULL:Threaded=)
|
|
SUFX = $(SUFX:t=)
|
|
!endif
|
|
|
|
!ifndef TMP_DIR
|
|
TMP_DIR = $(TMP_DIRFULL)
|
|
!ifndef OUT_DIR
|
|
OUT_DIR = .\$(BUILDDIRTOP)
|
|
!endif
|
|
!else
|
|
!ifndef OUT_DIR
|
|
OUT_DIR = $(TMP_DIR)
|
|
!endif
|
|
!endif
|
|
|
|
# Relative paths -> absolute
|
|
!if [echo OUT_DIR = \> nmakehlp.out] \
|
|
|| [nmakehlp -Q "$(OUT_DIR)" >> nmakehlp.out]
|
|
!error *** Could not fully qualify path OUT_DIR=$(OUT_DIR)
|
|
!endif
|
|
!if [echo TMP_DIR = \>> nmakehlp.out] \
|
|
|| [nmakehlp -Q "$(TMP_DIR)" >> nmakehlp.out]
|
|
!error *** Could not fully qualify path TMP_DIR=$(TMP_DIR)
|
|
!endif
|
|
!include nmakehlp.out
|
|
|
|
# The name of the stubs library for the project being built
|
|
STUBPREFIX = $(PROJECT)stub
|
|
|
|
# Set up paths to various Tcl executables and libraries needed by extensions
|
|
!if $(DOING_TCL)
|
|
|
|
TCLSHNAME = $(PROJECT)sh$(TCL_VERSION)$(SUFX).exe
|
|
TCLSH = $(OUT_DIR)\$(TCLSHNAME)
|
|
TCLIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
|
|
TCLLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
|
|
TCLLIB = $(OUT_DIR)\$(TCLLIBNAME)
|
|
|
|
TCLSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
|
|
TCLSTUBLIB = $(OUT_DIR)\$(TCLSTUBLIBNAME)
|
|
TCL_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
|
|
|
|
!else # ! $(DOING_TCL)
|
|
|
|
!if $(TCLINSTALL) # Building against an installed Tcl
|
|
|
|
TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe
|
|
!if !exist("$(TCLSH)") && $(TCL_THREADS)
|
|
TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe
|
|
!endif
|
|
TCLSTUBLIB = $(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib
|
|
TCLIMPLIB = $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib
|
|
TCL_LIBRARY = $(_TCLDIR)\lib
|
|
TCLREGLIB = $(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib
|
|
TCLDDELIB = $(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib
|
|
TCLTOOLSDIR = \must\have\tcl\sources\to\build\this\target
|
|
TCL_INCLUDES = -I"$(_TCLDIR)\include"
|
|
|
|
!else # Building against Tcl sources
|
|
|
|
TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe
|
|
!if !exist($(TCLSH)) && $(TCL_THREADS)
|
|
TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe
|
|
!endif
|
|
TCLSTUBLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib
|
|
TCLIMPLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib
|
|
TCL_LIBRARY = $(_TCLDIR)\library
|
|
TCLREGLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib
|
|
TCLDDELIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib
|
|
TCLTOOLSDIR = $(_TCLDIR)\tools
|
|
TCL_INCLUDES = -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
|
|
|
|
!endif # TCLINSTALL
|
|
|
|
tcllibs = "$(TCLSTUBLIB)" "$(TCLIMPLIB)"
|
|
|
|
!endif # $(DOING_TCL)
|
|
|
|
# We need a tclsh that will run on the host machine as part of the build.
|
|
# IX86 runs on all architectures.
|
|
!ifndef TCLSH_NATIVE
|
|
!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
|
|
TCLSH_NATIVE = $(TCLSH)
|
|
!else
|
|
!error You must explicitly set TCLSH_NATIVE for cross-compilation
|
|
!endif
|
|
!endif
|
|
|
|
# Do the same for Tk and Tk extensions that require the Tk libraries
|
|
!if $(DOING_TK) || $(NEED_TK)
|
|
WISHNAMEPREFIX = wish
|
|
WISHNAME = $(WISHNAMEPREFIX)$(TK_VERSION)$(SUFX).exe
|
|
TKLIBNAME = $(PROJECT)$(TK_VERSION)$(SUFX).$(EXT)
|
|
TKSTUBLIBNAME = tkstub$(TK_VERSION).lib
|
|
TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX).lib
|
|
|
|
!if $(DOING_TK)
|
|
WISH = $(OUT_DIR)\$(WISHNAME)
|
|
TKSTUBLIB = $(OUT_DIR)\$(TKSTUBLIBNAME)
|
|
TKIMPLIB = $(OUT_DIR)\$(TKIMPLIBNAME)
|
|
TKLIB = $(OUT_DIR)\$(TKLIBNAME)
|
|
TK_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)"
|
|
|
|
!else # effectively NEED_TK
|
|
|
|
!if $(TKINSTALL) # Building against installed Tk
|
|
WISH = $(_TKDIR)\bin\$(WISHNAME)
|
|
TKSTUBLIB = $(_TKDIR)\lib\$(TKSTUBLIBNAME)
|
|
TKIMPLIB = $(_TKDIR)\lib\$(TKIMPLIBNAME)
|
|
TK_INCLUDES = -I"$(_TKDIR)\include"
|
|
!else # Building against Tk sources
|
|
WISH = $(_TKDIR)\win\$(BUILDDIRTOP)\$(WISHNAME)
|
|
TKSTUBLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSTUBLIBNAME)
|
|
TKIMPLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
|
|
TK_INCLUDES = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
|
|
!endif # TKINSTALL
|
|
tklibs = "$(TKSTUBLIB)" "$(TKIMPLIB)"
|
|
|
|
!endif # $(DOING_TK)
|
|
!endif # $(DOING_TK) || $(NEED_TK)
|
|
|
|
# Various output paths
|
|
PRJIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
|
|
PRJLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT)
|
|
PRJLIB = $(OUT_DIR)\$(PRJLIBNAME)
|
|
|
|
PRJSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib
|
|
PRJSTUBLIB = $(OUT_DIR)\$(PRJSTUBLIBNAME)
|
|
|
|
# If extension parent makefile has not defined a resource definition file,
|
|
# we will generate one from standard template.
|
|
!if !$(DOING_TCL) && !$(DOING_TK) && !$(STATIC_BUILD)
|
|
!ifdef RCFILE
|
|
RESFILE = $(TMP_DIR)\$(RCFILE:.rc=.res)
|
|
!else
|
|
RESFILE = $(TMP_DIR)\$(PROJECT).res
|
|
!endif
|
|
!endif
|
|
|
|
###################################################################
|
|
# 11. Construct the paths for the installation directories
|
|
# The following macros get defined in this section:
|
|
# LIB_INSTALL_DIR - where libraries should be installed
|
|
# BIN_INSTALL_DIR - where the executables should be installed
|
|
# DOC_INSTALL_DIR - where documentation should be installed
|
|
# SCRIPT_INSTALL_DIR - where scripts should be installed
|
|
# INCLUDE_INSTALL_DIR - where C include files should be installed
|
|
# DEMO_INSTALL_DIR - where demos should be installed
|
|
# PRJ_INSTALL_DIR - where package will be installed (not set for tcl and tk)
|
|
|
|
!if $(DOING_TCL) || $(DOING_TK)
|
|
LIB_INSTALL_DIR = $(_INSTALLDIR)\lib
|
|
BIN_INSTALL_DIR = $(_INSTALLDIR)\bin
|
|
DOC_INSTALL_DIR = $(_INSTALLDIR)\doc
|
|
!if $(DOING_TCL)
|
|
SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
|
|
!else # DOING_TK
|
|
SCRIPT_INSTALL_DIR = $(_INSTALLDIR)\lib\$(PROJECT)$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
|
|
!endif
|
|
DEMO_INSTALL_DIR = $(SCRIPT_INSTALL_DIR)\demos
|
|
INCLUDE_INSTALL_DIR = $(_INSTALLDIR)\include
|
|
|
|
!else # extension other than Tk
|
|
|
|
PRJ_INSTALL_DIR = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
|
|
LIB_INSTALL_DIR = $(PRJ_INSTALL_DIR)
|
|
BIN_INSTALL_DIR = $(PRJ_INSTALL_DIR)
|
|
DOC_INSTALL_DIR = $(PRJ_INSTALL_DIR)
|
|
SCRIPT_INSTALL_DIR = $(PRJ_INSTALL_DIR)
|
|
DEMO_INSTALL_DIR = $(PRJ_INSTALL_DIR)\demos
|
|
INCLUDE_INSTALL_DIR = $(_TCLDIR)\include
|
|
|
|
!endif
|
|
|
|
###################################################################
|
|
# 12. Set up actual options to be passed to the compiler and linker
|
|
# Now we have all the information we need, set up the actual flags and
|
|
# options that we will pass to the compiler and linker. The main
|
|
# makefile should use these in combination with whatever other flags
|
|
# and switches are specific to it.
|
|
# The following macros are defined, names are for historical compatibility:
|
|
# OPTDEFINES - /Dxxx C macro flags based on user-specified OPTS
|
|
# COMPILERFLAGS - /Dxxx C macro flags independent of any configuration opttions
|
|
# crt - Compiler switch that selects the appropriate C runtime
|
|
# cdebug - Compiler switches related to debug AND optimizations
|
|
# cwarn - Compiler switches that set warning levels
|
|
# cflags - complete compiler switches (subsumes cdebug and cwarn)
|
|
# ldebug - Linker switches controlling debug information and optimization
|
|
# lflags - complete linker switches (subsumes ldebug) except subsystem type
|
|
# dlllflags - complete linker switches to build DLLs (subsumes lflags)
|
|
# conlflags - complete linker switches for console program (subsumes lflags)
|
|
# guilflags - complete linker switches for GUI program (subsumes lflags)
|
|
# baselibs - minimum Windows libraries required. Parent makefile can
|
|
# define PRJ_LIBS before including rules.rc if additional libs are needed
|
|
|
|
OPTDEFINES = -DTCL_CFGVAL_ENCODING=$(CFG_ENCODING) -DSTDC_HEADERS
|
|
|
|
!if $(TCL_MEM_DEBUG)
|
|
OPTDEFINES = $(OPTDEFINES) -DTCL_MEM_DEBUG
|
|
!endif
|
|
!if $(TCL_COMPILE_DEBUG)
|
|
OPTDEFINES = $(OPTDEFINES) -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
|
|
!endif
|
|
!if $(TCL_THREADS)
|
|
OPTDEFINES = $(OPTDEFINES) -DTCL_THREADS=1
|
|
!if $(USE_THREAD_ALLOC)
|
|
OPTDEFINES = $(OPTDEFINES) -DUSE_THREAD_ALLOC=1
|
|
!endif
|
|
!endif
|
|
!if $(STATIC_BUILD)
|
|
OPTDEFINES = $(OPTDEFINES) -DSTATIC_BUILD
|
|
!endif
|
|
!if $(TCL_NO_DEPRECATED)
|
|
OPTDEFINES = $(OPTDEFINES) -DTCL_NO_DEPRECATED
|
|
!endif
|
|
|
|
!if $(USE_STUBS)
|
|
# Note we do not define USE_TCL_STUBS even when building tk since some
|
|
# test targets in tk do not use stubs
|
|
!if ! $(DOING_TCL)
|
|
USE_STUBS_DEFS = -DUSE_TCL_STUBS -DUSE_TCLOO_STUBS
|
|
!if $(NEED_TK)
|
|
USE_STUBS_DEFS = $(USE_STUBS_DEFS) -DUSE_TK_STUBS
|
|
!endif
|
|
!endif
|
|
!endif # USE_STUBS
|
|
|
|
!if !$(DEBUG)
|
|
OPTDEFINES = $(OPTDEFINES) -DNDEBUG
|
|
!if $(OPTIMIZING)
|
|
OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_OPTIMIZED
|
|
!endif
|
|
!endif
|
|
!if $(PROFILE)
|
|
OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_PROFILED
|
|
!endif
|
|
!if "$(MACHINE)" == "AMD64"
|
|
OPTDEFINES = $(OPTDEFINES) -DTCL_CFG_DO64BIT
|
|
!endif
|
|
!if $(VCVERSION) < 1300
|
|
OPTDEFINES = $(OPTDEFINES) -DNO_STRTOI64
|
|
!endif
|
|
|
|
# _ATL_XP_TARGETING - Newer SDK's need this to build for XP
|
|
COMPILERFLAGS = /D_ATL_XP_TARGETING
|
|
|
|
# Following is primarily for the benefit of extensions. Tcl 8.5 builds
|
|
# Tcl without /DUNICODE, while 8.6 builds with it defined. When building
|
|
# an extension, it is advisable (but not mandated) to use the same Windows
|
|
# API as the Tcl build. This is accordingly defaulted below. A particular
|
|
# extension can override this by pre-definining USE_WIDECHAR_API.
|
|
!ifndef USE_WIDECHAR_API
|
|
!if $(TCL_VERSION) > 85
|
|
USE_WIDECHAR_API = 1
|
|
!else
|
|
USE_WIDECHAR_API = 0
|
|
!endif
|
|
!endif
|
|
|
|
!if $(USE_WIDECHAR_API)
|
|
COMPILERFLAGS = $(COMPILERFLAGS) /DUNICODE /D_UNICODE
|
|
!endif
|
|
|
|
# Like the TEA system only set this non empty for non-Tk extensions
|
|
# Note: some extensions use PACKAGE_NAME and others use PACKAGE_TCLNAME
|
|
# so we pass both
|
|
!if !$(DOING_TCL) && !$(DOING_TK)
|
|
PKGNAMEFLAGS = -DPACKAGE_NAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
|
|
-DPACKAGE_TCLNAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
|
|
-DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
|
|
-DMODULE_SCOPE=extern
|
|
!endif
|
|
|
|
# crt picks the C run time based on selected OPTS
|
|
!if $(MSVCRT)
|
|
!if $(DEBUG) && !$(UNCHECKED)
|
|
crt = -MDd
|
|
!else
|
|
crt = -MD
|
|
!endif
|
|
!else
|
|
!if $(DEBUG) && !$(UNCHECKED)
|
|
crt = -MTd
|
|
!else
|
|
crt = -MT
|
|
!endif
|
|
!endif
|
|
|
|
# cdebug includes compiler options for debugging as well as optimization.
|
|
!if $(DEBUG)
|
|
|
|
# In debugging mode, optimizations need to be disabled
|
|
cdebug = -Zi -Od $(DEBUGFLAGS)
|
|
|
|
!else
|
|
|
|
cdebug = $(OPTIMIZATIONS)
|
|
!if $(SYMBOLS)
|
|
cdebug = $(cdebug) -Zi
|
|
!endif
|
|
|
|
!endif # $(DEBUG)
|
|
|
|
# cwarn includes default warning levels.
|
|
cwarn = $(WARNINGS)
|
|
|
|
!if "$(MACHINE)" == "AMD64"
|
|
# Disable pointer<->int warnings related to cast between different sizes
|
|
# There are a gadzillion of these due to use of ClientData and
|
|
# clutter up compiler
|
|
# output increasing chance of a real warning getting lost. So disable them.
|
|
# Eventually some day, Tcl will be 64-bit clean.
|
|
cwarn = $(cwarn) -wd4311 -wd4312
|
|
!endif
|
|
|
|
### Common compiler options that are architecture specific
|
|
!if "$(MACHINE)" == "ARM"
|
|
carch = -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
|
|
!else
|
|
carch =
|
|
!endif
|
|
|
|
!if $(DEBUG)
|
|
# Turn warnings into errors
|
|
cwarn = $(cwarn) -WX
|
|
!endif
|
|
|
|
INCLUDES = $(TCL_INCLUDES) $(TK_INCLUDES) $(PRJ_INCLUDES)
|
|
!if !$(DOING_TCL) && !$(DOING_TK)
|
|
INCLUDES = $(INCLUDES) -I"$(GENERICDIR)" -I"$(WINDIR)" -I"$(COMPATDIR)"
|
|
!endif
|
|
|
|
# These flags are defined roughly in the order of the pre-reform
|
|
# rules.vc/makefile.vc to help visually compare that the pre- and
|
|
# post-reform build logs
|
|
|
|
# cflags contains generic flags used for building practically all object files
|
|
cflags = -nologo -c $(COMPILERFLAGS) $(carch) $(cwarn) -Fp$(TMP_DIR)^\ $(cdebug)
|
|
|
|
# appcflags contains $(cflags) and flags for building the application
|
|
# object files (e.g. tclsh, or wish) pkgcflags contains $(cflags) plus
|
|
# flags used for building shared object files The two differ in the
|
|
# BUILD_$(PROJECT) macro which should be defined only for the shared
|
|
# library *implementation* and not for its caller interface
|
|
|
|
appcflags = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES) $(USE_STUBS_DEFS)
|
|
appcflags_nostubs = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES)
|
|
pkgcflags = $(appcflags) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
|
|
pkgcflags_nostubs = $(appcflags_nostubs) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
|
|
|
|
# stubscflags contains $(cflags) plus flags used for building a stubs
|
|
# library for the package. Note: -DSTATIC_BUILD is defined in
|
|
# $(OPTDEFINES) only if the OPTS configuration indicates a static
|
|
# library. However the stubs library is ALWAYS static hence included
|
|
# here irrespective of the OPTS setting.
|
|
#
|
|
# TBD - tclvfs has a comment that stubs libs should not be compiled with -GL
|
|
# without stating why. Tcl itself compiled stubs libs with this flag.
|
|
# so we do not remove it from cflags. -GL may prevent extensions
|
|
# compiled with one VC version to fail to link against stubs library
|
|
# compiled with another VC version. Check for this and fix accordingly.
|
|
stubscflags = $(cflags) $(PKGNAMEFLAGS) $(PRJ_DEFINES) $(OPTDEFINES) -Zl -DSTATIC_BUILD $(INCLUDES)
|
|
|
|
# Link flags
|
|
|
|
!if $(DEBUG)
|
|
ldebug = -debug -debugtype:cv
|
|
!else
|
|
ldebug = -release -opt:ref -opt:icf,3
|
|
!if $(SYMBOLS)
|
|
ldebug = $(ldebug) -debug -debugtype:cv
|
|
!endif
|
|
!endif
|
|
|
|
# Note: Profiling is currently only possible with the Visual Studio Enterprise
|
|
!if $(PROFILE)
|
|
ldebug= $(ldebug) -profile
|
|
!endif
|
|
|
|
### Declarations common to all linker versions
|
|
lflags = -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)
|
|
|
|
!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
|
|
lflags = $(lflags) -nodefaultlib:libucrt.lib
|
|
!endif
|
|
|
|
# Old linkers (Visual C++ 6 in particular) will link for fast loading
|
|
# on Win98. Since we do not support Win98 any more, we specify nowin98
|
|
# as recommended for NT and later. However, this is only required by
|
|
# IX86 on older compilers and only needed if we are not doing a static build.
|
|
|
|
!if "$(MACHINE)" == "IX86" && !$(STATIC_BUILD)
|
|
!if [nmakehlp -l -opt:nowin98 $(LINKER_TESTFLAGS)]
|
|
# Align sections for PE size savings.
|
|
lflags = $(lflags) -opt:nowin98
|
|
!endif
|
|
!endif
|
|
|
|
dlllflags = $(lflags) -dll
|
|
conlflags = $(lflags) -subsystem:console
|
|
guilflags = $(lflags) -subsystem:windows
|
|
|
|
# Libraries that are required for every image.
|
|
# Extensions should define any additional libraries with $(PRJ_LIBS)
|
|
winlibs = kernel32.lib advapi32.lib
|
|
|
|
!if $(NEED_TK)
|
|
winlibs = $(winlibs) gdi32.lib user32.lib uxtheme.lib
|
|
!endif
|
|
|
|
# Avoid 'unresolved external symbol __security_cookie' errors.
|
|
# c.f. http://support.microsoft.com/?id=894573
|
|
!if "$(MACHINE)" == "AMD64"
|
|
!if $(VCVERSION) > 1399 && $(VCVERSION) < 1500
|
|
winlibs = $(winlibs) bufferoverflowU.lib
|
|
!endif
|
|
!endif
|
|
|
|
baselibs = $(winlibs) $(PRJ_LIBS)
|
|
|
|
!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
|
|
baselibs = $(baselibs) ucrt.lib
|
|
!endif
|
|
|
|
################################################################
|
|
# 13. Define standard commands, common make targets and implicit rules
|
|
|
|
CCPKGCMD = $(cc32) $(pkgcflags) -Fo$(TMP_DIR)^\
|
|
CCAPPCMD = $(cc32) $(appcflags) -Fo$(TMP_DIR)^\
|
|
CCSTUBSCMD = $(cc32) $(stubscflags) -Fo$(TMP_DIR)^\
|
|
|
|
LIBCMD = $(lib32) -nologo $(LINKERFLAGS) -out:$@
|
|
DLLCMD = $(link32) $(dlllflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
|
|
|
|
CONEXECMD = $(link32) $(conlflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
|
|
GUIEXECMD = $(link32) $(guilflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
|
|
RESCMD = $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" \
|
|
$(TCL_INCLUDES) \
|
|
-DDEBUG=$(DEBUG) -d UNCHECKED=$(UNCHECKED) \
|
|
-DCOMMAVERSION=$(DOTVERSION:.=,),0 \
|
|
-DDOTVERSION=\"$(DOTVERSION)\" \
|
|
-DVERSION=\"$(VERSION)\" \
|
|
-DSUFX=\"$(SUFX)\" \
|
|
-DPROJECT=\"$(PROJECT)\" \
|
|
-DPRJLIBNAME=\"$(PRJLIBNAME)\"
|
|
|
|
!ifndef DEFAULT_BUILD_TARGET
|
|
DEFAULT_BUILD_TARGET = $(PROJECT)
|
|
!endif
|
|
|
|
default-target: $(DEFAULT_BUILD_TARGET)
|
|
|
|
default-pkgindex:
|
|
@echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
|
|
[list load [file join $$dir $(PRJLIBNAME)]] > $(OUT_DIR)\pkgIndex.tcl
|
|
|
|
default-pkgindex-tea:
|
|
@if exist $(ROOT)\pkgIndex.tcl.in nmakehlp -s << $(ROOT)\pkgIndex.tcl.in > $(OUT_DIR)\pkgIndex.tcl
|
|
@PACKAGE_VERSION@ $(DOTVERSION)
|
|
@PACKAGE_NAME@ $(PRJ_PACKAGE_TCLNAME)
|
|
@PACKAGE_TCLNAME@ $(PRJ_PACKAGE_TCLNAME)
|
|
@PKG_LIB_FILE@ $(PRJLIBNAME)
|
|
<<
|
|
|
|
|
|
default-install: default-install-binaries default-install-libraries
|
|
|
|
default-install-binaries: $(PRJLIB)
|
|
@echo Installing binaries to '$(SCRIPT_INSTALL_DIR)'
|
|
@if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
|
|
@$(CPY) $(PRJLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
|
|
|
|
default-install-libraries: $(OUT_DIR)\pkgIndex.tcl
|
|
@echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
|
|
@if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)"
|
|
@echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
|
|
@$(CPY) $(OUT_DIR)\pkgIndex.tcl $(SCRIPT_INSTALL_DIR)
|
|
|
|
default-install-stubs:
|
|
@echo Installing stubs library to '$(SCRIPT_INSTALL_DIR)'
|
|
@if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
|
|
@$(CPY) $(PRJSTUBLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
|
|
|
|
default-install-docs-html:
|
|
@echo Installing documentation files to '$(DOC_INSTALL_DIR)'
|
|
@if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
|
|
@if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.html" "$(DOCDIR)\*.css" "$(DOCDIR)\*.png") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
|
|
|
|
default-install-docs-n:
|
|
@echo Installing documentation files to '$(DOC_INSTALL_DIR)'
|
|
@if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
|
|
@if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.n") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
|
|
|
|
default-install-demos:
|
|
@echo Installing demos to '$(DEMO_INSTALL_DIR)'
|
|
@if not exist "$(DEMO_INSTALL_DIR)" mkdir "$(DEMO_INSTALL_DIR)"
|
|
@if exist $(DEMODIR) $(CPYDIR) "$(DEMODIR)" "$(DEMO_INSTALL_DIR)"
|
|
|
|
default-clean:
|
|
@echo Cleaning $(TMP_DIR)\* ...
|
|
@if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
|
|
@echo Cleaning $(WINDIR)\nmakehlp.obj, nmakehlp.exe ...
|
|
@if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
|
|
@if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
|
|
@if exist $(WINDIR)\nmakehlp.out del $(WINDIR)\nmakehlp.out
|
|
@echo Cleaning $(WINDIR)\nmhlp-out.txt ...
|
|
@if exist $(WINDIR)\nmhlp-out.txt del $(WINDIR)\nmhlp-out.txt
|
|
@echo Cleaning $(WINDIR)\_junk.pch ...
|
|
@if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch
|
|
@echo Cleaning $(WINDIR)\vercl.x, vercl.i ...
|
|
@if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
|
|
@if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
|
|
@echo Cleaning $(WINDIR)\versions.vc, version.vc ...
|
|
@if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc
|
|
@if exist $(WINDIR)\version.vc del $(WINDIR)\version.vc
|
|
|
|
default-hose: default-clean
|
|
@echo Hosing $(OUT_DIR)\* ...
|
|
@if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
|
|
|
|
# Only for backward compatibility
|
|
default-distclean: default-hose
|
|
|
|
default-setup:
|
|
@if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
|
|
@if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
|
|
|
|
!if "$(TESTPAT)" != ""
|
|
TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
|
|
!endif
|
|
|
|
default-test: default-setup $(PROJECT)
|
|
@set TCLLIBPATH=$(OUT_DIR:\=/)
|
|
@if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
|
|
cd "$(TESTDIR)" && $(DEBUGGER) $(TCLSH) all.tcl $(TESTFLAGS)
|
|
|
|
default-shell: default-setup $(PROJECT)
|
|
@set TCLLIBPATH=$(OUT_DIR:\=/)
|
|
@if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
|
|
$(DEBUGGER) $(TCLSH)
|
|
|
|
# Generation of Windows version resource
|
|
!ifdef RCFILE
|
|
|
|
# Note: don't use $** in below rule because there may be other dependencies
|
|
# and only the "master" rc must be passed to the resource compiler
|
|
$(TMP_DIR)\$(PROJECT).res: $(RCDIR)\$(PROJECT).rc
|
|
$(RESCMD) $(RCDIR)\$(PROJECT).rc
|
|
|
|
!else
|
|
|
|
# If parent makefile has not defined a resource definition file,
|
|
# we will generate one from standard template.
|
|
$(TMP_DIR)\$(PROJECT).res: $(TMP_DIR)\$(PROJECT).rc
|
|
|
|
$(TMP_DIR)\$(PROJECT).rc:
|
|
@$(COPY) << $(TMP_DIR)\$(PROJECT).rc
|
|
#include <winver.h>
|
|
|
|
VS_VERSION_INFO VERSIONINFO
|
|
FILEVERSION COMMAVERSION
|
|
PRODUCTVERSION COMMAVERSION
|
|
FILEFLAGSMASK 0x3fL
|
|
#ifdef DEBUG
|
|
FILEFLAGS VS_FF_DEBUG
|
|
#else
|
|
FILEFLAGS 0x0L
|
|
#endif
|
|
FILEOS VOS_NT_WINDOWS32
|
|
FILETYPE VFT_DLL
|
|
FILESUBTYPE 0x0L
|
|
BEGIN
|
|
BLOCK "StringFileInfo"
|
|
BEGIN
|
|
BLOCK "040904b0"
|
|
BEGIN
|
|
VALUE "FileDescription", "Tcl extension " PROJECT
|
|
VALUE "OriginalFilename", PRJLIBNAME
|
|
VALUE "FileVersion", DOTVERSION
|
|
VALUE "ProductName", "Package " PROJECT " for Tcl"
|
|
VALUE "ProductVersion", DOTVERSION
|
|
END
|
|
END
|
|
BLOCK "VarFileInfo"
|
|
BEGIN
|
|
VALUE "Translation", 0x409, 1200
|
|
END
|
|
END
|
|
|
|
<<
|
|
|
|
!endif # ifdef RCFILE
|
|
|
|
!ifndef DISABLE_IMPLICIT_RULES
|
|
DISABLE_IMPLICIT_RULES = 0
|
|
!endif
|
|
|
|
!if !$(DISABLE_IMPLICIT_RULES)
|
|
# Implicit rule definitions - only for building library objects. For stubs and
|
|
# main application, the master makefile should define explicit rules.
|
|
|
|
{$(ROOT)}.c{$(TMP_DIR)}.obj::
|
|
$(CCPKGCMD) @<<
|
|
$<
|
|
<<
|
|
|
|
{$(WINDIR)}.c{$(TMP_DIR)}.obj::
|
|
$(CCPKGCMD) @<<
|
|
$<
|
|
<<
|
|
|
|
{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
|
|
$(CCPKGCMD) @<<
|
|
$<
|
|
<<
|
|
|
|
{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
|
|
$(CCPKGCMD) @<<
|
|
$<
|
|
<<
|
|
|
|
{$(RCDIR)}.rc{$(TMP_DIR)}.res:
|
|
$(RESCMD) $<
|
|
|
|
{$(WINDIR)}.rc{$(TMP_DIR)}.res:
|
|
$(RESCMD) $<
|
|
|
|
{$(TMP_DIR)}.rc{$(TMP_DIR)}.res:
|
|
$(RESCMD) $<
|
|
|
|
.SUFFIXES:
|
|
.SUFFIXES:.c .rc
|
|
|
|
!endif
|
|
|
|
################################################################
|
|
# 14. Sanity check selected options against Tcl build options
|
|
# When building an extension, certain configuration options should
|
|
# match the ones used when Tcl was built. Here we check and
|
|
# warn on a mismatch.
|
|
!if ! $(DOING_TCL)
|
|
|
|
!if $(TCLINSTALL) # Building against an installed Tcl
|
|
!if exist("$(_TCLDIR)\lib\nmake\tcl.nmake")
|
|
TCLNMAKECONFIG = "$(_TCLDIR)\lib\nmake\tcl.nmake"
|
|
!endif
|
|
!else # ! $(TCLINSTALL) - building against Tcl source
|
|
!if exist("$(OUT_DIR)\tcl.nmake")
|
|
TCLNMAKECONFIG = "$(OUT_DIR)\tcl.nmake"
|
|
!endif
|
|
!endif # TCLINSTALL
|
|
|
|
!if $(CONFIG_CHECK)
|
|
!ifdef TCLNMAKECONFIG
|
|
!include $(TCLNMAKECONFIG)
|
|
|
|
!if defined(CORE_MACHINE) && "$(CORE_MACHINE)" != "$(MACHINE)"
|
|
!error ERROR: Build target ($(MACHINE)) does not match the Tcl library architecture ($(CORE_MACHINE)).
|
|
!endif
|
|
!if defined(CORE_USE_THREAD_ALLOC) && $(CORE_USE_THREAD_ALLOC) != $(USE_THREAD_ALLOC)
|
|
!message WARNING: Value of USE_THREAD_ALLOC ($(USE_THREAD_ALLOC)) does not match its Tcl core value ($(CORE_USE_THREAD_ALLOC)).
|
|
!endif
|
|
!if defined(CORE_DEBUG) && $(CORE_DEBUG) != $(DEBUG)
|
|
!message WARNING: Value of DEBUG ($(DEBUG)) does not match its Tcl library configuration ($(DEBUG)).
|
|
!endif
|
|
!endif
|
|
|
|
!endif # TCLNMAKECONFIG
|
|
|
|
!endif # ! $(DOING_TCL)
|
|
|
|
|
|
#----------------------------------------------------------
|
|
# Display stats being used.
|
|
#----------------------------------------------------------
|
|
|
|
!if !$(DOING_TCL)
|
|
!message *** Building against Tcl at '$(_TCLDIR)'
|
|
!endif
|
|
!if !$(DOING_TK) && $(NEED_TK)
|
|
!message *** Building against Tk at '$(_TKDIR)'
|
|
!endif
|
|
!message *** Intermediate directory will be '$(TMP_DIR)'
|
|
!message *** Output directory will be '$(OUT_DIR)'
|
|
!message *** Installation, if selected, will be in '$(_INSTALLDIR)'
|
|
!message *** Suffix for binaries will be '$(SUFX)'
|
|
!message *** Compiler version $(VCVER). Target machine is $(MACHINE)
|
|
!message *** Host architecture is $(NATIVE_ARCH)
|
|
|
|
!endif # ifdef _RULES_VC
|