mirror of
https://git.code.sf.net/p/zint/code
synced 2025-05-31 23:28:27 -04:00
Add nmake.vc build system, add tcl 9 compatibility, half-fix unload, half-add version-info
This commit is contained in:
parent
041c74fe4d
commit
1456af0e8b
15 changed files with 4540 additions and 1351 deletions
1
backend_tcl/win/gitmanifest.in
Normal file
1
backend_tcl/win/gitmanifest.in
Normal file
|
@ -0,0 +1 @@
|
|||
git-
|
124
backend_tcl/win/makefile.vc
Normal file
124
backend_tcl/win/makefile.vc
Normal file
|
@ -0,0 +1,124 @@
|
|||
#------------------------------------------------------------- -*- makefile -*-
|
||||
#
|
||||
# makefile to build zint tcl extension
|
||||
#
|
||||
# Basic build and install
|
||||
# nmake /f makefile.vc INSTALLDIR=c:\path\to\tcl
|
||||
# nmake /f makefile.vc INSTALLDIR=c:\path\to\tcl install
|
||||
#
|
||||
# The options TCLDIR= and TKDIR= may be added, if the TCL/Tk installation
|
||||
# (or source) is not automatically located.
|
||||
#
|
||||
# For other build options (debug, static etc.),
|
||||
# See TIP 477 (https://core.tcl-lang.org/tips/doc/main/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 = zint
|
||||
PROJECT_REQUIRES_TK = 1
|
||||
|
||||
# Generic source is in root build folder (1 up)
|
||||
GENERICDIR = ..
|
||||
# Access the generic backend files
|
||||
BACKEND_DIR = $(ROOT)\..\backend
|
||||
|
||||
!include "rules-ext.vc"
|
||||
|
||||
# Define the object files and resource file that make up the extension.
|
||||
# Note the resource file does not makes sense if doing a static library build
|
||||
# hence it is under that condition. TMP_DIR is the output directory
|
||||
# defined by rules for object files.
|
||||
PRJ_OBJS = \
|
||||
$(TMP_DIR)\zint.obj \
|
||||
$(TMP_DIR)\2of5.obj \
|
||||
$(TMP_DIR)\auspost.obj \
|
||||
$(TMP_DIR)\aztec.obj \
|
||||
$(TMP_DIR)\bc412.obj \
|
||||
$(TMP_DIR)\bmp.obj \
|
||||
$(TMP_DIR)\codablock.obj \
|
||||
$(TMP_DIR)\code128.obj \
|
||||
$(TMP_DIR)\code16k.obj \
|
||||
$(TMP_DIR)\code1.obj \
|
||||
$(TMP_DIR)\code49.obj \
|
||||
$(TMP_DIR)\code.obj \
|
||||
$(TMP_DIR)\common.obj \
|
||||
$(TMP_DIR)\composite.obj \
|
||||
$(TMP_DIR)\dllversion.obj \
|
||||
$(TMP_DIR)\dmatrix.obj \
|
||||
$(TMP_DIR)\dotcode.obj \
|
||||
$(TMP_DIR)\eci.obj \
|
||||
$(TMP_DIR)\emf.obj \
|
||||
$(TMP_DIR)\filemem.obj \
|
||||
$(TMP_DIR)\general_field.obj \
|
||||
$(TMP_DIR)\gif.obj \
|
||||
$(TMP_DIR)\gridmtx.obj \
|
||||
$(TMP_DIR)\gs1.obj \
|
||||
$(TMP_DIR)\hanxin.obj \
|
||||
$(TMP_DIR)\imail.obj \
|
||||
$(TMP_DIR)\large.obj \
|
||||
$(TMP_DIR)\library.obj \
|
||||
$(TMP_DIR)\mailmark.obj \
|
||||
$(TMP_DIR)\maxicode.obj \
|
||||
$(TMP_DIR)\medical.obj \
|
||||
$(TMP_DIR)\output.obj \
|
||||
$(TMP_DIR)\pcx.obj \
|
||||
$(TMP_DIR)\pdf417.obj \
|
||||
$(TMP_DIR)\plessey.obj \
|
||||
$(TMP_DIR)\png.obj \
|
||||
$(TMP_DIR)\postal.obj \
|
||||
$(TMP_DIR)\ps.obj \
|
||||
$(TMP_DIR)\qr.obj \
|
||||
$(TMP_DIR)\raster.obj \
|
||||
$(TMP_DIR)\reedsol.obj \
|
||||
$(TMP_DIR)\rss.obj \
|
||||
$(TMP_DIR)\svg.obj \
|
||||
$(TMP_DIR)\telepen.obj \
|
||||
$(TMP_DIR)\tif.obj \
|
||||
$(TMP_DIR)\ultra.obj \
|
||||
$(TMP_DIR)\upcean.obj \
|
||||
$(TMP_DIR)\vector.obj
|
||||
|
||||
# Define any additional compiler flags that might be required for the project
|
||||
PRJ_DEFINES = -D_CRT_SECURE_NO_DEPRECATE
|
||||
PRJ_DEFINES = $(PRJ_DEFINES) -DZINT_NO_PNG=1
|
||||
# PRJ_DEFINES = $(PRJ_DEFINES) -DZINT_VERSION=PACKAGE_VERSION
|
||||
PRJ_DEFINES = $(PRJ_DEFINES) -I$(TMP_DIR)
|
||||
PRJ_DEFINES = $(PRJ_DEFINES) -I$(BACKEND_DIR)
|
||||
|
||||
|
||||
|
||||
|
||||
# Define the standard targets
|
||||
!include "$(_RULESDIR)\targets.vc"
|
||||
|
||||
# We must define a pkgindex target that will create a pkgIndex.tcl
|
||||
# file in the $(OUT_DIR) directory. We can just redirect to the
|
||||
# default-pkgindex target for our sample extension.
|
||||
pkgindex: default-pkgindex
|
||||
|
||||
$(ROOT)\manifest.uuid:
|
||||
copy $(WIN_DIR)\gitmanifest.in $(ROOT)\manifest.uuid
|
||||
git rev-parse HEAD >>$(ROOT)\manifest.uuid
|
||||
|
||||
$(TMP_DIR)\zintUuid.h: $(ROOT)\manifest.uuid
|
||||
copy $(WIN_DIR)\zintUuid.h.in+$(ROOT)\manifest.uuid $(TMP_DIR)\zintUuid.h
|
||||
|
||||
|
||||
# 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: default-install-docs-n
|
||||
|
||||
# Explicit dependency rules
|
||||
$(GENERICDIR)\zint.c : $(TMP_DIR)\zintUuid.h
|
||||
|
||||
{$(BACKEND_DIR)}.c{$(TMP_DIR)}.obj::
|
||||
$(cc32) $(pkgcflags) -Fo$(TMP_DIR)\ @<<
|
||||
$<
|
||||
<<
|
820
backend_tcl/win/nmakehlp.c
Normal file
820
backend_tcl/win/nmakehlp.c
Normal file
|
@ -0,0 +1,820 @@
|
|||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* nmakehlp.c --
|
||||
*
|
||||
* This is used to fix limitations within nmake and the environment.
|
||||
*
|
||||
* Copyright (c) 2002 David Gravereaux.
|
||||
* Copyright (c) 2006 Pat Thoyts
|
||||
*
|
||||
* See the file "license.terms" for information on usage and redistribution of
|
||||
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#include <windows.h>
|
||||
#ifdef _MSC_VER
|
||||
#pragma comment (lib, "user32.lib")
|
||||
#pragma comment (lib, "kernel32.lib")
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* This library is required for x64 builds with _some_ versions of MSVC
|
||||
*/
|
||||
#if defined(_M_IA64) || defined(_M_AMD64)
|
||||
#if _MSC_VER >= 1400 && _MSC_VER < 1500
|
||||
#pragma comment(lib, "bufferoverflowU")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* ISO hack for dumb VC++ */
|
||||
#if defined(_WIN32) && defined(_MSC_VER) && _MSC_VER < 1900
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
|
||||
/* protos */
|
||||
|
||||
static int CheckForCompilerFeature(const char *option);
|
||||
static int CheckForLinkerFeature(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);
|
||||
|
||||
/* globals */
|
||||
|
||||
#define CHUNK 25
|
||||
#define STATICBUFFERSIZE 1000
|
||||
typedef struct {
|
||||
HANDLE pipe;
|
||||
char buffer[STATICBUFFERSIZE];
|
||||
} pipeinfo;
|
||||
|
||||
pipeinfo Out = {INVALID_HANDLE_VALUE, ""};
|
||||
pipeinfo Err = {INVALID_HANDLE_VALUE, ""};
|
||||
|
||||
/*
|
||||
* exitcodes: 0 == no, 1 == yes, 2 == error
|
||||
*/
|
||||
|
||||
int
|
||||
main(
|
||||
int argc,
|
||||
char *argv[])
|
||||
{
|
||||
char msg[300];
|
||||
DWORD dwWritten;
|
||||
int chars;
|
||||
const char *s;
|
||||
|
||||
/*
|
||||
* Make sure children (cl.exe and link.exe) are kept quiet.
|
||||
*/
|
||||
|
||||
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
|
||||
|
||||
/*
|
||||
* Make sure the compiler and linker aren't effected by the outside world.
|
||||
*/
|
||||
|
||||
SetEnvironmentVariable("CL", "");
|
||||
SetEnvironmentVariable("LINK", "");
|
||||
|
||||
if (argc > 1 && *argv[1] == '-') {
|
||||
switch (*(argv[1]+1)) {
|
||||
case 'c':
|
||||
if (argc != 3) {
|
||||
chars = snprintf(msg, sizeof(msg) - 1,
|
||||
"usage: %s -c <compiler option>\n"
|
||||
"Tests for whether cl.exe supports an option\n"
|
||||
"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
|
||||
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
|
||||
&dwWritten, NULL);
|
||||
return 2;
|
||||
}
|
||||
return CheckForCompilerFeature(argv[2]);
|
||||
case 'l':
|
||||
if (argc < 3) {
|
||||
chars = snprintf(msg, sizeof(msg) - 1,
|
||||
"usage: %s -l <linker option> ?<mandatory option> ...?\n"
|
||||
"Tests for whether link.exe supports an option\n"
|
||||
"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
|
||||
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
|
||||
&dwWritten, NULL);
|
||||
return 2;
|
||||
}
|
||||
return CheckForLinkerFeature(&argv[2], argc-2);
|
||||
case 'f':
|
||||
if (argc == 2) {
|
||||
chars = snprintf(msg, sizeof(msg) - 1,
|
||||
"usage: %s -f <string> <substring>\n"
|
||||
"Find a substring within another\n"
|
||||
"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
|
||||
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
|
||||
&dwWritten, NULL);
|
||||
return 2;
|
||||
} else if (argc == 3) {
|
||||
/*
|
||||
* If the string is blank, there is no match.
|
||||
*/
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
return IsIn(argv[2], argv[3]);
|
||||
}
|
||||
case 's':
|
||||
if (argc == 2) {
|
||||
chars = snprintf(msg, sizeof(msg) - 1,
|
||||
"usage: %s -s <substitutions file> <file>\n"
|
||||
"Perform a set of string map type substutitions on a file\n"
|
||||
"exitcodes: 0\n",
|
||||
argv[0]);
|
||||
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
|
||||
&dwWritten, NULL);
|
||||
return 2;
|
||||
}
|
||||
return SubstituteFile(argv[2], argv[3]);
|
||||
case 'V':
|
||||
if (argc != 4) {
|
||||
chars = snprintf(msg, sizeof(msg) - 1,
|
||||
"usage: %s -V filename matchstring\n"
|
||||
"Extract a version from a file:\n"
|
||||
"eg: pkgIndex.tcl \"package ifneeded http\"",
|
||||
argv[0]);
|
||||
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
|
||||
&dwWritten, NULL);
|
||||
return 0;
|
||||
}
|
||||
s = GetVersionFromFile(argv[2], argv[3], *(argv[1]+2) - '0');
|
||||
if (s && *s) {
|
||||
printf("%s\n", s);
|
||||
return 0;
|
||||
} else
|
||||
return 1; /* Version not found. Return non-0 exit code */
|
||||
|
||||
case 'Q':
|
||||
if (argc != 3) {
|
||||
chars = snprintf(msg, sizeof(msg) - 1,
|
||||
"usage: %s -Q path\n"
|
||||
"Emit the fully qualified path\n"
|
||||
"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
|
||||
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
|
||||
&dwWritten, NULL);
|
||||
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,
|
||||
"usage: %s -c|-f|-l|-Q|-s|-V ...\n"
|
||||
"This is a little helper app to equalize shell differences between WinNT and\n"
|
||||
"Win9x and get nmake.exe to accomplish its job.\n",
|
||||
argv[0]);
|
||||
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, &dwWritten, NULL);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int
|
||||
CheckForCompilerFeature(
|
||||
const char *option)
|
||||
{
|
||||
STARTUPINFO si;
|
||||
PROCESS_INFORMATION pi;
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
DWORD threadID;
|
||||
char msg[300];
|
||||
BOOL ok;
|
||||
HANDLE hProcess, h, pipeThreads[2];
|
||||
char cmdline[100];
|
||||
|
||||
hProcess = GetCurrentProcess();
|
||||
|
||||
memset(&pi, 0, sizeof(PROCESS_INFORMATION));
|
||||
memset(&si, 0, sizeof(STARTUPINFO));
|
||||
si.cb = sizeof(STARTUPINFO);
|
||||
si.dwFlags = STARTF_USESTDHANDLES;
|
||||
si.hStdInput = INVALID_HANDLE_VALUE;
|
||||
|
||||
memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
|
||||
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
sa.lpSecurityDescriptor = NULL;
|
||||
sa.bInheritHandle = FALSE;
|
||||
|
||||
/*
|
||||
* Create a non-inheritable pipe.
|
||||
*/
|
||||
|
||||
CreatePipe(&Out.pipe, &h, &sa, 0);
|
||||
|
||||
/*
|
||||
* Dupe the write side, make it inheritable, and close the original.
|
||||
*/
|
||||
|
||||
DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
|
||||
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
|
||||
|
||||
/*
|
||||
* Same as above, but for the error side.
|
||||
*/
|
||||
|
||||
CreatePipe(&Err.pipe, &h, &sa, 0);
|
||||
DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE,
|
||||
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
|
||||
|
||||
/*
|
||||
* Base command line.
|
||||
*/
|
||||
|
||||
lstrcpy(cmdline, "cl.exe -nologo -c -TC -Zs -X -Fp.\\_junk.pch ");
|
||||
|
||||
/*
|
||||
* Append our option for testing
|
||||
*/
|
||||
|
||||
lstrcat(cmdline, option);
|
||||
|
||||
/*
|
||||
* Filename to compile, which exists, but is nothing and empty.
|
||||
*/
|
||||
|
||||
lstrcat(cmdline, " .\\nul");
|
||||
|
||||
ok = CreateProcess(
|
||||
NULL, /* Module name. */
|
||||
cmdline, /* Command line. */
|
||||
NULL, /* Process handle not inheritable. */
|
||||
NULL, /* Thread handle not inheritable. */
|
||||
TRUE, /* yes, inherit handles. */
|
||||
DETACHED_PROCESS, /* No console for you. */
|
||||
NULL, /* Use parent's environment block. */
|
||||
NULL, /* Use parent's starting directory. */
|
||||
&si, /* Pointer to STARTUPINFO structure. */
|
||||
&pi); /* Pointer to PROCESS_INFORMATION structure. */
|
||||
|
||||
if (!ok) {
|
||||
DWORD err = GetLastError();
|
||||
int chars = snprintf(msg, sizeof(msg) - 1,
|
||||
"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
|
||||
|
||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
|
||||
FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPSTR)&msg[chars],
|
||||
(300-chars), 0);
|
||||
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
|
||||
return 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close our references to the write handles that have now been inherited.
|
||||
*/
|
||||
|
||||
CloseHandle(si.hStdOutput);
|
||||
CloseHandle(si.hStdError);
|
||||
|
||||
WaitForInputIdle(pi.hProcess, 5000);
|
||||
CloseHandle(pi.hThread);
|
||||
|
||||
/*
|
||||
* Start the pipe reader threads.
|
||||
*/
|
||||
|
||||
pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID);
|
||||
pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID);
|
||||
|
||||
/*
|
||||
* Block waiting for the process to end.
|
||||
*/
|
||||
|
||||
WaitForSingleObject(pi.hProcess, INFINITE);
|
||||
CloseHandle(pi.hProcess);
|
||||
|
||||
/*
|
||||
* Wait for our pipe to get done reading, should it be a little slow.
|
||||
*/
|
||||
|
||||
WaitForMultipleObjects(2, pipeThreads, TRUE, 500);
|
||||
CloseHandle(pipeThreads[0]);
|
||||
CloseHandle(pipeThreads[1]);
|
||||
|
||||
/*
|
||||
* Look for the commandline warning code in both streams.
|
||||
* - in MSVC 6 & 7 we get D4002, in MSVC 8 we get D9002.
|
||||
*/
|
||||
|
||||
return !(strstr(Out.buffer, "D4002") != NULL
|
||||
|| strstr(Err.buffer, "D4002") != NULL
|
||||
|| strstr(Out.buffer, "D9002") != NULL
|
||||
|| strstr(Err.buffer, "D9002") != NULL
|
||||
|| strstr(Out.buffer, "D2021") != NULL
|
||||
|| strstr(Err.buffer, "D2021") != NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
CheckForLinkerFeature(
|
||||
char **options,
|
||||
int count)
|
||||
{
|
||||
STARTUPINFO si;
|
||||
PROCESS_INFORMATION pi;
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
DWORD threadID;
|
||||
char msg[300];
|
||||
BOOL ok;
|
||||
HANDLE hProcess, h, pipeThreads[2];
|
||||
int i;
|
||||
char cmdline[255];
|
||||
|
||||
hProcess = GetCurrentProcess();
|
||||
|
||||
memset(&pi, 0, sizeof(PROCESS_INFORMATION));
|
||||
memset(&si, 0, sizeof(STARTUPINFO));
|
||||
si.cb = sizeof(STARTUPINFO);
|
||||
si.dwFlags = STARTF_USESTDHANDLES;
|
||||
si.hStdInput = INVALID_HANDLE_VALUE;
|
||||
|
||||
memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
|
||||
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
sa.lpSecurityDescriptor = NULL;
|
||||
sa.bInheritHandle = TRUE;
|
||||
|
||||
/*
|
||||
* Create a non-inheritible pipe.
|
||||
*/
|
||||
|
||||
CreatePipe(&Out.pipe, &h, &sa, 0);
|
||||
|
||||
/*
|
||||
* Dupe the write side, make it inheritable, and close the original.
|
||||
*/
|
||||
|
||||
DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
|
||||
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
|
||||
|
||||
/*
|
||||
* Same as above, but for the error side.
|
||||
*/
|
||||
|
||||
CreatePipe(&Err.pipe, &h, &sa, 0);
|
||||
DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE,
|
||||
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
|
||||
|
||||
/*
|
||||
* Base command line.
|
||||
*/
|
||||
|
||||
lstrcpy(cmdline, "link.exe -nologo ");
|
||||
|
||||
/*
|
||||
* Append our option for testing.
|
||||
*/
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
lstrcat(cmdline, " \"");
|
||||
lstrcat(cmdline, options[i]);
|
||||
lstrcat(cmdline, "\"");
|
||||
}
|
||||
|
||||
ok = CreateProcess(
|
||||
NULL, /* Module name. */
|
||||
cmdline, /* Command line. */
|
||||
NULL, /* Process handle not inheritable. */
|
||||
NULL, /* Thread handle not inheritable. */
|
||||
TRUE, /* yes, inherit handles. */
|
||||
DETACHED_PROCESS, /* No console for you. */
|
||||
NULL, /* Use parent's environment block. */
|
||||
NULL, /* Use parent's starting directory. */
|
||||
&si, /* Pointer to STARTUPINFO structure. */
|
||||
&pi); /* Pointer to PROCESS_INFORMATION structure. */
|
||||
|
||||
if (!ok) {
|
||||
DWORD err = GetLastError();
|
||||
int chars = snprintf(msg, sizeof(msg) - 1,
|
||||
"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
|
||||
|
||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
|
||||
FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPSTR)&msg[chars],
|
||||
(300-chars), 0);
|
||||
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
|
||||
return 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close our references to the write handles that have now been inherited.
|
||||
*/
|
||||
|
||||
CloseHandle(si.hStdOutput);
|
||||
CloseHandle(si.hStdError);
|
||||
|
||||
WaitForInputIdle(pi.hProcess, 5000);
|
||||
CloseHandle(pi.hThread);
|
||||
|
||||
/*
|
||||
* Start the pipe reader threads.
|
||||
*/
|
||||
|
||||
pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID);
|
||||
pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID);
|
||||
|
||||
/*
|
||||
* Block waiting for the process to end.
|
||||
*/
|
||||
|
||||
WaitForSingleObject(pi.hProcess, INFINITE);
|
||||
CloseHandle(pi.hProcess);
|
||||
|
||||
/*
|
||||
* Wait for our pipe to get done reading, should it be a little slow.
|
||||
*/
|
||||
|
||||
WaitForMultipleObjects(2, pipeThreads, TRUE, 500);
|
||||
CloseHandle(pipeThreads[0]);
|
||||
CloseHandle(pipeThreads[1]);
|
||||
|
||||
/*
|
||||
* Look for the commandline warning code in the stderr stream.
|
||||
*/
|
||||
|
||||
return !(strstr(Out.buffer, "LNK1117") != NULL ||
|
||||
strstr(Err.buffer, "LNK1117") != NULL ||
|
||||
strstr(Out.buffer, "LNK4044") != NULL ||
|
||||
strstr(Err.buffer, "LNK4044") != NULL ||
|
||||
strstr(Out.buffer, "LNK4224") != NULL ||
|
||||
strstr(Err.buffer, "LNK4224") != NULL);
|
||||
}
|
||||
|
||||
static DWORD WINAPI
|
||||
ReadFromPipe(
|
||||
LPVOID args)
|
||||
{
|
||||
pipeinfo *pi = (pipeinfo *) args;
|
||||
char *lastBuf = pi->buffer;
|
||||
DWORD dwRead;
|
||||
BOOL ok;
|
||||
|
||||
again:
|
||||
if (lastBuf - pi->buffer + CHUNK > STATICBUFFERSIZE) {
|
||||
CloseHandle(pi->pipe);
|
||||
return (DWORD)-1;
|
||||
}
|
||||
ok = ReadFile(pi->pipe, lastBuf, CHUNK, &dwRead, 0L);
|
||||
if (!ok || dwRead == 0) {
|
||||
CloseHandle(pi->pipe);
|
||||
return 0;
|
||||
}
|
||||
lastBuf += dwRead;
|
||||
goto again;
|
||||
|
||||
return 0; /* makes the compiler happy */
|
||||
}
|
||||
|
||||
static int
|
||||
IsIn(
|
||||
const char *string,
|
||||
const char *substring)
|
||||
{
|
||||
return (strstr(string, substring) != NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* GetVersionFromFile --
|
||||
* Looks for a match string in a file and then returns the version
|
||||
* following the match where a version is anything acceptable to
|
||||
* package provide or package ifneeded.
|
||||
*/
|
||||
|
||||
static const char *
|
||||
GetVersionFromFile(
|
||||
const char *filename,
|
||||
const char *match,
|
||||
int numdots)
|
||||
{
|
||||
static char szBuffer[100];
|
||||
char *szResult = NULL;
|
||||
FILE *fp = fopen(filename, "rt");
|
||||
|
||||
if (fp != NULL) {
|
||||
/*
|
||||
* Read data until we see our match string.
|
||||
*/
|
||||
|
||||
while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) {
|
||||
LPSTR p, q;
|
||||
|
||||
p = strstr(szBuffer, match);
|
||||
if (p != NULL) {
|
||||
/*
|
||||
* Skip to first digit after the match.
|
||||
*/
|
||||
|
||||
p += strlen(match);
|
||||
while (*p && !isdigit((unsigned char)*p)) {
|
||||
++p;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find ending whitespace.
|
||||
*/
|
||||
|
||||
q = p;
|
||||
while (*q && (strchr("0123456789.ab", *q)) && (((!strchr(".ab", *q)
|
||||
&& !strchr("ab", q[-1])) || --numdots))) {
|
||||
++q;
|
||||
}
|
||||
|
||||
*q = 0;
|
||||
szResult = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
return szResult;
|
||||
}
|
||||
|
||||
/*
|
||||
* List helpers for the SubstituteFile function
|
||||
*/
|
||||
|
||||
typedef struct list_item_t {
|
||||
struct list_item_t *nextPtr;
|
||||
char * key;
|
||||
char * value;
|
||||
} list_item_t;
|
||||
|
||||
/* insert a list item into the list (list may be null) */
|
||||
static list_item_t *
|
||||
list_insert(list_item_t **listPtrPtr, const char *key, const char *value)
|
||||
{
|
||||
list_item_t *itemPtr = (list_item_t *)malloc(sizeof(list_item_t));
|
||||
if (itemPtr) {
|
||||
itemPtr->key = strdup(key);
|
||||
itemPtr->value = strdup(value);
|
||||
itemPtr->nextPtr = NULL;
|
||||
|
||||
while(*listPtrPtr) {
|
||||
listPtrPtr = &(*listPtrPtr)->nextPtr;
|
||||
}
|
||||
*listPtrPtr = itemPtr;
|
||||
}
|
||||
return itemPtr;
|
||||
}
|
||||
|
||||
static void
|
||||
list_free(list_item_t **listPtrPtr)
|
||||
{
|
||||
list_item_t *tmpPtr, *listPtr = *listPtrPtr;
|
||||
while (listPtr) {
|
||||
tmpPtr = listPtr;
|
||||
listPtr = listPtr->nextPtr;
|
||||
free(tmpPtr->key);
|
||||
free(tmpPtr->value);
|
||||
free(tmpPtr);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SubstituteFile --
|
||||
* As windows doesn't provide anything useful like sed and it's unreliable
|
||||
* to use the tclsh you are building against (consider x-platform builds -
|
||||
* e.g. compiling AMD64 target from IX86) we provide a simple substitution
|
||||
* option here to handle autoconf style substitutions.
|
||||
* The substitution file is whitespace and line delimited. The file should
|
||||
* consist of lines matching the regular expression:
|
||||
* \s*\S+\s+\S*$
|
||||
*
|
||||
* Usage is something like:
|
||||
* nmakehlp -S << $** > $@
|
||||
* @PACKAGE_NAME@ $(PACKAGE_NAME)
|
||||
* @PACKAGE_VERSION@ $(PACKAGE_VERSION)
|
||||
* <<
|
||||
*/
|
||||
|
||||
static int
|
||||
SubstituteFile(
|
||||
const char *substitutions,
|
||||
const char *filename)
|
||||
{
|
||||
static char szBuffer[1024], szCopy[1024];
|
||||
list_item_t *substPtr = NULL;
|
||||
FILE *fp, *sp;
|
||||
|
||||
fp = fopen(filename, "rt");
|
||||
if (fp != NULL) {
|
||||
|
||||
/*
|
||||
* Build a list of substitutions from the first filename
|
||||
*/
|
||||
|
||||
sp = fopen(substitutions, "rt");
|
||||
if (sp != NULL) {
|
||||
while (fgets(szBuffer, sizeof(szBuffer), sp) != NULL) {
|
||||
unsigned char *ks, *ke, *vs, *ve;
|
||||
ks = (unsigned char*)szBuffer;
|
||||
while (ks && *ks && isspace(*ks)) ++ks;
|
||||
ke = ks;
|
||||
while (ke && *ke && !isspace(*ke)) ++ke;
|
||||
vs = ke;
|
||||
while (vs && *vs && isspace(*vs)) ++vs;
|
||||
ve = vs;
|
||||
while (ve && *ve && !(*ve == '\r' || *ve == '\n')) ++ve;
|
||||
*ke = 0, *ve = 0;
|
||||
list_insert(&substPtr, (char*)ks, (char*)vs);
|
||||
}
|
||||
fclose(sp);
|
||||
}
|
||||
|
||||
/* debug: dump the list */
|
||||
#ifndef NDEBUG
|
||||
{
|
||||
int n = 0;
|
||||
list_item_t *p = NULL;
|
||||
for (p = substPtr; p != NULL; p = p->nextPtr, ++n) {
|
||||
fprintf(stderr, "% 3d '%s' => '%s'\n", n, p->key, p->value);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Run the substitutions over each line of the input
|
||||
*/
|
||||
|
||||
while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) {
|
||||
list_item_t *p = NULL;
|
||||
for (p = substPtr; p != NULL; p = p->nextPtr) {
|
||||
char *m = strstr(szBuffer, p->key);
|
||||
if (m) {
|
||||
char *cp, *op, *sp;
|
||||
cp = szCopy;
|
||||
op = szBuffer;
|
||||
while (op != m) *cp++ = *op++;
|
||||
sp = p->value;
|
||||
while (sp && *sp) *cp++ = *sp++;
|
||||
op += strlen(p->key);
|
||||
while (*op) *cp++ = *op++;
|
||||
*cp = 0;
|
||||
memcpy(szBuffer, szCopy, sizeof(szCopy));
|
||||
}
|
||||
}
|
||||
printf("%s", szBuffer);
|
||||
}
|
||||
|
||||
list_free(&substPtr);
|
||||
}
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL FileExists(LPCTSTR szPath)
|
||||
{
|
||||
#ifndef INVALID_FILE_ATTRIBUTES
|
||||
#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
|
||||
#endif
|
||||
DWORD pathAttr = GetFileAttributes(szPath);
|
||||
return (pathAttr != INVALID_FILE_ATTRIBUTES &&
|
||||
!(pathAttr & FILE_ATTRIBUTE_DIRECTORY));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* QualifyPath --
|
||||
*
|
||||
* This composes the current working directory with a provided path
|
||||
* and returns the fully qualified and normalized path.
|
||||
* Mostly needed to setup paths for testing.
|
||||
*/
|
||||
|
||||
static int
|
||||
QualifyPath(
|
||||
const char *szPath)
|
||||
{
|
||||
char szCwd[MAX_PATH + 1];
|
||||
|
||||
GetFullPathName(szPath, sizeof(szCwd)-1, szCwd, NULL);
|
||||
printf("%s\n", szCwd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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];
|
||||
size_t dirlen;
|
||||
int 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 > sizeof(path) - 3) {
|
||||
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 (FileExists(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)
|
||||
{
|
||||
size_t i;
|
||||
int ret;
|
||||
static const 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
|
||||
* fill-column: 78
|
||||
* indent-tabs-mode: t
|
||||
* tab-width: 8
|
||||
* End:
|
||||
*/
|
123
backend_tcl/win/rules-ext.vc
Normal file
123
backend_tcl/win/rules-ext.vc
Normal file
|
@ -0,0 +1,123 @@
|
|||
# This file should only be included in makefiles for Tcl extensions,
|
||||
# NOT in the makefile for Tcl itself.
|
||||
|
||||
!ifndef _RULES_EXT_VC
|
||||
|
||||
# We need to run from the directory the parent makefile is located in.
|
||||
# nmake does not tell us what makefile was used to invoke it so parent
|
||||
# makefile has to set the MAKEFILEVC macro or we just make a guess and
|
||||
# warn if we think that is not the case.
|
||||
!if "$(MAKEFILEVC)" == ""
|
||||
|
||||
!if exist("$(PROJECT).vc")
|
||||
MAKEFILEVC = $(PROJECT).vc
|
||||
!elseif exist("makefile.vc")
|
||||
MAKEFILEVC = makefile.vc
|
||||
!endif
|
||||
!endif # "$(MAKEFILEVC)" == ""
|
||||
|
||||
!if !exist("$(MAKEFILEVC)")
|
||||
MSG = ^
|
||||
You must run nmake from the directory containing the project makefile.^
|
||||
If you are doing that and getting this message, set the MAKEFILEVC^
|
||||
macro to the name of the project makefile.
|
||||
!message WARNING: $(MSG)
|
||||
!endif
|
||||
|
||||
!if "$(PROJECT)" == "tcl"
|
||||
!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 "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
|
||||
!if [$(CC) -nologo -DNDEBUG "nmakehlp.c" -link -subsystem:console > nul]
|
||||
!endif
|
||||
!else
|
||||
!if [copy x86_64-w64-mingw32-nmakehlp.exe nmakehlp.exe >NUL]
|
||||
!endif
|
||||
!endif
|
||||
|
||||
# First locate the Tcl directory that we are working with.
|
||||
!if "$(TCLDIR)" != ""
|
||||
|
||||
_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
|
||||
!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
|
||||
# file and not rules.vc because the latter also exists on older systems.
|
||||
!if exist("$(_RULESDIR)\lib\nmake\targets.vc") # Building against installed Tcl
|
||||
_RULESDIR = $(_RULESDIR)\lib\nmake
|
||||
!elseif exist("$(_RULESDIR)\win\targets.vc") # Building against Tcl sources
|
||||
_RULESDIR = $(_RULESDIR)\win
|
||||
!else
|
||||
# If we have not located Tcl's targets file, most likely we are compiling
|
||||
# against an older version of Tcl and so must use our own support files.
|
||||
_RULESDIR = .
|
||||
!endif
|
||||
|
||||
!if "$(_RULESDIR)" != "."
|
||||
# Potentially using Tcl's support files. If this extension has its own
|
||||
# nmake support files, need to compare the versions and pick newer.
|
||||
|
||||
!if exist("rules.vc") # The extension has its own copy
|
||||
|
||||
!if [echo TCL_RULES_MAJOR = \> versions.vc] \
|
||||
&& [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MAJOR >> versions.vc]
|
||||
!endif
|
||||
!if [echo TCL_RULES_MINOR = \>> versions.vc] \
|
||||
&& [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MINOR >> versions.vc]
|
||||
!endif
|
||||
|
||||
!if [echo OUR_RULES_MAJOR = \>> versions.vc] \
|
||||
&& [nmakehlp -V "rules.vc" RULES_VERSION_MAJOR >> versions.vc]
|
||||
!endif
|
||||
!if [echo OUR_RULES_MINOR = \>> versions.vc] \
|
||||
&& [nmakehlp -V "rules.vc" RULES_VERSION_MINOR >> versions.vc]
|
||||
!endif
|
||||
!include versions.vc
|
||||
# We have a newer version of the support files, use them
|
||||
!if ($(TCL_RULES_MAJOR) != $(OUR_RULES_MAJOR)) || ($(TCL_RULES_MINOR) < $(OUR_RULES_MINOR))
|
||||
_RULESDIR = .
|
||||
!endif
|
||||
|
||||
!endif # if exist("rules.vc")
|
||||
|
||||
!endif # if $(_RULESDIR) != "."
|
||||
|
||||
# Let rules.vc know what copy of nmakehlp.c to use.
|
||||
NMAKEHLPC = $(_RULESDIR)\nmakehlp.c
|
||||
|
||||
# Get rid of our internal defines before calling rules.vc
|
||||
!undef TCL_RULES_MAJOR
|
||||
!undef TCL_RULES_MINOR
|
||||
!undef OUR_RULES_MAJOR
|
||||
!undef OUR_RULES_MINOR
|
||||
|
||||
!if exist("$(_RULESDIR)\rules.vc")
|
||||
!message *** Using $(_RULESDIR)\rules.vc
|
||||
!include "$(_RULESDIR)\rules.vc"
|
||||
!else
|
||||
!error *** Could not locate rules.vc in $(_RULESDIR)
|
||||
!endif
|
||||
|
||||
!endif # _RULES_EXT_VC
|
1920
backend_tcl/win/rules.vc
Normal file
1920
backend_tcl/win/rules.vc
Normal file
File diff suppressed because it is too large
Load diff
98
backend_tcl/win/targets.vc
Normal file
98
backend_tcl/win/targets.vc
Normal file
|
@ -0,0 +1,98 @@
|
|||
#------------------------------------------------------------- -*- makefile -*-
|
||||
# targets.vc --
|
||||
#
|
||||
# Part of the nmake based build system for Tcl and its extensions.
|
||||
# This file defines some standard targets for the convenience of extensions
|
||||
# and can be optionally included by the extension makefile.
|
||||
# See TIP 477 (https://core.tcl-lang.org/tips/doc/main/tip/477.md) for docs.
|
||||
|
||||
$(PROJECT): setup pkgindex $(PRJLIB)
|
||||
|
||||
!ifdef PRJ_STUBOBJS
|
||||
$(PROJECT): $(PRJSTUBLIB)
|
||||
$(PRJSTUBLIB): $(PRJ_STUBOBJS)
|
||||
$(LIBCMD) $**
|
||||
|
||||
$(PRJ_STUBOBJS):
|
||||
$(CCSTUBSCMD) %s
|
||||
!endif # PRJ_STUBOBJS
|
||||
|
||||
!ifdef PRJ_MANIFEST
|
||||
$(PROJECT): $(PRJLIB).manifest
|
||||
$(PRJLIB).manifest: $(PRJ_MANIFEST)
|
||||
@nmakehlp -s << $** >$@
|
||||
@MACHINE@ $(MACHINE:IX86=X86)
|
||||
<<
|
||||
!endif
|
||||
|
||||
!if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk"
|
||||
$(PRJLIB): $(PRJ_OBJS) $(RESFILE)
|
||||
!if $(STATIC_BUILD)
|
||||
$(LIBCMD) $**
|
||||
!else
|
||||
$(DLLCMD) $**
|
||||
$(_VC_MANIFEST_EMBED_DLL)
|
||||
!endif
|
||||
-@del $*.exp
|
||||
!endif
|
||||
|
||||
!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
|
1
backend_tcl/win/zintUuid.h.in
Normal file
1
backend_tcl/win/zintUuid.h.in
Normal file
|
@ -0,0 +1 @@
|
|||
#define SAMPLE_VERSION_UUID \
|
Loading…
Add table
Add a link
Reference in a new issue