######################################################################
# makefile.vc --
#
# Microsoft Visual C++ descriptions file for their program
# maintenance utility -> nmake.exe that builds the Tcl thread
# extension.  See README.txt for commandline options and instructions.
#
# RCS: @(#) $Id: makefile.vc,v 1.15 2000/08/24 01:13:06 welch Exp $
######################################################################


######################################################################
# 2 bug fixes needed for VC++ 6.0's nmake tool.

# Reset the version *string* back to the integer it's supposed to be.
# more entries will have to be made here for all subsiquent releases
# until they fix it.
#
_NMAKE_VER  = $(_NMAKE_VER:6.00.8168.0=600)

!if $(_NMAKE_VER) >= 600
# non existent directories as dependents are either considered always
# UP-TO-DATE or just plain don't work for calling their target command
#
HAVE_BAD_NODIR_TS   = 1
!endif
######################################################################


!include "config.vc"


######################################################################
# Commandline checks and over-rides
######################################################################


# Set NODEBUG to 0 to compile with symbols.
#
!ifndef NODEBUG
NODEBUG		= 1
!endif

# Set STATIC_BUILD to 1 to make a static library rather
# than a dll.
#
!ifndef STATIC_BUILD
STATIC_BUILD	= 0
!endif

# Set USE_TCL_STUBS to 0 to disable Stubs support.  Stubs
# will work fine even with static libraries, but you may
# disable it if you want to.
#
!ifndef USE_TCL_STUBS
USE_TCL_STUBS	= 1
!endif

# Set NOMSVCRT to 1 to use libcmt(d).lib instead of the
# dynamic run-time.
#
!ifndef NOMSVCRT
!if $(STATIC_BUILD)
NOMSVCRT	= 1
!else
NOMSVCRT	= 0
!endif
!endif

!if $(STATIC_BUILD) == 0 && $(NOMSVCRT) == 1
!error "The static runtime in a loadable (dll) extension is a useless configuration that will cause abnormal and unnecessary code bloat."
!endif


######################################################################
# Macro setups
######################################################################


# remember to change thread.h as well when this changes
#
VER	= 21

!if $(NODEBUG)
TMPDIRNAMEPREFIX = Release
DBGX =
!else
TMPDIRNAMEPREFIX = Debug
DBGX = d
!endif

TMPDIRNAME	=

!if $(STATIC_BUILD)
!if $(NOMSVCRT) == 0
TMPDIRNAME = $(TMPDIRNAMEPREFIX)_StaticX
STCX	= x
!else
TMPDIRNAME = $(TMPDIRNAMEPREFIX)_Static
STCX	= s
!endif
OUTEXT	= lib
!else
STCX	=
OUTEXT	= dll
!endif

!if "$(TMPDIRNAME)" == ""
TMPDIRNAME	= $(TMPDIRNAMEPREFIX)
!endif

SOURCEROOT	= ..\..
GENERICDIR	= $(SOURCEROOT)\generic
TESTDIR		= $(SOURCEROOT)\tests
WINDIR		= $(SOURCEROOT)\win\vc
TMP_DIR		= $(WINDIR)\$(TMPDIRNAME)

!ifndef OUT_DIR
OUT_DIR		= $(WINDIR)\$(TMPDIRNAME)
!endif

THREADLIB	= $(OUT_DIR)\thread$(VER)$(STCX)$(DBGX).$(OUTEXT)
THREADLIBBASE	= $(OUT_DIR)\thread$(VER)$(STCX)$(DBGX)

# Is TCLROOT pointing to the sources or the install ?
#
!if $(ISTCLINSTALL)
TCLSTUBSLIB	= "$(TCLROOT)\lib\tclstub$(TCLMAJOR)$(TCLMINOR).lib"
TCLLIB		= "$(TCLROOT)\lib\tcl$(TCLMAJOR)$(TCLMINOR).lib"
TCLSH_PROG	= "$(TCLROOT)\bin\tclsh$(TCLMAJOR)$(TCLMINOR).exe"
!else
TCLSTUBSLIB	= "$(TCLROOT)\win\$(TMPDIRNAMEPREFIX)\tclstub$(TCLMAJOR)$(TCLMINOR)$(DBGX).lib"
TCLLIB		= "$(TCLROOT)\win\$(TMPDIRNAMEPREFIX)\tcl$(TCLMAJOR)$(TCLMINOR)$(DBGX).lib"
TCLSH_PROG	= "$(TCLROOT)\win\$(TMPDIRNAMEPREFIX)\tclsh$(TCLMAJOR)$(TCLMINOR)$(DBGX).exe"
!endif

THREADOBJS	= \
	$(TMP_DIR)\threadCmd.obj \
	$(TMP_DIR)\threadSpCmd.obj \
	$(TMP_DIR)\threadSvCmd.obj \
!if $(STATIC_BUILD) == 0
	$(TMP_DIR)\resource.obj
