summaryrefslogtreecommitdiffstats
path: root/win
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2017-12-14 13:41:37 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2017-12-14 13:41:37 (GMT)
commit9c5c1a721f5b27c1d86ef4824de5c6ecd00d4fce (patch)
tree7c52fd5cbae6e10d0aab9dd1f027344ff67140b6 /win
parentbf868c1c56292a44ff5faeef5b348408554cab1a (diff)
parent556dc3036e36d2449fe4feaece94487adfd745b8 (diff)
downloadtcl-9c5c1a721f5b27c1d86ef4824de5c6ecd00d4fce.zip
tcl-9c5c1a721f5b27c1d86ef4824de5c6ecd00d4fce.tar.gz
tcl-9c5c1a721f5b27c1d86ef4824de5c6ecd00d4fce.tar.bz2
merge core-8-branch. Fully tested now, works fine.
Diffstat (limited to 'win')
-rw-r--r--win/nmakehlp.c105
-rw-r--r--win/rules-ext.vc19
-rw-r--r--win/rules.vc87
-rw-r--r--win/targets.vc48
4 files changed, 231 insertions, 28 deletions
diff --git a/win/nmakehlp.c b/win/nmakehlp.c
index 0439d1c..025bb99 100644
--- a/win/nmakehlp.c
+++ b/win/nmakehlp.c
@@ -39,7 +39,6 @@
#endif
-
/* protos */
static int CheckForCompilerFeature(const char *option);
@@ -47,6 +46,7 @@ static int CheckForLinkerFeature(const char **options, int count);
static int IsIn(const char *string, const char *substring);
static int SubstituteFile(const char *substs, const char *filename);
static int QualifyPath(const char *path);
+static int LocateDependency(const char *keyfile);
static const char *GetVersionFromFile(const char *filename, const char *match, int numdots);
static DWORD WINAPI ReadFromPipe(LPVOID args);
@@ -172,6 +172,18 @@ main(
return 2;
}
return QualifyPath(argv[2]);
+
+ case 'L':
+ if (argc != 3) {
+ chars = snprintf(msg, sizeof(msg) - 1,
+ "usage: %s -L keypath\n"
+ "Emit the fully qualified path of directory containing keypath\n"
+ "exitcodes: 0 == success, 1 == not found, 2 == error\n", argv[0]);
+ WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
+ &dwWritten, NULL);
+ return 2;
+ }
+ return LocateDependency(argv[2]);
}
}
chars = snprintf(msg, sizeof(msg) - 1,
@@ -701,6 +713,97 @@ QualifyPath(
}
/*
+ * Implements LocateDependency for a single directory. See that command
+ * for an explanation.
+ * Returns 0 if found after printing the directory.
+ * Returns 1 if not found but no errors.
+ * Returns 2 on any kind of error
+ * Basically, these are used as exit codes for the process.
+ */
+static int LocateDependencyHelper(const char *dir, const char *keypath)
+{
+ HANDLE hSearch;
+ char path[MAX_PATH+1];
+ int dirlen, keylen, ret;
+ WIN32_FIND_DATA finfo;
+
+ if (dir == NULL || keypath == NULL)
+ return 2; /* Have no real error reporting mechanism into nmake */
+ dirlen = strlen(dir);
+ if ((dirlen + 3) > sizeof(path))
+ return 2;
+ strncpy(path, dir, dirlen);
+ strncpy(path+dirlen, "\\*", 3); /* Including terminating \0 */
+ keylen = strlen(keypath);
+
+#if 0 /* This function is not available in Visual C++ 6 */
+ /*
+ * Use numerics 0 -> FindExInfoStandard,
+ * 1 -> FindExSearchLimitToDirectories,
+ * as these are not defined in Visual C++ 6
+ */
+ hSearch = FindFirstFileEx(path, 0, &finfo, 1, NULL, 0);
+#else
+ hSearch = FindFirstFile(path, &finfo);
+#endif
+ if (hSearch == INVALID_HANDLE_VALUE)
+ return 1; /* Not found */
+
+ /* Loop through all subdirs checking if the keypath is under there */
+ ret = 1; /* Assume not found */
+ do {
+ int sublen;
+ /*
+ * We need to check it is a directory despite the
+ * FindExSearchLimitToDirectories in the above call. See SDK docs
+ */
+ if ((finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
+ continue;
+ sublen = strlen(finfo.cFileName);
+ if ((dirlen+1+sublen+1+keylen+1) > sizeof(path))
+ continue; /* Path does not fit, assume not matched */
+ strncpy(path+dirlen+1, finfo.cFileName, sublen);
+ path[dirlen+1+sublen] = '\\';
+ strncpy(path+dirlen+1+sublen+1, keypath, keylen+1);
+ if (PathFileExists(path)) {
+ /* Found a match, print to stdout */
+ path[dirlen+1+sublen] = '\0';
+ QualifyPath(path);
+ ret = 0;
+ break;
+ }
+ } while (FindNextFile(hSearch, &finfo));
+ FindClose(hSearch);
+ return ret;
+}
+
+/*
+ * LocateDependency --
+ *
+ * Locates a dependency for a package.
+ * keypath - a relative path within the package directory
+ * that is used to confirm it is the correct directory.
+ * The search path for the package directory is currently only
+ * the parent and grandparent of the current working directory.
+ * If found, the command prints
+ * name_DIRPATH=<full path of located directory>
+ * and returns 0. If not found, does not print anything and returns 1.
+ */
+static int LocateDependency(const char *keypath)
+{
+ int i, ret;
+ static char *paths[] = {"..", "..\\..", "..\\..\\.."};
+
+ for (i = 0; i < (sizeof(paths)/sizeof(paths[0])); ++i) {
+ ret = LocateDependencyHelper(paths[i], keypath);
+ if (ret == 0)
+ return ret;
+ }
+ return ret;
+}
+
+
+/*
* Local variables:
* mode: c
* c-basic-offset: 4
diff --git a/win/rules-ext.vc b/win/rules-ext.vc
index 3aba80d..58c70fa 100644
--- a/win/rules-ext.vc
+++ b/win/rules-ext.vc
@@ -28,6 +28,12 @@ macro to the name of the project makefile.
!error The rules-ext.vc file is not intended for Tcl itself.
!endif
+# We extract version numbers using the nmakehlp program. For now use
+# the local copy of nmakehlp. Once we locate Tcl, we will use that
+# one if it is newer.
+!if [$(CC) -nologo "nmakehlp.c" -link -subsystem:console > nul]
+!endif
+
# First locate the Tcl directory that we are working with.
!ifdef TCLDIR
@@ -36,13 +42,20 @@ _RULESDIR = $(TCLDIR:/=\)
!else
# If an installation path is specified, that is also the Tcl directory.
-# Also, tk never builds against an installed Tcl, it needs Tcl sources
+# Also Tk never builds against an installed Tcl, it needs Tcl sources
!if defined(INSTALLDIR) && "$(PROJECT)" != "tk"
_RULESDIR=$(INSTALLDIR:/=\)
!else
+# Locate Tcl sources
+!if [echo _RULESDIR = \> nmakehlp.out] \
+ || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
_RULESDIR = ..\..\tcl
+!else
+!include nmakehlp.out
!endif
+!endif # defined(INSTALLDIR)....
+
!endif # ifndef TCLDIR
# Now look for the targets.vc file under the Tcl root. Note we check this
@@ -63,10 +76,6 @@ _RULESDIR = .
!if exist("rules.vc") # The extension has its own copy
-# We extract version numbers using the nmakehlp program.
-!if [$(CC) -nologo "$(_RULESDIR)\nmakehlp.c" -link -subsystem:console > nul]
-!endif
-
!if [echo TCL_RULES_MAJOR = \> versions.vc] \
&& [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MAJOR >> versions.vc]
!endif
diff --git a/win/rules.vc b/win/rules.vc
index 890618c..f22a2dc 100644
--- a/win/rules.vc
+++ b/win/rules.vc
@@ -256,8 +256,13 @@ _TCL_H = ..\generic\tcl.h
TCLINSTALL = 0 # Tk always builds against Tcl source, not an installed Tcl
!if "$(TCLDIR)" == ""
-TCLDIR = ../../tcl
+!if [echo TCLDIR = \> nmakehlp.out] \
+ || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
+!error *** Could not locate Tcl source directory.
!endif
+!include nmakehlp.out
+!endif # TCLDIR == ""
+
_TCLDIR = $(TCLDIR:/=\)
_TCL_H = $(_TCLDIR)\generic\tcl.h
!if !exist("$(_TCL_H)")
@@ -285,21 +290,32 @@ TCLINSTALL = 0
_TCL_H = $(_TCLDIR)\generic\tcl.h
!endif
-!else # TCLDIR is not defined
+!else # # Case 2(c) for extensions with TCLDIR undefined
+
+# Need to locate Tcl depending on whether it needs Tcl source or not.
+# If we don't, check the INSTALLDIR for an installed Tcl first
+
+!if exist("$(_INSTALLDIR)\include\tcl.h") && !$(NEED_TCL_SOURCE)
-!if exist("$(_INSTALLDIR)\include\tcl.h") # Case 2(c) for extensions with TCLDIR undefined
TCLINSTALL = 1
TCLDIR = $(_INSTALLDIR)\..
# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
# later so the \.. accounts for the /lib
_TCLDIR = $(_INSTALLDIR)\..
_TCL_H = $(_TCLDIR)\include\tcl.h
-!elseif exist("..\..\tcl\generic\tcl.h")
+
+!else # exist(...) && ! $(NEED_TCL_SOURCE)
+
+!if [echo _TCLDIR = \> nmakehlp.out] \
+ || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
+!error *** Could not locate Tcl source directory.
+!endif
+!include nmakehlp.out
TCLINSTALL = 0
-TCLDIR = ..\..\tcl
-_TCLDIR = $(TCLDIR)
+TCLDIR = $(_TCLDIR)
_TCL_H = $(_TCLDIR)\generic\tcl.h
-!endif
+
+!endif # exist(...) && ! $(NEED_TCL_SOURCE)
!endif # TCLDIR
@@ -325,17 +341,30 @@ _TK_H = $(_TKDIR)\generic\tk.h
!else # TKDIR not defined
-!if exist("$(_INSTALLDIR)\..\include\tk.h")
+# Need to locate Tcl depending on whether it needs Tcl source or not.
+# If we don't, check the INSTALLDIR for an installed Tcl first
+
+!if exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
+
TKINSTALL = 1
+# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
+# later so the \.. accounts for the /lib
_TKDIR = $(_INSTALLDIR)\..
_TK_H = $(_TKDIR)\include\tk.h
TKDIR = $(_TKDIR)
-!elseif exist("$(_TCLDIR)\include\tk.h")
-TKINSTALL = 1
-_TKDIR = $(_TCLDIR)
-_TK_H = $(_TKDIR)\include\tk.h
-TKDIR = $(_TKDIR)
+
+!else # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
+
+!if [echo _TKDIR = \> nmakehlp.out] \
+ || [nmakehlp -L generic\tk.h >> nmakehlp.out]
+!error *** Could not locate Tk source directory.
!endif
+!include nmakehlp.out
+TKINSTALL = 0
+TKDIR = $(_TKDIR)
+_TK_H = $(_TKDIR)\generic\tk.h
+
+!endif # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
!endif # TKDIR
@@ -626,6 +655,7 @@ LINKERFLAGS = $(LINKERFLAGS) -ltcg
# The following macros are defined by this section based on OPTS
# STATIC_BUILD - 0 -> Tcl is to be built as a shared library
# 1 -> build as a static library and shell
+# TCL_THREADS - legacy but always 1 on Windows since winsock requires it.
# DEBUG - 1 -> debug build, 0 -> release builds
# SYMBOLS - 1 -> generate PDB's, 0 -> no PDB's
# PROFILE - 1 -> generate profiling info, 0 -> no profiling
@@ -647,6 +677,7 @@ LINKERFLAGS = $(LINKERFLAGS) -ltcg
# Default values for all the above
STATIC_BUILD = 0
+TCL_THREADS = 1
DEBUG = 0
SYMBOLS = 0
PROFILE = 0
@@ -926,6 +957,7 @@ VERSION = $(DOTVERSION:.=)
# different compilers, build configurations etc.,
#
# Naming convention (suffixes):
+# t = full thread support. (Not used for Tcl >= 8.6)
# s = static library (as opposed to an import library)
# g = linked to the debug enabled C run-time.
# x = special static build when it links to the dynamic C run-time.
@@ -947,7 +979,7 @@ VERSION = $(DOTVERSION:.=)
# PRJSTUBLIB - output path of the generated project stubs library
# RESFILE - output resource file (only if not static build)
-SUFX = sgx
+SUFX = tsgx
!if $(DEBUG)
BUILDDIRTOP = Debug
@@ -966,7 +998,7 @@ BUILDDIRTOP =$(BUILDDIRTOP)_VC$(VCVER)
SUFX = $(SUFX:g=)
!endif
-TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_DynamicStaticX
+TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX
!if !$(STATIC_BUILD)
TMP_DIRFULL = $(TMP_DIRFULL:Static=)
@@ -983,6 +1015,11 @@ SUFX = $(SUFX:x=)
!endif
!endif
+!if !$(TCL_THREADS) || $(TCL_VERSION) > 86
+TMP_DIRFULL = $(TMP_DIRFULL:Threaded=)
+SUFX = $(SUFX:t=)
+!endif
+
!ifndef TMP_DIR
TMP_DIR = $(TMP_DIRFULL)
!ifndef OUT_DIR
@@ -1176,8 +1213,11 @@ OPTDEFINES = $(OPTDEFINES) -DTCL_MEM_DEBUG
!if $(TCL_COMPILE_DEBUG)
OPTDEFINES = $(OPTDEFINES) -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
!endif
-!if $(USE_THREAD_ALLOC)==0
-OPTDEFINES = $(OPTDEFINES) -DUSE_THREAD_ALLOC=0
+!if $(TCL_THREADS) && $(TCL_VERSION) < 86
+OPTDEFINES = $(OPTDEFINES) -DTCL_THREADS=1
+!if $(USE_THREAD_ALLOC)
+OPTDEFINES = $(OPTDEFINES) -DUSE_THREAD_ALLOC=1
+!endif
!endif
!if $(STATIC_BUILD)
OPTDEFINES = $(OPTDEFINES) -DSTATIC_BUILD
@@ -1486,13 +1526,12 @@ default-clean:
@if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc
@if exist $(WINDIR)\version.vc del $(WINDIR)\version.vc
-default-hose:
+default-hose: default-clean
@echo Hosing $(OUT_DIR)\* ...
@if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
+# Only for backward compatibility
default-distclean: default-hose
- @if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
- @if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
default-setup:
@if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
@@ -1644,10 +1683,16 @@ TCLNMAKECONFIG = "$(OUT_DIR)\tcl.nmake"
# Display stats being used.
#----------------------------------------------------------
+!if !$(DOING_TCL)
+!message *** Building against Tcl at '$(_TCLDIR)'
+!endif
+!if !$(DOING_TK) && $(NEED_TK)
+!message *** Building against Tk at '$(_TKDIR)'
+!endif
!message *** Intermediate directory will be '$(TMP_DIR)'
!message *** Output directory will be '$(OUT_DIR)'
+!message *** Installation, if selected, will be in '$(_INSTALLDIR)'
!message *** Suffix for binaries will be '$(SUFX)'
-!message *** Optional defines are '$(OPTDEFINES)'
!message *** Compiler version $(VCVER). Target machine is $(MACHINE)
!message *** Host architecture is $(NATIVE_ARCH)
diff --git a/win/targets.vc b/win/targets.vc
index ca227d8..7f1d388 100644
--- a/win/targets.vc
+++ b/win/targets.vc
@@ -36,17 +36,63 @@ $(PRJLIB): $(PRJ_OBJS) $(RESFILE)
-@del $*.exp
!endif
-!ifndef DISABLE_STANDARD_TARGETS
+!if "$(PRJ_HEADERS)" != "" && "$(PRJ_OBJS)" != ""
+$(PRJ_OBJS): $(PRJ_HEADERS)
+!endif
+
+# If parent makefile has defined stub objects, add their installation
+# to the default install
+!if "$(PRJ_STUBOBJS)" != ""
+default-install: default-install-stubs
+!endif
+
+# Unlike the other default targets, these cannot be in rules.vc because
+# the executed command depends on existence of macro PRJ_HEADERS_PUBLIC
+# that the parent makefile will not define until after including rules-ext.vc
+!if "$(PRJ_HEADERS_PUBLIC)" != ""
+default-install: default-install-headers
+default-install-headers:
+ @echo Installing headers to '$(INCLUDE_INSTALL_DIR)'
+ @for %f in ($(PRJ_HEADERS_PUBLIC)) do @$(COPY) %f "$(INCLUDE_INSTALL_DIR)"
+!endif
+
+!if "$(DISABLE_STANDARD_TARGETS)" == ""
DISABLE_STANDARD_TARGETS = 0
!endif
+!if "$(DISABLE_TARGET_setup)" == ""
+DISABLE_TARGET_setup = 0
+!endif
+!if "$(DISABLE_TARGET_install)" == ""
+DISABLE_TARGET_install = 0
+!endif
+!if "$(DISABLE_TARGET_clean)" == ""
+DISABLE_TARGET_clean = 0
+!endif
+!if "$(DISABLE_TARGET_test)" == ""
+DISABLE_TARGET_test = 0
+!endif
+!if "$(DISABLE_TARGET_shell)" == ""
+DISABLE_TARGET_shell = 0
+!endif
+
!if !$(DISABLE_STANDARD_TARGETS)
+!if !$(DISABLE_TARGET_setup)
setup: default-setup
+!endif
+!if !$(DISABLE_TARGET_install)
install: default-install
+!endif
+!if !$(DISABLE_TARGET_clean)
clean: default-clean
realclean: hose
hose: default-hose
distclean: realclean default-distclean
+!endif
+!if !$(DISABLE_TARGET_test)
test: default-test
+!endif
+!if !$(DISABLE_TARGET_shell)
shell: default-shell
!endif
+!endif # DISABLE_STANDARD_TARGETS