1# makefile.vc -- -*- Makefile -*- 2# 3# Microsoft Visual C++ makefile for use with nmake.exe v1.62+ (VC++ 5.0+) 4# 5# This makefile is based upon the Tcl 8.4 Makefile.vc and modified to 6# make it suitable as a general package makefile. Look for the word EDIT 7# which marks sections that may need modification. As a minumum you will 8# need to change the PROJECT, DOTVERSION and DLLOBJS variables to values 9# relevant to your package. 10# 11# See the file "license.terms" for information on usage and redistribution 12# of this file, and for a DISCLAIMER OF ALL WARRANTIES. 13# 14# Copyright (c) 1995-1996 Sun Microsystems, Inc. 15# Copyright (c) 1998-2000 Ajuba Solutions. 16# Copyright (c) 2001 ActiveState Corporation. 17# Copyright (c) 2001-2002 David Gravereaux. 18# Copyright (c) 2003-2006 Pat Thoyts 19# 20#------------------------------------------------------------------------- 21# RCS: @(#)$Id: makefile.vc,v 8.6 2008/06/29 23:53:57 patthoyts Exp $ 22#------------------------------------------------------------------------- 23 24# Check to see we are configured to build with MSVC (MSDEVDIR or MSVCDIR) 25# or with the MS Platform SDK (MSSDK). Visual Studio .NET 2003 and 2005 define 26# VCINSTALLDIR instead. The MSVC Toolkit release defines yet another. 27!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(MSSDK) && !defined(VCINSTALLDIR) && !defined(VCToolkitInstallDir) 28MSG = ^ 29You need to run vcvars32.bat from Developer Studio or setenv.bat from the^ 30Platform SDK first to setup the environment. Jump to this line to read^ 31the build instructions. 32!error $(MSG) 33!endif 34 35#------------------------------------------------------------------------------ 36# HOW TO USE this makefile: 37# 38# 1) It is now necessary to have %MSVCDir% set in the environment. This is 39# used as a check to see if vcvars32.bat had been run prior to running 40# nmake or during the installation of Microsoft Visual C++, MSVCDir had 41# been set globally and the PATH adjusted. Either way is valid. 42# 43# You'll need to run vcvars32.bat contained in the MsDev's vc(98)/bin 44# directory to setup the proper environment, if needed, for your current 45# setup. This is a needed bootstrap requirement and allows the swapping of 46# different environments to be easier. 47# 48# 2) To use the Platform SDK (not expressly needed), run setenv.bat after 49# vcvars32.bat according to the instructions for it. This can also turn on 50# the 64-bit compiler, if your SDK has it. 51# 52# 3) Targets are: 53# all -- Builds everything. 54# <project> -- Builds the project (eg: nmake sample) 55# test -- Builds and runs the test suite. 56# install -- Installs the built binaries and libraries to $(INSTALLDIR) 57# in an appropriate subdirectory. 58# clean/realclean/distclean -- varying levels of cleaning. 59# 60# 4) Macros usable on the commandline: 61# INSTALLDIR=<path> 62# Sets where to install Tcl from the built binaries. 63# C:\Progra~1\Tcl is assumed when not specified. 64# 65# OPTS=static,msvcrt,staticpkg,threads,symbols,profile,loimpact,none 66# Sets special options for the core. The default is for none. 67# Any combination of the above may be used (comma separated). 68# 'none' will over-ride everything to nothing. 69# 70# static = Builds a static library of the core instead of a 71# dll. The shell will be static (and large), as well. 72# msvcrt = Effects the static option only to switch it from 73# using libcmt(d) as the C runtime [by default] to 74# msvcrt(d). This is useful for static embedding 75# support. 76# staticpkg = Effects the static option only to switch 77# tclshXX.exe to have the dde and reg extension linked 78# inside it. 79# nothreads = Turns off multithreading support (not recommended) 80# thrdalloc = Use the thread allocator (shared global free pool). 81# symbols = Adds symbols for step debugging. 82# profile = Adds profiling hooks. Map file is assumed. 83# loimpact = Adds a flag for how NT treats the heap to keep memory 84# in use, low. This is said to impact alloc performance. 85# 86# STATS=memdbg,compdbg,none 87# Sets optional memory and bytecode compiler debugging code added 88# to the core. The default is for none. Any combination of the 89# above may be used (comma separated). 'none' will over-ride 90# everything to nothing. 91# 92# memdbg = Enables the debugging memory allocator. 93# compdbg = Enables byte compilation logging. 94# 95# MACHINE=(IX86|IA64|ALPHA|AMD64) 96# Set the machine type used for the compiler, linker, and 97# resource compiler. This hook is needed to tell the tools 98# when alternate platforms are requested. IX86 is the default 99# when not specified. If the CPU environment variable has been 100# set (ie: recent Platform SDK) then MACHINE is set from CPU. 101# 102# TMP_DIR=<path> 103# OUT_DIR=<path> 104# Hooks to allow the intermediate and output directories to be 105# changed. $(OUT_DIR) is assumed to be 106# $(BINROOT)\(Release|Debug) based on if symbols are requested. 107# $(TMP_DIR) will de $(OUT_DIR)\<buildtype> by default. 108# 109# TESTPAT=<file> 110# Reads the tests requested to be run from this file. 111# 112# CFG_ENCODING=encoding 113# name of encoding for configuration information. Defaults 114# to cp1252 115# 116# 5) Examples: 117# 118# Basic syntax of calling nmake looks like this: 119# nmake [-nologo] -f makefile.vc [target|macrodef [target|macrodef] [...]] 120# 121# Standard (no frills) 122# c:\tcl_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat 123# Setting environment for using Microsoft Visual C++ tools. 124# c:\tcl_src\win\>nmake -f makefile.vc all 125# c:\tcl_src\win\>nmake -f makefile.vc install INSTALLDIR=c:\progra~1\tcl 126# 127# Building for Win64 128# c:\tcl_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat 129# Setting environment for using Microsoft Visual C++ tools. 130# c:\tcl_src\win\>c:\progra~1\platfo~1\setenv.bat /pre64 /RETAIL 131# Targeting Windows pre64 RETAIL 132# c:\tcl_src\win\>nmake -f makefile.vc MACHINE=IA64 133# 134#------------------------------------------------------------------------------ 135#============================================================================== 136############################################################################### 137#------------------------------------------------------------------------------ 138 139!if !exist("makefile.vc") 140MSG = ^ 141You must run this makefile only from the directory it is in.^ 142Please `cd` to its location first. 143!error $(MSG) 144!endif 145 146#------------------------------------------------------------------------- 147# Project specific information (EDIT) 148# 149# You should edit this with the name and version of your project. This 150# information is used to generate the name of the package library and 151# it's install location. 152# 153# For example, the sample extension is going to build sample04.dll and 154# would install it into $(INSTALLDIR)\lib\sample04 155# 156# You need to specify the object files that need to be linked into your 157# binary here. 158# 159#------------------------------------------------------------------------- 160 161PROJECT = tclx 162 163# Uncomment the following line if this is a Tk extension. 164#PROJECT_REQUIRES_TK=1 165!include "rules.vc" 166 167FULL_VERSION = 8.4.0 168DOTVERSION = 8.4 169VERSION = $(DOTVERSION:.=) 170STUBPREFIX = $(PROJECT)stub 171 172DLLOBJS = \ 173 $(TMP_DIR)\tclXbsearch.obj \ 174 $(TMP_DIR)\tclXchmod.obj \ 175 $(TMP_DIR)\tclXcmdloop.obj \ 176 $(TMP_DIR)\tclXdebug.obj \ 177 $(TMP_DIR)\tclXdup.obj \ 178 $(TMP_DIR)\tclXfcntl.obj \ 179 $(TMP_DIR)\tclXfilecmds.obj \ 180 $(TMP_DIR)\tclXfilescan.obj \ 181 $(TMP_DIR)\tclXflock.obj \ 182 $(TMP_DIR)\tclXfstat.obj \ 183 $(TMP_DIR)\tclXgeneral.obj \ 184 $(TMP_DIR)\tclXhandles.obj \ 185 $(TMP_DIR)\tclXinit.obj \ 186 $(TMP_DIR)\tclXkeylist.obj \ 187 $(TMP_DIR)\tclXlib.obj \ 188 $(TMP_DIR)\tclXlist.obj \ 189 $(TMP_DIR)\tclXmath.obj \ 190 $(TMP_DIR)\tclXmsgcat.obj \ 191 $(TMP_DIR)\tclXprocess.obj \ 192 $(TMP_DIR)\tclXprofile.obj \ 193 $(TMP_DIR)\tclXselect.obj \ 194 $(TMP_DIR)\tclXsignal.obj \ 195 $(TMP_DIR)\tclXstring.obj \ 196 $(TMP_DIR)\tclXsocket.obj \ 197 $(TMP_DIR)\tclXutil.obj \ 198 $(TMP_DIR)\tclXoscmds.obj \ 199 $(TMP_DIR)\tclXlgets.obj \ 200 $(TMP_DIR)\tclXwinCmds.obj \ 201 $(TMP_DIR)\tclXwinDup.obj \ 202 $(TMP_DIR)\tclXwinId.obj \ 203 $(TMP_DIR)\tclXwinOS.obj \ 204 $(TMP_DIR)\random.obj \ 205 $(TMP_DIR)\getopt.obj \ 206!if !$(STATIC_BUILD) 207 $(TMP_DIR)\tclx.res 208!endif 209 210#------------------------------------------------------------------------- 211# Target names and paths ( shouldn't need changing ) 212#------------------------------------------------------------------------- 213 214BINROOT = . 215ROOT = .. 216 217PRJIMPLIB = $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib 218PRJLIBNAME = $(PROJECT)$(VERSION)$(SUFX).$(EXT) 219PRJLIB = $(OUT_DIR)\$(PRJLIBNAME) 220 221PRJSTUBLIBNAME = $(STUBPREFIX)$(VERSION).lib 222PRJSTUBLIB = $(OUT_DIR)\$(PRJSTUBLIBNAME) 223 224### Make sure we use backslash only. 225PRJ_INSTALL_DIR = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION) 226LIB_INSTALL_DIR = $(PRJ_INSTALL_DIR) 227BIN_INSTALL_DIR = $(PRJ_INSTALL_DIR) 228DOC_INSTALL_DIR = $(PRJ_INSTALL_DIR) 229SCRIPT_INSTALL_DIR = $(PRJ_INSTALL_DIR) 230INCLUDE_INSTALL_DIR = $(_TCLDIR)\include 231 232### The following paths CANNOT have spaces in them. 233GENERICDIR = $(ROOT)\generic 234WINDIR = $(ROOT)\win 235LIBDIR = $(ROOT)\library 236DOCDIR = $(ROOT)\doc 237TOOLSDIR = $(ROOT)\tools 238COMPATDIR = $(ROOT)\compat 239 240#--------------------------------------------------------------------- 241# Compile flags 242#--------------------------------------------------------------------- 243 244!if !$(DEBUG) 245!if $(OPTIMIZING) 246### This cranks the optimization level to maximize speed 247cdebug = $(OPTIMIZATIONS) 248!else 249cdebug = 250!endif 251!else if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64" 252### Warnings are too many, can't support warnings into errors. 253cdebug = -Zi -Od $(DEBUGFLAGS) 254!else 255cdebug = -Zi -WX $(DEBUGFLAGS) 256!endif 257 258### Declarations common to all compiler options 259cwarn = $(WARNINGS) -D _CRT_SECURE_NO_DEPRECATE -D _CRT_NONSTDC_NO_DEPRECATE 260cflags = -nologo -c $(COMPILERFLAGS) $(cwarn) -Fp$(TMP_DIR)^\ 261 262!if $(MSVCRT) 263!if $(DEBUG) && !$(UNCHECKED) 264crt = -MDd 265!else 266crt = -MD 267!endif 268!else 269!if $(DEBUG) && !$(UNCHECKED) 270crt = -MTd 271!else 272crt = -MT 273!endif 274!endif 275 276!if !$(STATIC_BUILD) 277cflags = $(cflags) -DUSE_TCL_STUBS 278!if defined(TKSTUBLIB) 279cflags = $(cflags) -DUSE_TK_STUBS 280!endif 281!endif 282 283INCLUDES = $(TCL_INCLUDES) -I"$(WINDIR)" -I"$(GENERICDIR)" 284BASE_CFLAGS = $(cflags) $(cdebug) $(crt) $(INCLUDES) 285CON_CFLAGS = $(cflags) $(cdebug) $(crt) -DCONSOLE 286TCL_CFLAGS = -DPACKAGE_NAME="\"$(PROJECT)\"" \ 287 -DPACKAGE_VERSION="\"$(DOTVERSION)\"" \ 288 -DBUILD_$(PROJECT) -DWIN32 \ 289 -DFULL_VERSION="\"$(FULL_VERSION)\"" \ 290 $(BASE_CFLAGS) $(OPTDEFINES) 291 292#--------------------------------------------------------------------- 293# Link flags 294#--------------------------------------------------------------------- 295 296!if $(DEBUG) 297ldebug = -debug:full -debugtype:cv 298!if $(MSVCRT) 299ldebug = $(ldebug) -nodefaultlib:msvcrt 300!endif 301!else 302ldebug = -release -opt:ref -opt:icf,3 303!endif 304 305### Declarations common to all linker options 306lflags = -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug) 307 308!if $(PROFILE) 309lflags = $(lflags) -profile 310!endif 311 312!if $(ALIGN98_HACK) && !$(STATIC_BUILD) 313### Align sections for PE size savings. 314lflags = $(lflags) -opt:nowin98 315!else if !$(ALIGN98_HACK) && $(STATIC_BUILD) 316### Align sections for speed in loading by choosing the virtual page size. 317lflags = $(lflags) -align:4096 318!endif 319 320!if $(LOIMPACT) 321lflags = $(lflags) -ws:aggressive 322!endif 323 324dlllflags = $(lflags) -dll 325conlflags = $(lflags) -subsystem:console 326guilflags = $(lflags) -subsystem:windows 327!if !$(STATIC_BUILD) 328baselibs = $(TCLSTUBLIB) 329!if defined(TKSTUBLIB) 330baselibs = $(baselibs) $(TKSTUBLIB) 331!endif 332!endif 333 334# Avoid 'unresolved external symbol __security_cookie' errors. 335# c.f. http://support.microsoft.com/?id=894573 336!if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64" 337!if $(VCVERSION) >= 1400 && $(VCVERSION) < 1500 338baselibs = $(baselibs) bufferoverflowU.lib 339!endif 340!endif 341 342baselibs = $(baselibs) ws2_32.lib 343 344#--------------------------------------------------------------------- 345# TclTest flags 346#--------------------------------------------------------------------- 347 348!IF "$(TESTPAT)" != "" 349TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT) 350!ENDIF 351 352#--------------------------------------------------------------------- 353# Project specific targets (EDIT) 354#--------------------------------------------------------------------- 355 356all: setup $(PROJECT) 357$(PROJECT): setup pkgIndex $(PRJLIB) 358install: install-binaries install-libraries install-docs 359pkgIndex: $(OUT_DIR)\pkgIndex.tcl 360 361test: setup $(PROJECT) 362 @set TCL_LIBRARY=$(TCL_LIBRARY:\=/) 363 @set TCLLIBPATH=$(OUT_DIR_PATH:\=/) 364!if $(TCLINSTALL) 365 @set PATH=$(_TCLDIR)\bin;$(PATH) 366!else 367 @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH) 368!endif 369 @$(CPY) $(LIBDIR) $(OUT_DIR)\tclx8.4 370!if "$(OS)" == "Windows_NT" || "$(MSVCDIR)" == "IDE" 371 $(DEBUGGER) $(TCLSH) "$(ROOT)/tests/all.tcl" $(TESTFLAGS) 372!else 373 @echo Please wait while the tests are collected... 374 $(DEBUGGER) $(TCLSH) "$(ROOT)/tests/all.tcl" $(TESTFLAGS) > tests.log 375 type tests.log | more 376!endif 377 378shell: setup $(PROJECT) 379 @set TCL_LIBRARY=$(TCL_LIBRARY:\=/) 380 @set TCLLIBPATH=$(OUT_DIR_PATH:\=/) 381!if $(TCLINSTALL) 382 @set PATH=$(_TCLDIR)\bin;$(PATH) 383!else 384 @set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH) 385!endif 386 @$(CPY) $(LIBDIR) $(OUT_DIR)\tclx8.4 387 $(DEBUGGER) $(TCLSH) $(SCRIPT) 388 389setup: 390 @if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR) 391 @if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR) 392 393# See <tcl>/win/coffbase.txt for extension base addresses. 394$(PRJLIB): $(DLLOBJS) 395!if $(STATIC_BUILD) 396 $(lib32) -nologo -out:$@ @<< 397$** 398<< 399!else 400 $(link32) $(dlllflags) -base:0x10000000 -out:$@ $(baselibs) @<< 401$** 402<< 403 $(_VC_MANIFEST_EMBED_DLL) 404 -@del $*.exp 405!endif 406 407$(PRJSTUBLIB): $(PRJSTUBOBJS) 408 $(lib32) -nologo -out:$@ $(PRJSTUBOBJS) 409 410#--------------------------------------------------------------------- 411# Implicit rules 412#--------------------------------------------------------------------- 413 414{$(WINDIR)}.c{$(TMP_DIR)}.obj:: 415 $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<< 416$< 417<< 418 419{$(GENERICDIR)}.c{$(TMP_DIR)}.obj:: 420 $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<< 421$< 422<< 423 424{$(COMPATDIR)}.c{$(TMP_DIR)}.obj:: 425 $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<< 426$< 427<< 428 429{$(WINDIR)}.rc{$(TMP_DIR)}.res: 430 $(rc32) -fo $@ -r -i "$(GENERICDIR)" -D__WIN32__ \ 431 -DCOMMAVERSION=$(DOTVERSION:.=,),0,0 \ 432 -DDOTVERSION=\"$(DOTVERSION)\" \ 433 -DVERSION=\"$(VERSION)$(SUFX)\" \ 434!if $(DEBUG) 435 -d DEBUG \ 436!endif 437!if $(TCL_THREADS) 438 -d TCL_THREADS \ 439!endif 440!if $(STATIC_BUILD) 441 -d STATIC_BUILD \ 442!endif 443 $< 444 445.SUFFIXES: 446.SUFFIXES:.c .rc 447 448#------------------------------------------------------------------------- 449# Explicit dependency rules 450# 451#------------------------------------------------------------------------- 452 453$(OUT_DIR)\pkgIndex.tcl: $(WINDIR)\pkgIndex.tcl.in 454 @nmakehlp -s << $** > $@ 455@PACKAGE_VERSION@ $(DOTVERSION) 456@PACKAGE_NAME@ $(PROJECT) 457@PKG_LIB_FILE@ $(PRJLIBNAME) 458<< 459 460#--------------------------------------------------------------------- 461# Installation. (EDIT) 462# 463# You may need to modify this section to reflect the final distribution 464# of your files and possibly to generate documentation. 465# 466#--------------------------------------------------------------------- 467 468install-binaries: 469 @echo Installing binaries to '$(SCRIPT_INSTALL_DIR)' 470 @if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)" 471 @$(CPY) $(PRJLIB) "$(SCRIPT_INSTALL_DIR)" >NUL 472 473install-libraries: $(OUT_DIR)\pkgIndex.tcl 474 @echo Installing libraries to '$(SCRIPT_INSTALL_DIR)' 475 @if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)" 476 @echo Installing package index in '$(SCRIPT_INSTALL_DIR)' 477 @$(CPY) $(OUT_DIR)\pkgIndex.tcl $(SCRIPT_INSTALL_DIR) 478 479install-docs: 480 @echo Installing documentation files to '$(DOC_INSTALL_DIR)' 481 @if exist $(DOCDIR) $(CPY) $(DOCDIR)\*.n "$(DOC_INSTALL_DIR)" 482 483#--------------------------------------------------------------------- 484# Clean up 485#--------------------------------------------------------------------- 486 487clean: 488 @if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR) 489 @if exist $(WINDIR)\version.vc del $(WINDIR)\version.vc 490 @if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i 491 @if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x 492 @if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch 493 494realclean: clean 495 @if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR) 496 497distclean: realclean 498 @if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe 499 @if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj 500