# makefile.vc --                                               -*- Makefile -*-
#
# Microsoft Visual C++ makefile for use with nmake.exe v1.62+ (VC++ 5.0+)
#
# This makefile is based upon the Tcl 8.4 Makefile.vc and modified to 
# make it suitable as a general package makefile. Look for the word EDIT
# which marks sections that may need modification. As a minumum you will
# need to change the PROJECT, DOTVERSION and DLLOBJS variables to values
# relevant to your package.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
# 
# Copyright (c) 1995-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-2000 Ajuba Solutions.
# Copyright (c) 2001 ActiveState Corporation.
# Copyright (c) 2001-2002 David Gravereaux.
# Copyright (c) 2003-2006 Pat Thoyts
#
#-------------------------------------------------------------------------
# RCS: @(#)$Id$
#-------------------------------------------------------------------------

# Check to see we are configured to build with MSVC (MSDEVDIR or MSVCDIR)
# or with the MS Platform SDK (MSSDK). Visual Studio .NET 2003 and 2005 define
# VCINSTALLDIR instead. The MSVC Toolkit release defines yet another.
!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(MSSDK) && !defined(VCINSTALLDIR) && !defined(VCToolkitInstallDir)
MSG = ^
You need to run vcvars32.bat from Developer Studio or setenv.bat from the^
Platform SDK first to setup the environment.  Jump to this line to read^
the build instructions.
!error $(MSG)
!endif

#------------------------------------------------------------------------------
# HOW TO USE this makefile:
#
# 1)  It is now necessary to have %MSVCDir% set in the environment.  This is
#     used  as a check to see if vcvars32.bat had been run prior to running
#     nmake or during the installation of Microsoft Visual C++, MSVCDir had
#     been set globally and the PATH adjusted.  Either way is valid.
#
#     You'll need to run vcvars32.bat contained in the MsDev's vc(98)/bin
#     directory to setup the proper environment, if needed, for your current
#     setup.  This is a needed bootstrap requirement and allows the swapping of
#     different environments to be easier.
#
# 2)  To use the Platform SDK (not expressly needed), run setenv.bat after
#     vcvars32.bat according to the instructions for it.  This can also turn on
#     the 64-bit compiler, if your SDK has it.
#
# 3)  Targets are:
#	all       -- Builds everything.
#       <project> -- Builds the project (eg: nmake sample)
#	test      -- Builds and runs the test suite.
#	install   -- Installs the built binaries and libraries to $(INSTALLDIR)
#		     in an appropriate subdirectory.
#	clean/realclean/distclean -- varying levels of cleaning.
#
# 4)  Macros usable on the commandline:
#	INSTALLDIR=<path>
#		Sets where to install Tcl from the built binaries.
#		C:\Progra~1\Tcl is assumed when not specified.
#
#	OPTS=static,msvcrt,staticpkg,threads,symbols,profile,loimpact,none
#		Sets special options for the core.  The default is for none.
#		Any combination of the above may be used (comma separated).
#		'none' will over-ride everything to nothing.
#
#		static  =  Builds a static library of the core instead of a
#			   dll.  The shell will be static (and large), as well.
#		msvcrt  =  Effects the static option only to switch it from
#			   using libcmt(d) as the C runtime [by default] to
#			   msvcrt(d). This is useful for static embedding
#			   support.
#		staticpkg = Effects the static option only to switch
#			   tclshXX.exe to have the dde and reg extension linked
#			   inside it.
#		nothreads = Turns off multithreading support (not recommended)
#		thrdalloc = Use the thread allocator (shared global free pool).
#		symbols =  Adds symbols for step debugging.
#		profile =  Adds profiling hooks.  Map file is assumed.
#		loimpact =  Adds a flag for how NT treats the heap to keep memory
#			   in use, low.  This is said to impact alloc performance.
#
#	STATS=memdbg,compdbg,none
#		Sets optional memory and bytecode compiler debugging code added
#		to the core.  The default is for none.  Any combination of the
#		above may be used (comma separated).  'none' will over-ride
#		everything to nothing.
#
#		memdbg   = Enables the debugging memory allocator.
#		compdbg  = Enables byte compilation logging.
#
#	MACHINE=(IX86|IA64|ALPHA|AMD64)
#		Set the machine type used for the compiler, linker, and
#		resource compiler.  This hook is needed to tell the tools
#		when alternate platforms are requested.  IX86 is the default
#		when not specified. If the CPU environment variable has been
#		set (ie: recent Platform SDK) then MACHINE is set from CPU.
#
#	TMP_DIR=<path>
#	OUT_DIR=<path>
#		Hooks to allow the intermediate and output directories to be
#		changed.  $(OUT_DIR) is assumed to be 
#		$(BINROOT)\(Release|Debug) based on if symbols are requested.
#		$(TMP_DIR) will de $(OUT_DIR)\<buildtype> by default.
#
#	TESTPAT=<file>
#		Reads the tests requested to be run from this file.
#
#	CFG_ENCODING=encoding
#		name of encoding for configuration information. Defaults
#		to cp1252
#
# 5)  Examples:
#
#	Basic syntax of calling nmake looks like this:
#	nmake [-nologo] -f makefile.vc [target|macrodef [target|macrodef] [...]]
#
#                        Standard (no frills)
#       c:\tcl_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat
#       Setting environment for using Microsoft Visual C++ tools.
#       c:\tcl_src\win\>nmake -f makefile.vc all
#       c:\tcl_src\win\>nmake -f makefile.vc install INSTALLDIR=c:\progra~1\tcl
#
#                         Building for Win64
#       c:\tcl_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat
#       Setting environment for using Microsoft Visual C++ tools.
#       c:\tcl_src\win\>c:\progra~1\platfo~1\setenv.bat /pre64 /RETAIL
#       Targeting Windows pre64 RETAIL
#       c:\tcl_src\win\>nmake -f makefile.vc MACHINE=IA64
#
#------------------------------------------------------------------------------
#==============================================================================
###############################################################################
#------------------------------------------------------------------------------

