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 Pat Thoyts
19#
20#-------------------------------------------------------------------------
21# RCS: @(#)$Id: makefile.vc,v 1.17 2006/09/30 22:44:25 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.
27!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(MSSDK) && !defined(VCINSTALLDIR)
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#		threads =  Turns on full multithreading support.
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)
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.
100#
101#	TMP_DIR=<path>
102#	OUT_DIR=<path>
103#		Hooks to allow the intermediate and output directories to be
104#		changed.  $(OUT_DIR) is assumed to be 
105#		$(BINROOT)\(Release|Debug) based on if symbols are requested.
106#		$(TMP_DIR) will de $(OUT_DIR)\<buildtype> by default.
107#
108#	TESTPAT=<file>
109#		Reads the tests requested to be run from this file.
110#
111#	CFG_ENCODING=encoding
112#		name of encoding for configuration information. Defaults
113#		to cp1252
114#
115# 5)  Examples:
116#
117#	Basic syntax of calling nmake looks like this:
118#	nmake [-nologo] -f makefile.vc [target|macrodef [target|macrodef] [...]]
119#
120#                        Standard (no frills)
121#       c:\tcl_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat
122#       Setting environment for using Microsoft Visual C++ tools.
123#       c:\tcl_src\win\>nmake -f makefile.vc all
124#       c:\tcl_src\win\>nmake -f makefile.vc install INSTALLDIR=c:\progra~1\tcl
125#
126#                         Building for Win64
127#       c:\tcl_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat
128#       Setting environment for using Microsoft Visual C++ tools.
129#       c:\tcl_src\win\>c:\progra~1\platfo~1\setenv.bat /pre64 /RETAIL
130#       Targeting Windows pre64 RETAIL
131#       c:\tcl_src\win\>nmake -f makefile.vc MACHINE=IA64
132#
133#------------------------------------------------------------------------------
134#==============================================================================
135###############################################################################
136#------------------------------------------------------------------------------
137
138!if !exist("makefile.vc")
139MSG = ^
140You must run this makefile only from the directory it is in.^
141Please `cd` to its location first.
142!error $(MSG)
143!endif
144
145#-------------------------------------------------------------------------
146# Project specific information (EDIT)
147#
148# You should edit this with the name and version of your project. This
149# information is used to generate the name of the package library and
150# it's install location.
151#
152# For example, the sample extension is  going to build sample04.dll and
153# would install it into $(INSTALLDIR)\lib\sample04
154#
155# You need to specify the object files that need to be linked into your
156# binary here.
157#
158#-------------------------------------------------------------------------
159
160PROJECT = Memchan
161!include "rules.vc"
162
163DOTVERSION      = 2.2.1
164MEMCHAN_VERSION = 2.2.1
165VERSION         = $(DOTVERSION:.=)
166STUBPREFIX      = $(PROJECT)stub
167
168DLLOBJS	= \
169	$(TMP_DIR)\memchan.obj	\
170	$(TMP_DIR)\init.obj	\
171	$(TMP_DIR)\counter.obj	\
172	$(TMP_DIR)\fifo.obj	\
173	$(TMP_DIR)\fifo2.obj	\
174	$(TMP_DIR)\null.obj	\
175	$(TMP_DIR)\random.obj	\
176	$(TMP_DIR)\zero.obj	\
177	$(TMP_DIR)\buf.obj	\
178	$(TMP_DIR)\bufFix.obj	\
179	$(TMP_DIR)\bufExt.obj	\
180	$(TMP_DIR)\bufRange.obj	\
181	$(TMP_DIR)\bufQueue.obj	\
182	$(TMP_DIR)\bufStubInit.obj \
183	$(TMP_DIR)\bufStubLib.obj \
184	$(TMP_DIR)\dllEntry.obj \
185	$(TMP_DIR)\randport.obj \
186	$(TMP_DIR)\memchanStubInit.obj \
187	$(TMP_DIR)\memchanStubLib.obj
188
189PRJSTUBOBJS = \
190	$(TMP_DIR)\memchanStubLib.obj \
191	$(TMP_DIR)\bufStubLib.obj
192
193PRJDOCS = \
194	$(OUT_DIR)\fifo.html \
195	$(OUT_DIR)\fifo2.html \
196	$(OUT_DIR)\memchan.html \
197	$(OUT_DIR)\null.html \
198	$(OUT_DIR)\zero.html \
199	$(OUT_DIR)\random.html \
200	$(OUT_DIR)\memchanapi.html
201
202DLLRES = $(TMP_DIR)\mc.res
203
204PRJHDRS = \
205	$(GENERICDIR)\memchan.h \
206	$(GENERICDIR)\memchanDecls.h
207
208#-------------------------------------------------------------------------
209# Target names and paths ( shouldn't need changing )
210#-------------------------------------------------------------------------
211
212BINROOT		= .
213ROOT            = ..
214
215PRJIMPLIB	= $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
216PRJLIBNAME	= $(PROJECT)$(VERSION)$(SUFX).$(EXT)
217PRJLIB		= $(OUT_DIR)\$(PRJLIBNAME)
218
219PRJSTUBLIBNAME	= $(STUBPREFIX)$(VERSION).lib
220PRJSTUBLIB	= $(OUT_DIR)\$(PRJSTUBLIBNAME)
221
222CHANTEST        = $(OUT_DIR)\Chantest$(SUFX).$(EXT)
223CHANTESTOBJ     = $(TMP_DIR)\chantest.obj
224
225### Make sure we use backslash only.
226PRJ_INSTALL_DIR         = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
227BIN_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
228DOC_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
229SCRIPT_INSTALL_DIR	= $(PRJ_INSTALL_DIR)
230DEMO_INSTALL_DIR	= $(PRJ_INSTALL_DIR)
231INCLUDE_INSTALL_DIR	= $(_TCLDIR)\include
232LIB_INSTALL_DIR		= $(_TCLDIR)\lib
233
234### The following paths CANNOT have spaces in them.
235GENERICDIR	= $(ROOT)\generic
236WINDIR		= $(ROOT)\win
237LIBDIR          = $(ROOT)\library
238DOCDIR		= $(ROOT)\doc
239TOOLSDIR	= $(ROOT)\tools
240COMPATDIR	= $(ROOT)\compat
241ISAACDIR	= $(ROOT)\isaac
242
243#---------------------------------------------------------------------
244# Compile flags
245#---------------------------------------------------------------------
246
247!if !$(DEBUG)
248!if $(OPTIMIZING)
249### This cranks the optimization level to maximize speed
250cdebug	= -O2 $(OPTIMIZATIONS)
251!else
252cdebug	=
253!endif
254!else if "$(MACHINE)" == "IA64"
255### Warnings are too many, can't support warnings into errors.
256cdebug	= -Z7 -Od $(DEBUGFLAGS)
257!else
258cdebug	= -Z7 -WX $(DEBUGFLAGS)
259!endif
260
261### Declarations common to all compiler options
262cflags = -nologo -c $(COMPILERFLAGS) -Fp$(TMP_DIR)^\
263
264!if $(VCVER) > 7
265cflags  =$(cflags) -D_CRT_SECURE_NO_DEPRECATE
266!endif
267
268!if $(MSVCRT)
269!if $(DEBUG)
270crt = -MDd
271!else
272crt = -MD
273!endif
274!else
275!if $(DEBUG)
276crt = -MTd
277!else
278crt = -MT
279!endif
280!endif
281
282INCLUDES	= $(TCL_INCLUDES) -I"$(WINDIR)" -I"$(GENERICDIR)" -I"$(ISAACDIR)"
283BASE_CFLAGS	= $(cflags) $(cdebug) $(crt) $(INCLUDES)
284CON_CFLAGS	= $(cflags) $(cdebug) $(crt) -DCONSOLE
285MC_CFLAGS	= -DHAVE_STDLIB_H -DMEMCHAN_VERSION=\"$(MEMCHAN_VERSION)\" \
286		  -DBUILD_Memchan  -DDLL_BUILD -DHAVE_LTOA -D__WIN32__
287TCL_CFLAGS	= -DUSE_TCL_STUBS -DVERSION="\"$(DOTVERSION)\"" \
288		  $(BASE_CFLAGS) $(OPTDEFINES) $(MC_CFLAGS)
289
290#---------------------------------------------------------------------
291# Link flags
292#---------------------------------------------------------------------
293
294!if $(DEBUG)
295ldebug	= -debug:full -debugtype:cv
296!if $(MSVCRT)
297ldebug = $(ldebug) -nodefaultlib:msvcrt
298!endif
299!else
300ldebug	= -release -opt:ref -opt:icf,3
301!endif
302
303### Declarations common to all linker options
304lflags	= -nologo -machine:$(MACHINE) $(ldebug)
305
306!if $(PROFILE)
307lflags	= $(lflags) -profile
308!endif
309
310!if $(ALIGN98_HACK) && !$(STATIC_BUILD)
311### Align sections for PE size savings.
312lflags	= $(lflags) -opt:nowin98
313!else if !$(ALIGN98_HACK) && $(STATIC_BUILD)
314### Align sections for speed in loading by choosing the virtual page size.
315lflags	= $(lflags) -align:4096
316!endif
317
318!if $(LOIMPACT)
319lflags	= $(lflags) -ws:aggressive
320!endif
321
322dlllflags = $(lflags) -dll
323conlflags = $(lflags) -subsystem:console
324guilflags = $(lflags) -subsystem:windows
325baselibs   = $(TCLSTUBLIB)
326
327#---------------------------------------------------------------------
328# TclTest flags
329#---------------------------------------------------------------------
330
331!IF "$(TESTPAT)" != ""
332TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
333!ENDIF
334
335#---------------------------------------------------------------------
336# Project specific targets (EDIT)
337#---------------------------------------------------------------------
338
339all:	    setup $(PROJECT)
340stubs:      setup $(PRJSTUBLIB)
341$(PROJECT): setup $(PRJLIB) $(PRJSTUBLIB)
342chantest:   stubs $(CHANTEST)
343doc:        setup $(PRJDOCS)
344install:    install-binaries install-libraries install-docs
345
346# Tests need to ensure we load the right dll file we
347# have to handle the output differently on Win9x.
348#
349!if "$(OS)" == "Windows_NT"  || "$(MSVCDIR)" == "IDE"
350test: setup $(PROJECT)
351        $(TCLSH) <<
352load $(PRJLIB:\=/)
353cd "$(ROOT)/tests"
354set argv "$(TESTFLAGS)"
355source all
356<<
357!else
358test: setup $(PROJECT)
359        echo Please wait while the test results are collected
360        $(TCLSH) << >tests.log
361load $(PRJLIB:\=/)
362cd "$(ROOT)/tests"
363set argv "$(TESTFLAGS)"
364source all
365<<
366        type tests.log | more
367!endif
368
369$(CHANTEST): $(CHANTESTOBJ)
370	$(link32) $(dlllflags) -out:$@ $** $(PRJSTUBLIB) $(baselibs)
371	-@del $*.exp
372
373setup:
374	@if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
375	@if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
376
377$(PRJLIB): $(DLLOBJS) $(DLLRES)
378!if $(STATIC_BUILD)
379	$(lib32) -nologo -out:$@ @<<
380$**
381<<
382!else
383	$(link32) $(dlllflags) -out:$@ $(baselibs) @<<
384$**
385<<
386	$(_VC_MANIFEST_EMBED_DLL)
387	-@del $*.exp
388!endif
389
390$(PRJSTUBLIB): $(PRJSTUBOBJS)
391	$(lib32) -nologo -out:$@ $(PRJSTUBOBJS)
392
393$(TMP_DIR)\chantest.obj: $(GENERICDIR)\chantest.c
394    $(cc32) -nologo -DUSE_TCL_STUBS -DUSE_MEMCHAN_STUBS $(BASE_CFLAGS) \
395	$(OPTDEFINES) $(INCLUDES) -Fo$(TMP_DIR)\ -c $**
396
397#---------------------------------------------------------------------
398# Implicit rules
399#---------------------------------------------------------------------
400
401{$(WINDIR)}.c{$(TMP_DIR)}.obj::
402    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
403$<
404<<
405
406{$(ISAACDIR)}.c{$(TMP_DIR)}.obj::
407    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
408$<
409<<
410
411{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
412    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
413$<
414<<
415
416{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
417    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
418$<
419<<
420
421{$(WINDIR)}.rc{$(TMP_DIR)}.res:
422	$(rc32) -fo $@ -r -i "$(GENERICDIR)" -D__WIN32__ \
423		-DCOMMAVERSION=$(DOTVERSION:.=,),0 \
424		-DDOTVERSION=\"$(DOTVERSION)\" \
425		-DVERSION=\"$(VERSION)$(SUFX)\" \
426!if $(DEBUG)
427	-d DEBUG \
428!endif
429!if $(TCL_THREADS)
430	-d TCL_THREADS \
431!endif
432!if $(STATIC_BUILD)
433	-d STATIC_BUILD \
434!endif
435	$<
436
437DOC2HTML = $(TCLSH) "$(TOOLSDIR)\mpexpand.tcl" html
438
439{$(DOCDIR)}.man{$(OUT_DIR)}.html:
440	$(DOC2HTML) $< $@
441        @$(TCLSH) <<
442set name $(@:\=/)
443set f [open $$name r]; set d [read $$f]; close $$f
444set d [regsub {</head>} $$d {<link rel="stylesheet" href="manpage.css" type="text/css"></head>}]
445set f [open $$name w]; puts -nonewline $$f $$d; close $$f
446<<
447
448
449.SUFFIXES:
450.SUFFIXES:.c .rc .man
451
452#---------------------------------------------------------------------
453# Installation. (EDIT)
454#
455# You may need to modify this section to reflect the final distribution
456# of your files and possibly to generate documentation.
457#
458#---------------------------------------------------------------------
459
460install-binaries:
461	@echo Installing binaries to '$(SCRIPT_INSTALL_DIR)'
462	@if not exist $(SCRIPT_INSTALL_DIR)\nul mkdir "$(SCRIPT_INSTALL_DIR)"
463	@if not exist $(LIB_INSTALLDIR)\nul mkdir "$(LIB_INSTALL_DIR)"
464	@if not exist $(INCLUDE_INSTALL_DIR)\nul mkdir "$(INCLUDE_INSTALL_DIR)"
465	@$(CPY) $(PRJLIB)     "$(SCRIPT_INSTALL_DIR)" >NUL
466	@$(CPY) $(PRJIMPLIB)  "$(SCRIPT_INSTALL_DIR)" >NUL
467	@echo Installing stubs library to '$(LIB_INSTALL_DIR)'
468	@$(CPY) $(PRJSTUBLIB) "$(LIB_INSTALL_DIR)" >NUL
469	@echo Installing headers to '$(INCLUDE_INSTALL_DIR)'
470	@for %i in ($(PRJHDRS)) do @$(CPY) %i "$(INCLUDE_INSTALL_DIR)" >NUL
471
472# "fix font locking
473
474install-libraries:
475	@echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
476	@if exist $(LIBDIR)\nul $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)" >NUL
477	@type << >"$(SCRIPT_INSTALL_DIR)\pkgIndex.tcl"
478# Handcrafted pkgIndex for memchan.
479if {[info exists ::tcl_platform(debug)]} {
480    package ifneeded $(PROJECT) $(DOTVERSION) [list load [file join $$dir $(PROJECT)$(VERSION)g.$(EXT)]]
481} else {
482    package ifneeded $(PROJECT) $(DOTVERSION) [list load [file join $$dir $(PROJECT)$(VERSION).$(EXT)]]
483}
484<<
485
486install-docs: $(PRJDOCS)
487	@echo Installing documentation to '$(DOC_INSTALL_DIR)'
488	@if not exist $(DOC_INSTALL_DIR)\NUL mkdir $(DOC_INSTALL_DIR)
489	@$(CPY) "$(DOCDIR)\manpage.css" "$(DOC_INSTALL_DIR)\" >NUL
490	@for %i in ($(PRJDOCS)) do @$(CPY) %i "$(DOC_INSTALL_DIR)\" > NUL
491
492#---------------------------------------------------------------------
493# Clean up
494#---------------------------------------------------------------------
495
496clean:
497	@if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
498	@if exist $(WINDIR)\version.vc del $(WINDIR)\version.vc
499
500realclean: clean
501	@if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
502
503distclean: realclean
504	@if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
505	@if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
506