#------------------------------------------------------------- -*- makefile -*-
#
# Nmake makefile for building cffi.
#
# Basic build, test and install using libffi
#   nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\tcl EXTDIR=c:\path\to\libffi
# Basic build, test and install using dyncall
#   nmake /s /nologo /f makefile.vc OPTS=dyncall INSTALLDIR=c:\path\to\tcl EXTDIR=c:\path\to\dyncall
#
# The EXTDIR directory should contain "include" and "lib" directories for
# dyncall/libffi depending on the library being used. If undefined, it will default
# to ../external-libs/win/$(BUILDDIRTOP) where BUILDDIRTOP is defined by rules-ext.vc
# above based on architecture, compiler version and build mode (debug/release).
# See the BUILD.md in top level directory for building dyncall and libffi itself.
#
# To test and install,
#   nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\tcl test
#   nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\tcl install
#
# For other build options (debug, static etc.)
# 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.
#
#------------------------------------------------------------------------------
# The name of the package
PROJECT = cffi

!include "rules-ext.vc"

!if [nmakehlp -f $(OPTS) "dyncall"]
!message *** Using dyncall.
USE_DYNCALL = 1
KEYFILE = dyncall.h
!else
!message *** Using libffi.
USE_DYNCALL = 0
KEYFILE = ffi.h
!endif

# Override shared library installation directory
!if "$(ARCH)" == "AMD64"
DLLSUBDIR = win32-x86_64
!else
DLLSUBDIR = win32-ix86
!endif


PRJ_DEFINES = $(PRJ_DEFINES)

!ifndef EXTDIR
EXTDIR = $(ROOT)\external-libs\win\$(BUILDDIRTOP)
!endif
!if exist("$(EXTDIR)\include\$(KEYFILE)")
!message *** Using dyncall library in $(EXTDIR)
!else
!message *** Could not locate $(KEYFILE) in $(EXTDIR).
!message *** Please check path or see instructions in makefile.vc
!error Could not locate external libraries.
!endif

# Define the object files and resource file that make up the extension.
PRJ_OBJS = \
	$(TMP_DIR)\tclCffi.obj \
	$(TMP_DIR)\tclCffiAlias.obj \
	$(TMP_DIR)\tclCffiCallback.obj \
	$(TMP_DIR)\tclCffiEnum.obj \
	$(TMP_DIR)\tclCffiFunction.obj \
	$(TMP_DIR)\tclCffiHelp.obj \
	$(TMP_DIR)\tclCffiLoad.obj \
	$(TMP_DIR)\tclCffiMemory.obj \
	$(TMP_DIR)\tclCffiNames.obj \
	$(TMP_DIR)\tclCffiPointer.obj \
	$(TMP_DIR)\tclCffiPrototype.obj \
	$(TMP_DIR)\tclCffiStruct.obj \
	$(TMP_DIR)\tclCffiTypes.obj \
	$(TMP_DIR)\tclCffiWrapper.obj \
	$(TMP_DIR)\memlifo.obj

!if $(USE_DYNCALL)
PRJ_OBJS = $(PRJ_OBJS) $(TMP_DIR)\tclCffiDyncall.obj
!else
PRJ_OBJS = $(PRJ_OBJS) $(TMP_DIR)\tclCffiLibffi.obj
!endif

PRJ_TEST_OBJS = $(TMP_DIR)\tclCffiTest.obj
PRJ_TEST_DLL = $(OUT_DIR)\cffitest.dll

HEADERS = \
	$(GENERICDIR)\tclCffiInt.h \
	$(GENERICDIR)\tclhBase.h \
	$(GENERICDIR)\tclhPointer.h \
	$(GENERICDIR)\memlifo.h \
	$(GENERICDIR)\tclhObj.h

PRJ_INCLUDES = -I $(EXTDIR)\include

PRJ_DEFINES = -D_CRT_SECURE_NO_WARNINGS

!if $(USE_DYNCALL)
PRJ_DEFINES = $(PRJ_DEFINES) -DCFFI_USE_DYNCALL
PRJ_LIBS = $(EXTDIR)\lib\dyncall_s.lib $(EXTDIR)\lib\dynload_s.lib $(EXTDIR)\lib\dyncallback_s.lib
!else
PRJ_DEFINES = $(PRJ_DEFINES) -DFFI_BUILDING -DCFFI_USE_LIBFFI
PRJ_LIBS = $(EXTDIR)\lib\libffi.lib
!endif

# Define the standard targets
# We do not use the standard predefined install targets because we want
# to load binaries from platform-specific subdirectories of the package
# directory.
DISABLE_TARGET_install = 1
!include "$(_RULESDIR)\targets.vc"

pkgindex: default-pkgindex-tea

# The default install target only installs binaries and scripts so add
# an additional target for our documentation. Note this *adds* a target
# since no commands are listed after it. The original targets for
# install (from targets.vc) will remain.
install: $(PRJLIB) default-install-docs-html default-install-scripts
	@echo Installing binaries to '$(LIB_INSTALL_DIR)\$(DLLSUBDIR)'
	@if not exist "$(LIB_INSTALL_DIR)\$(DLLSUBDIR)" mkdir "$(LIB_INSTALL_DIR)\$(DLLSUBDIR)"
	@$(CPY) $(PRJLIB) "$(LIB_INSTALL_DIR)\$(DLLSUBDIR)" >NUL

$(PRJ_OBJS): $(HEADERS) $(ROOT)\configure.ac

# Build test DLL
$(PROJECT): testdll
testdll: $(PRJ_TEST_DLL)
$(PRJ_TEST_OBJS): $(HEADERS)
# NOTE - we intentionally do NOT link Tcl libraries. The DLL should be
# loaded outside of the Tcl infrastructure.
$(PRJ_TEST_DLL): $(PRJ_TEST_OBJS)
	$(link32) $(dlllflags) -out:$@ $**