!if !exist("makefile.vc")
MSG = ^
You must run this makefile only from the directory it is in.^
Please `cd` to its location first.
!error $(MSG)
!endif

#-------------------------------------------------------------------------
# Project specific information (EDIT)
#
# You should edit this with the name and version of your project. This
# information is used to generate the name of the package library and
# it's install location.
#
# For example, the sample extension is  going to build sample04.dll and
# would install it into $(INSTALLDIR)\lib\sample04
#
# You need to specify the object files that need to be linked into your
# binary here.
#
#-------------------------------------------------------------------------

PROJECT = tnc
!include "..\..\..\win\rules.vc"

DOTVERSION      = 0.3.0
VERSION         = $(DOTVERSION:.=)
STUBPREFIX      = $(PROJECT)stub

DLLOBJS = $(TMP_DIR)\tnc.obj

TDOM_DOTVERSION      = 0.8.3
TDOMVER             = $(TDOM_DOTVERSION:.=)

BINROOT		= .
# tdom root
ROOT            = ..\..\..

PRJIMPLIB	= $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
PRJLIBNAME	= $(PROJECT)$(VERSION)$(SUFX).$(EXT)
PRJLIB		= $(OUT_DIR)\$(PRJLIBNAME)

### Make sure we use backslash only.
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)
INCLUDE_INSTALL_DIR	= $(_TCLDIR)\include

#---------------------------------------------------------------------
# Compile flags
#---------------------------------------------------------------------

!if !$(DEBUG)
!if $(OPTIMIZING)
### This cranks the optimization level to maximize speed
cdebug	= $(OPTIMIZATIONS)
!else
cdebug	=
!endif
!else if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64"
### Warnings are too many, can't support warnings into errors.
cdebug	= -Zi -Od $(DEBUGFLAGS)
!else
cdebug	= -Zi -WX $(DEBUGFLAGS)
!endif