!endif


######################################################################
# Compile flags
######################################################################


!if $(NODEBUG)
cdebug = -O2 -Gs -GD
!else
cdebug = -Z7 -Od -WX
!endif

!if $(NOMSVCRT)
crt	= -MT$(DBGX)
!else
crt	= -MD$(DBGX)
!endif

!if $(USE_TCL_STUBS)
ctclstubs   = -DUSE_TCL_STUBS
!else
ctclstubs   =
!endif

# Is TCLROOT pointing to the sources or the install?
#
!if $(ISTCLINSTALL)
TCLINCLUDE	= -I"$(TCLROOT)\include"
!else
TCLINCLUDE	= -I"$(TCLROOT)\generic"
!endif

cflags = -nologo -c -W3 -YX $(cdebug) $(crt) -Fp$(TMP_DIR)\ \
	-Fo$(TMP_DIR)\ $(TCLINCLUDE)


######################################################################
# Link flags
######################################################################


!if $(NODEBUG)
ldebug = -opt:ref -release
!else
ldebug = -opt:noref -debug -debugtype:cv
!endif

# declarations common to all linker options
#
lcommon = -nologo -incremental:no -machine:$(MACHINE) $(ldebug)

!if $(NOMSVCRT)
lrt	= libcmt$(DBGX).lib
!else
lrt	= msvcrt$(DBGX).lib
!endif

lflags = $(lcommon) -machine:$(MACHINE) -subsystem:windows -dll -link50compat $(lrt)

!if $(USE_TCL_STUBS)
# A reference to msvcrt.lib happens to be embedded into the
# Stubs library.  This is a bug with no current solution.
# We need to strip this reference at link-time.
#
ltclstubs	    = -nodefaultlib:msvcrt.lib $(TCLSTUBSLIB)
!else
# Fall back to linking with the import library
#
ltclstubs	    = $(TCLLIB)
!endif


######################################################################
# Project specific targets
######################################################################


all: setup $(THREADLIB)

setup:
	@$(vcvars) > nul
	@if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR) &\
		echo Created directory '$(TMP_DIR)'
	@if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR) &\
		echo Created directory '$(OUT_DIR)'

test: all
    $(TCLSH_PROG) <<
regsub -all {\\} {$(THREADLIB)} {/} threadlib
package ifneeded Thread 2.0 [list load $$threadlib]
regsub -all {\\} {$(TESTDIR)} {/} testdir
source [file join $$testdir all.tcl]
<<nokeep

!if $(STATIC_BUILD)
$(THREADLIB) : $(THREADOBJS)
	@echo Creating Static Library...
	$(lib32) -nologo -machine:$(MACHINE) -out:$@ @<<
!else
$(THREADLIB) : $(THREADOBJS) $(TCLSTUBSLIB)
	@echo Linking...
	$(link32) $(lflags) -out:$@ $(ltclstubs) @<<
!endif
$(THREADOBJS)
<<nokeep
!if $(STATIC_BUILD) == 0
	-del $(THREADLIBBASE).exp $(THREADLIBBASE).lib
!endif


######################################################################
# Inference rules.  Use batch-mode when supported.
######################################################################


!if $(_NMAKE_VER) < 162
{$(GENERICDIR)}.c{$(TMP_DIR)}.obj :
!else
{$(GENERICDIR)}.c{$(TMP_DIR)}.obj ::
	@echo Compiling...
!endif
	$(cc32) $(cflags) $(ctclstubs) -DTCL_THREADS=1 @<<
$<
<<nokeep


######################################################################
# Special case targets
######################################################################


$(TMP_DIR)\thread.res : $(WINDIR)\thread.rc
	@echo Compiling resources...
	$(rc32) -fo"$@" -i "$(GENERICDIR)" -i "$(TCLROOT)\generic" -r \
		-DNODEBUG=$(NODEBUG) -DRESOURCE_INCLUDED $(WINDIR)\thread.rc

$(TMP_DIR)\resource.obj : $(TMP_DIR)\thread.res
	$(cvtres32) -nologo -machine:$(MACHINE) -out:$@ $(TMP_DIR)\thread.res


######################################################################
# Dedependency rules
######################################################################


$(WINDIR)\thread.rc : $(GENERICDIR)\thread.h
$(GENERICDIR)\threadCmd.c : $(GENERICDIR)\thread.h
$(GENERICDIR)\threadSpCmd.c : $(GENERICDIR)\thread.h
$(GENERICDIR)\threadSpCmd.c : $(GENERICDIR)\thread.h


######################################################################
# Cleanup
######################################################################


clean:
	@echo Cleaning non-output build files...
	@if exist $(TMP_DIR)\nul rmdir /s /q $(TMP_DIR)

hose: clean
	@echo Deleting output file $(THREADLIB) ...
	@del $(THREADLIB)


.SUFFIXES:
.SUFFIXES: .c