### Declarations common to all compiler options
cwarn = -D _CRT_SECURE_NO_DEPRECATE -D _CRT_NONSTDC_NO_DEPRECATE
cflags = -nologo -c $(COMPILERFLAGS) $(cwarn) -Fp$(TMP_DIR)^\

!if $(MSVCRT)
!if $(DEBUG) && !$(UNCHECKED)
crt = -MDd
!else
crt = -MD
!endif
!else
!if $(DEBUG) && !$(UNCHECKED)
crt = -MTd
!else
crt = -MT
!endif
!endif

!if !$(STATIC_BUILD)
cflags = $(cflags) -DUSE_TCL_STUBS -DUSE_TDOM_STUBS
!if defined(TKSTUBLIB)
cflags = $(cflags) -DUSE_TK_STUBS
!endif
!endif

TDOMLIBPATH    = "$(ROOT)\win\$(BUILDDIRTOP)"

TNCDIR         = $(ROOT)\extensions\tnc
WINDIR		= $(TNCDIR)\win
GENERICDIR     = $(ROOT)\generic
EXPATDIR    = $(ROOT)\expat
TCLINCDIR      = $(INSTALLDIR)\Include

DEFS            = -DHAVE_MEMMOVE=1 -DXML_DTD=1 -DXML_NS=1 -DTDOM_NO_UNKNOWN_CMD=1
INCLUDES	= -I"$(WINDIR)" -I"$(TNCDIR)" -I"$(GENERICDIR)" -I"$(EXPATDIR)" $(TCL_INCLUDES)
BASE_CFLAGS	= $(cflags) $(cdebug) $(crt) $(INCLUDES)
CON_CFLAGS	= $(cflags) $(cdebug) $(crt) -DCONSOLE
TCL_CFLAGS      = -DPACKAGE_NAME="\"$(PROJECT)\"" \
		  -DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
		  -DTDOM_PACKAGE_VERSION="\"$(TDOM_DOTVERSION)\"" \
		  $(BASE_CFLAGS) $(OPTDEFINES) $(DEFS) $(DEFS_EXPAT)


#---------------------------------------------------------------------
# Link flags
#---------------------------------------------------------------------

!if $(DEBUG)
ldebug	= -debug:full -debugtype:cv
!if $(MSVCRT)
ldebug = $(ldebug) -nodefaultlib:msvcrt
!endif
!else
ldebug	= -release -opt:ref -opt:icf,3
!endif

### Declarations common to all linker options
lflags	= -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)

!if $(PROFILE)
lflags	= $(lflags) -profile
!endif

!if $(ALIGN98_HACK) && !$(STATIC_BUILD)
### Align sections for PE size savings.
lflags	= $(lflags) -opt:nowin98
!else if !$(ALIGN98_HACK) && $(STATIC_BUILD)
### Align sections for speed in loading by choosing the virtual page size.
lflags	= $(lflags) -align:4096
!endif

!if $(LOIMPACT)
lflags	= $(lflags) -ws:aggressive
!endif

dlllflags = $(lflags) -dll
conlflags = $(lflags) -subsystem:console
guilflags = $(lflags) -subsystem:windows
!if !$(STATIC_BUILD)
baselibs  = $(TCLSTUBLIB) $(TDOMLIBPATH)\tdomstub$(TDOMVER).lib
!if defined(TKSTUBLIB)
baselibs  = $(baselibs) $(TKSTUBLIB)
!endif
!endif

# Avoid 'unresolved external symbol __security_cookie' errors.
# c.f. http://support.microsoft.com/?id=894573
!if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64"
baselibs   = $(baselibs) bufferoverflowU.lib
!endif

#---------------------------------------------------------------------
# TclTest flags
#---------------------------------------------------------------------

!IF "$(TESTPAT)" != ""
TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
!ENDIF

#---------------------------------------------------------------------
# Project specific targets (EDIT)
#---------------------------------------------------------------------

all:	    setup $(PROJECT)
$(PROJECT): setup $(PRJLIB)
install:    install-binaries install-libraries install-docs

# Tests need to ensure we load the right dll file we
# have to handle the output differently on Win9x.
#
!if "$(OS)" == "Windows_NT"  || "$(MSVCDIR)" == "IDE"
test: setup $(PROJECT)
        set TCL_LIBRARY=$(ROOT)/library
        $(TCLSH) <<
load $(PRJLIB:\=/)
source [file join $(LIBDIR:\=/) tdom.tcl]
cd "$(ROOT)/tests"
set argv "$(TESTFLAGS)"
source all.tcl
<<
!else
test: setup $(PROJECT)
        echo Please wait while the test results are collected
        set TCL_LIBRARY=$(ROOT)/library
        $(TCLSH) << >tests.log
load $(PRJLIB:\=/)
source [file join $(LIBDIR:\=/) tdom.tcl]
cd "$(ROOT)/tests"
set argv "$(TESTFLAGS)"
source all.tcl
<<
        type tests.log | more
!endif

setup:
	@if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
	@if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)

# See <tcl>/win/coffbase.txt for extension base addresses.
$(PRJLIB): $(DLLOBJS)
!if $(STATIC_BUILD)
	$(lib32) -nologo -out:$@ @<<
$**
<<
!else
	$(link32) $(dlllflags)  -out:$@ $(baselibs) @<<
$**
<<
	$(_VC_MANIFEST_EMBED_DLL)
	-@del $*.exp
!endif

#---------------------------------------------------------------------
# Implicit rules
#---------------------------------------------------------------------

{$(WINDIR)}.c{$(TMP_DIR)}.obj::
    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
$<
<<

{$(TNCDIR)}.c{$(TMP_DIR)}.obj::
    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
$<
<<

{$(WINDIR)}.rc{$(TMP_DIR)}.res:
	$(rc32) -fo $@ -r -i "$(GENERICDIR)" -D__WIN32__ \
                -DCOMMAVERSION=$(DOTVERSION:.=,),0 \
                -DDOTVERSION=\"$(DOTVERSION)\" \
                -DVERSION=\"$(VERSION)$(SUFX)\" \
!if $(DEBUG)
	-d DEBUG \
!endif
!if $(TCL_THREADS)
	-d TCL_THREADS \
!endif
!if $(STATIC_BUILD)
	-d STATIC_BUILD \
!endif
	$<

.SUFFIXES:
.SUFFIXES:.c .rc

#-------------------------------------------------------------------------
# Explicit dependency rules
#
#-------------------------------------------------------------------------


#---------------------------------------------------------------------
# Installation. (EDIT)
#
# You may need to modify this section to reflect the final distribution
# of your files and possibly to generate documentation.
#
#---------------------------------------------------------------------

install-binaries:
	@echo Installing binaries to '$(SCRIPT_INSTALL_DIR)'
	@if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
	@$(CPY) $(PRJLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
	@$(CPY) $(PRJSTUBLIB) "$(SCRIPT_INSTALL_DIR)" >NUL

install-libraries:
        @echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
        @type << >"$(SCRIPT_INSTALL_DIR)\pkgIndex.tcl"
    package ifneeded $(PROJECT) $(DOTVERSION) "[list load [file join $$dir $(PROJECT)$(VERSION)$(SUFX).$(EXT)] $(PROJECT)]"
<<

install-docs:
#	@echo Installing documentation files to '$(DOC_INSTALL_DIR)'
#	@if exist $(DOCDIR) $(CPY) $(DOCDIR)\*.n "$(DOC_INSTALL_DIR)"

#---------------------------------------------------------------------
# Clean up
#---------------------------------------------------------------------

clean:
	@if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
	@if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc
	@if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
	@if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
	@if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch

realclean: clean
	@if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)

distclean: realclean
	@if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
	@if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
