Merge pull request #773 from jeffhostetler/vs2015

Build with VS2015
This commit is contained in:
Johannes Schindelin
2018-06-08 13:42:38 +02:00
18 changed files with 984 additions and 27 deletions

3
.gitignore vendored
View File

@@ -1,6 +1,7 @@
/GIT-BUILD-OPTIONS
/GIT-CFLAGS
/GIT-LDFLAGS
/GIT-MSVC-GEN
/GIT-PREFIX
/GIT-PERL-DEFINES
/GIT-PERL-HEADER
@@ -222,5 +223,7 @@
*.user
*.idb
*.pdb
*.ilk
.vs/
/Debug/
/Release/

View File

@@ -1179,7 +1179,7 @@ endif
ifdef SANE_TOOL_PATH
SANE_TOOL_PATH_SQ = $(subst ','\'',$(SANE_TOOL_PATH))
BROKEN_PATH_FIX = 's|^\# @@BROKEN_PATH_FIX@@$$|git_broken_path_fix $(SANE_TOOL_PATH_SQ)|'
BROKEN_PATH_FIX = 's|^\# @@BROKEN_PATH_FIX@@$$|git_broken_path_fix "$(SANE_TOOL_PATH_SQ)"|'
PATH := $(SANE_TOOL_PATH):${PATH}
else
BROKEN_PATH_FIX = '/^\# @@BROKEN_PATH_FIX@@$$/d'
@@ -2750,6 +2750,28 @@ install: all
$(INSTALL) $(ALL_PROGRAMS) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) -m 644 $(SCRIPT_LIB) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) $(install_bindir_programs) '$(DESTDIR_SQ)$(bindir_SQ)'
ifdef MSVC
$(INSTALL) compat/vcbuild/GEN.DEPS/bin/*.dll '$(DESTDIR_SQ)$(bindir_SQ)'
$(INSTALL) compat/vcbuild/GEN.DEPS/bin/*.pdb '$(DESTDIR_SQ)$(bindir_SQ)'
# We DO NOT install the individual foo.o.pdb files because they
# have already been rolled up into the exe's pdb file.
# We DO NOT have pdb files for the builtin commands (like git-status.exe)
# because it is just a copy/hardlink of git.exe, rather than a unique binary.
$(INSTALL) git.pdb '$(DESTDIR_SQ)$(bindir_SQ)'
$(INSTALL) git-shell.pdb '$(DESTDIR_SQ)$(bindir_SQ)'
$(INSTALL) git-upload-pack.pdb '$(DESTDIR_SQ)$(bindir_SQ)'
$(INSTALL) git-credential-store.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) git-daemon.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) git-fast-import.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) git-http-backend.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) git-http-fetch.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) git-http-push.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) git-imap-send.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) git-remote-http.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) git-remote-testsvn.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) git-sh-i18n--envsubst.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
$(INSTALL) git-show-index.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
endif
$(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(mergetools_instdir_SQ)'
$(INSTALL) -m 644 mergetools/* '$(DESTDIR_SQ)$(mergetools_instdir_SQ)'
@@ -2950,6 +2972,13 @@ endif
$(RM) GIT-VERSION-FILE GIT-CFLAGS GIT-LDFLAGS GIT-BUILD-OPTIONS
$(RM) GIT-USER-AGENT GIT-PREFIX
$(RM) GIT-SCRIPT-DEFINES GIT-PERL-DEFINES GIT-PERL-HEADER GIT-PYTHON-VARS
ifdef MSVC
$(RM) $(patsubst %.o,%.o.pdb,$(OBJECTS))
$(RM) $(patsubst %.exe,%.pdb,$(OTHER_PROGRAMS))
$(RM) $(patsubst %.exe,%.pdb,$(PROGRAMS))
$(RM) $(patsubst %.exe,%.pdb,$(TEST_PROGRAMS))
$(RM) GIT-MSVC-GEN
endif
.PHONY: all install profile-clean cocciclean clean strip
.PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell

View File

@@ -5,8 +5,8 @@
#include "cache-tree.h"
#include "object-store.h"
#ifndef DEBUG
#define DEBUG 0
#ifndef DEBUG_CACHE_TREE
#define DEBUG_CACHE_TREE 0
#endif
struct cache_tree *cache_tree(void)
@@ -110,7 +110,7 @@ static int do_invalidate_path(struct cache_tree *it, const char *path)
int namelen;
struct cache_tree_sub *down;
#if DEBUG
#if DEBUG_CACHE_TREE
fprintf(stderr, "cache-tree invalidate <%s>\n", path);
#endif
@@ -393,7 +393,7 @@ static int update_one(struct cache_tree *it,
strbuf_addf(&buffer, "%o %.*s%c", mode, entlen, path + baselen, '\0');
strbuf_add(&buffer, oid->hash, the_hash_algo->rawsz);
#if DEBUG
#if DEBUG_CACHE_TREE
fprintf(stderr, "cache-tree update-one %o %.*s\n",
mode, entlen, path + baselen);
#endif
@@ -416,7 +416,7 @@ static int update_one(struct cache_tree *it,
strbuf_release(&buffer);
it->entry_count = to_invalidate ? -1 : i - *skip_count;
#if DEBUG
#if DEBUG_CACHE_TREE
fprintf(stderr, "cache-tree update-one (%d ent, %d subtree) %s\n",
it->entry_count, it->subtree_nr,
oid_to_hex(&it->oid));
@@ -455,7 +455,7 @@ static void write_one(struct strbuf *buffer, struct cache_tree *it,
strbuf_add(buffer, path, pathlen);
strbuf_addf(buffer, "%c%d %d\n", 0, it->entry_count, it->subtree_nr);
#if DEBUG
#if DEBUG_CACHE_TREE
if (0 <= it->entry_count)
fprintf(stderr, "cache-tree <%.*s> (%d ent, %d subtree) %s\n",
pathlen, path, it->entry_count, it->subtree_nr,
@@ -529,7 +529,7 @@ static struct cache_tree *read_one(const char **buffer, unsigned long *size_p)
size -= rawsz;
}
#if DEBUG
#if DEBUG_CACHE_TREE
if (0 <= it->entry_count)
fprintf(stderr, "cache-tree <%s> (%d ent, %d subtree) %s\n",
*buffer, it->entry_count, subtree_nr,

View File

@@ -1326,6 +1326,147 @@ static char *path_lookup(const char *cmd, int exe_only)
return prog;
}
#if defined(_MSC_VER)
/* We need a stable sort */
#ifndef INTERNAL_QSORT
#include "qsort.c"
#endif
/* Compare only keys */
static int wenvcmp(const void *a, const void *b)
{
wchar_t *p = *(wchar_t **)a, *q = *(wchar_t **)b;
size_t p_len, q_len;
int ret;
/* Find end of keys */
for (p_len = 0; p[p_len] && p[p_len] != L'='; p_len++)
; /* do nothing */
for (q_len = 0; q[q_len] && q[q_len] != L'='; q_len++)
; /* do nothing */
/* Are keys identical (modulo case)? */
if (p_len == q_len && !_wcsnicmp(p, q, p_len))
return 0;
ret = _wcsnicmp(p, q, p_len < q_len ? p_len : q_len);
return ret ? ret : (p_len < q_len ? -1 : +1);
}
/*
* Build an environment block combining the inherited environment
* merged with the given list of settings.
*
* Values of the form "KEY=VALUE" in deltaenv override inherited values.
* Values of the form "KEY" in deltaenv delete inherited values.
*
* Multiple entries in deltaenv for the same key are explicitly allowed.
*
* We return a contiguous block of UNICODE strings with a final trailing
* zero word.
*/
static wchar_t *make_environment_block(char **deltaenv)
{
/*
* The CRT (at least as of UCRT) secretly declares "_wenviron"
* as a function that returns a pointer to a mostly static table.
* Grab the pointer and cache it for the duration of our loop.
*/
const wchar_t *wenv = GetEnvironmentStringsW(), *p;
size_t delta_size = 0, size = 1; /* for extra NUL at the end */
wchar_t **array = NULL;
size_t alloc = 0, nr = 0, i;
const char *p2;
wchar_t *wdeltaenv;
wchar_t *result, *p3;
/*
* If there is no deltaenv to apply, simply return a copy
*/
if (!deltaenv || !*deltaenv) {
for (p = wenv; p && *p; ) {
size_t s = wcslen(p) + 1;
size += s;
p += s;
}
ALLOC_ARRAY(result, size);
memcpy(result, wenv, size * sizeof(*wenv));
FreeEnvironmentStringsW(wenv);
return result;
}
/*
* If there is a deltaenv, let's accumulate all keys into `array`,
* sort them using the stable git_qsort() and then copy, skipping
* duplicate keys
*/
for (p = wenv; p && *p; ) {
size_t s = wcslen(p) + 1;
size += s;
ALLOC_GROW(array, nr + 1, alloc);
array[nr++] = p;
p += s;
}
/* (over-)assess size needed for wchar version of deltaenv */
for (i = 0; deltaenv[i]; i++) {
size_t s = strlen(deltaenv[i]) + 1;
delta_size += s;
}
ALLOC_ARRAY(wdeltaenv, delta_size);
/* convert the deltaenv, appending to array */
for (i = 0, p3 = wdeltaenv; deltaenv[i]; i++) {
size_t s = strlen(deltaenv[i]) + 1, wlen;
wlen = xutftowcs(p3, deltaenv[i], s * 2);
ALLOC_GROW(array, nr + 1, alloc);
array[nr++] = p3;
p3 += wlen + 1;
}
git_qsort(array, nr, sizeof(*array), wenvcmp);
ALLOC_ARRAY(result, size + delta_size);
for (p3 = result, i = 0; i < nr; i++) {
wchar_t *equal = wcschr(array[i], L'=');;
/* Skip "to delete" entry */
if (!equal)
continue;
p = array[i];
/* Skip any duplicate */
if (i + 1 < nr) {
wchar_t *next = array[i + 1];
size_t n = equal - p;
if (!_wcsnicmp(p, next, n) && (!next[n] || next[n] == L'='))
continue;
}
size = wcslen(p) + 1;
memcpy(p3, p, size * sizeof(*p));
p3 += size;
}
*p3 = L'\0';
free(array);
FreeEnvironmentStringsW(wenv);
return result;
}
#else
static int do_putenv(char **env, const char *name, int size, int free_old);
/* used number of elements of environ array, including terminating NULL */
@@ -1372,6 +1513,7 @@ static wchar_t *make_environment_block(char **deltaenv)
free(tmpenv);
return wenvblk;
}
#endif
static void do_unset_environment_variables(void)
{
@@ -1621,7 +1763,10 @@ static int try_shell_exec(const char *cmd, char *const *argv)
prog = path_lookup(interpr, 1);
if (prog) {
int argc = 0;
const char **argv2;
#ifndef _MSC_VER
const
#endif
char **argv2;
while (argv[argc]) argc++;
ALLOC_ARRAY(argv2, argc + 1);
argv2[0] = (char *)cmd; /* full path to the script file */
@@ -1694,6 +1839,70 @@ int mingw_kill(pid_t pid, int sig)
return -1;
}
#if defined(_MSC_VER)
/* UTF8 versions of getenv and putenv (and unsetenv).
* Internally, they use the CRT's stock UNICODE routines
* to avoid data loss.
*
* Unlike the mingw version, we DO NOT directly write to
* the CRT variables. We also DO NOT try to manage/replace
* the CRT storage.
*/
char *msc_getenv(const char *name)
{
int len_key, len_value;
wchar_t *w_key;
char *value;
const wchar_t *w_value;
if (!name || !*name)
return NULL;
len_key = strlen(name) + 1;
w_key = calloc(len_key, sizeof(wchar_t));
xutftowcs(w_key, name, len_key);
w_value = _wgetenv(w_key);
free(w_key);
if (!w_value)
return NULL;
len_value = wcslen(w_value) * 3 + 1;
value = calloc(len_value, sizeof(char));
xwcstoutf(value, w_value, len_value);
/* TODO Warning: We return "value" which is an allocated
* value and the caller is NOT expecting to have to free
* it, so we leak memory.
*/
return value;
}
int msc_putenv(const char *name)
{
int len, result;
char *equal;
wchar_t *wide;
if (!name || !*name)
return 0;
len = strlen(name);
equal = strchr(name, '=');
wide = calloc(len+1+!equal, sizeof(wchar_t));
xutftowcs(wide, name, len+1);
if (!equal)
wcscat(wide, L"=");
result = _wputenv(wide);
free(wide);
return result;
}
#else
/*
* Compare environment entries by key (i.e. stopping at '=' or '\0').
*/
@@ -1822,6 +2031,8 @@ int mingw_putenv(const char *namevalue)
return 0;
}
#endif
/*
* Note, this isn't a complete replacement for getaddrinfo. It assumes
* that service contains a numerical port, or that it is null. It
@@ -2388,8 +2599,34 @@ int mingw_raise(int sig)
sigint_fn(SIGINT);
return 0;
#if defined(_MSC_VER)
/*
* <signal.h> in the CRT defines 8 signals as being
* supported on the platform. Anything else causes
* an "Invalid signal or error" (which in DEBUG builds
* causes the Abort/Retry/Ignore dialog). We by-pass
* the CRT for things we already know will fail.
*/
/*case SIGINT:*/
case SIGILL:
case SIGFPE:
case SIGSEGV:
case SIGTERM:
case SIGBREAK:
case SIGABRT:
case SIGABRT_COMPAT:
return raise(sig);
default:
errno = EINVAL;
return -1;
#else
default:
return raise(sig);
#endif
}
}
@@ -2481,7 +2718,10 @@ typedef struct _REPARSE_DATA_BUFFER {
DWORD ReparseTag;
WORD ReparseDataLength;
WORD Reserved;
_ANONYMOUS_UNION union {
#ifndef _MSC_VER
_ANONYMOUS_UNION
#endif
union {
struct {
WORD SubstituteNameOffset;
WORD SubstituteNameLength;
@@ -2856,6 +3096,7 @@ int handle_long_path(wchar_t *path, int len, int max_path, int expand)
}
}
#if !defined(_MSC_VER)
/*
* Disable MSVCRT command line wildcard expansion (__getmainargs called from
* mingw startup code, see init.c in mingw runtime).
@@ -2868,6 +3109,7 @@ typedef struct {
extern int __wgetmainargs(int *argc, wchar_t ***argv, wchar_t ***env, int glob,
_startupinfo *si);
#endif
static NORETURN void die_startup(void)
{
@@ -2963,6 +3205,96 @@ static void adjust_symlink_flags(void)
}
#if defined(_MSC_VER)
/*
* This routine sits between wmain() and "main" in git.exe.
* We receive UNICODE (wchar_t) values for argv and env.
*
* To be more compatible with the core git code, we convert
* argv into UTF8 and pass them directly to the "main" routine.
*
* We don't bother converting the given UNICODE env vector,
* but rather leave them in the CRT. We replaced the various
* getenv/putenv routines to pull them directly from the CRT.
*
* This is unlike the MINGW version:
* [] It does the UNICODE-2-UTF8 conversion on both sets and
* stuffs the values back into the CRT using exported symbols.
* [] It also maintains a private copy of the environment and
* tries to track external changes to it.
*/
int msc_startup(int argc, wchar_t **w_argv, wchar_t **w_env)
{
char **my_utf8_argv = NULL, **save = NULL;
char *buffer = NULL;
int maxlen;
int k, exit_status;
#ifdef USE_MSVC_CRTDBG
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
maybe_redirect_std_handles();
adjust_symlink_flags();
/* determine size of argv conversion buffer */
maxlen = wcslen(_wpgmptr);
for (k = 1; k < argc; k++)
maxlen = max(maxlen, wcslen(w_argv[k]));
/* allocate buffer (wchar_t encodes to max 3 UTF-8 bytes) */
maxlen = 3 * maxlen + 1;
buffer = malloc_startup(maxlen);
/*
* Create a UTF-8 version of w_argv. Also create a "save" copy
* to remember all the string pointers because parse_options()
* will remove claimed items from the argv that we pass down.
*/
ALLOC_ARRAY(my_utf8_argv, argc + 1);
ALLOC_ARRAY(save, argc + 1);
save[0] = my_utf8_argv[0] = wcstoutfdup_startup(buffer, _wpgmptr, maxlen);
for (k = 1; k < argc; k++)
save[k] = my_utf8_argv[k] = wcstoutfdup_startup(buffer, w_argv[k], maxlen);
save[k] = my_utf8_argv[k] = NULL;
free(buffer);
/* fix Windows specific environment settings */
setup_windows_environment();
unset_environment_variables = xstrdup("PERL5LIB");
/* initialize critical section for waitpid pinfo_t list */
InitializeCriticalSection(&pinfo_cs);
InitializeCriticalSection(&phantom_symlinks_cs);
/* set up default file mode and file modes for stdin/out/err */
_fmode = _O_BINARY;
_setmode(_fileno(stdin), _O_BINARY);
_setmode(_fileno(stdout), _O_BINARY);
_setmode(_fileno(stderr), _O_BINARY);
/* initialize Unicode console */
winansi_init();
/* init length of current directory for handle_long_path */
current_directory_len = GetCurrentDirectoryW(0, NULL);
/* invoke the real main() using our utf8 version of argv. */
exit_status = msc_main(argc, my_utf8_argv);
for (k = 0; k < argc; k++)
free(save[k]);
free(save);
free(my_utf8_argv);
return exit_status;
}
#else
void mingw_startup(void)
{
int i, maxlen, argc;
@@ -3042,6 +3374,8 @@ void mingw_startup(void)
current_directory_len = GetCurrentDirectoryW(0, NULL);
}
#endif
int uname(struct utsname *buf)
{
unsigned v = (unsigned)GetVersion();

View File

@@ -265,12 +265,53 @@ char *mingw_getcwd(char *pointer, int len);
#error "NO_UNSETENV is incompatible with the MinGW startup code!"
#endif
#if defined(_MSC_VER)
/*
* We bind *env() routines (even the mingw_ ones) to private msc_ versions.
* These talk to the CRT using UNICODE/wchar_t, but maintain the original
* narrow-char API.
*
* Note that the MSCRT maintains both ANSI (getenv()) and UNICODE (_wgetenv())
* routines and stores both versions of each environment variable in parallel
* (and secretly updates both when you set one or the other), but it uses CP_ACP
* to do the conversion rather than CP_UTF8.
*
* Since everything in the git code base is UTF8, we define the msc_ routines
* to access the CRT using the UNICODE routines and manually convert them to
* UTF8. This also avoids round-trip problems.
*
* This also helps with our linkage, since "_wenviron" is publicly exported
* from the CRT. But to access "_environ" we would have to statically link
* to the CRT (/MT).
*
* We also use "wmain(argc,argv,env)" and get the initial UNICODE setup for us.
* This avoids the need for the msc_startup() to import and convert the
* inherited environment.
*
* We require NO_SETENV (and let gitsetenv() call our msc_putenv).
*/
#define getenv msc_getenv
#define putenv msc_putenv
#define unsetenv msc_putenv
#define mingw_getenv msc_getenv
#define mingw_putenv msc_putenv
char *msc_getenv(const char *name);
int msc_putenv(const char *name);
#ifndef NO_SETENV
#error "NO_SETENV is required for MSC startup code!"
#endif
#else
char *mingw_getenv(const char *name);
#define getenv mingw_getenv
int mingw_putenv(const char *namevalue);
#define putenv mingw_putenv
#define unsetenv mingw_putenv
#endif
int mingw_gethostname(char *host, int namelen);
#define gethostname mingw_gethostname
@@ -353,11 +394,13 @@ static inline long long filetime_to_hnsec(const FILETIME *ft)
#ifndef __MINGW64_VERSION_MAJOR
#define off_t off64_t
#define lseek _lseeki64
#ifndef _MSC_VER
struct timespec {
time_t tv_sec;
long tv_nsec;
};
#endif
#endif
static inline void filetime_to_timespec(const FILETIME *ft, struct timespec *ts)
{
@@ -657,7 +700,26 @@ extern CRITICAL_SECTION pinfo_cs;
/*
* A replacement of main() that adds win32 specific initialization.
*
* Note that the end of these macros are unterminated so that the
* brace group following the use of the macro is the body of the
* function.
*/
#if defined(_MSC_VER)
int msc_startup(int argc, wchar_t **w_argv, wchar_t **w_env);
extern int msc_main(int argc, const char **argv);
#define main(c,v) dummy_decl_msc_main(void); \
int wmain(int my_argc, \
wchar_t **my_w_argv, \
wchar_t **my_w_env) \
{ \
return msc_startup(my_argc, my_w_argv, my_w_env); \
} \
int msc_main(c, v)
#else
void mingw_startup(void);
#define main(c,v) dummy_decl_mingw_main(void); \
@@ -669,6 +731,8 @@ int main(int argc, const char **argv) \
} \
static int mingw_main(c,v)
#endif
/*
* Used by Pthread API implementation for Windows
*/

View File

@@ -24,6 +24,12 @@ static __inline int strcasecmp (const char *s1, const char *s2)
#undef ERROR
#define ftello _ftelli64
typedef int sigset_t;
/* open for reading, writing, or both (not in fcntl.h) */
#define O_ACCMODE (_O_RDONLY | _O_WRONLY | _O_RDWR)
#include "compat/mingw.h"
#endif

1
compat/vcbuild/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
GEN.*

147
compat/vcbuild/Makefile Normal file
View File

@@ -0,0 +1,147 @@
## Makefile to install nuget package dependencies.
##################################################################
INST=GEN.DEPS
INST_INC=$(INST)/include
INST_LIB=$(INST)/lib
INST_BIN=$(INST)/bin
PKGDIR=GEN.PKGS
NUGET ?= nuget.exe
ifneq ($(shell $(NUGET) help 2>/dev/null; echo $$?),0)
NUGET := /usr/src/build-extra/nuget/nuget.exe
endif
##################################################################
all: unpack expat libssh libssh_redist curl curl_redist openssl zlib \
libiconv libiconv_redist
unpack:
[ -d $(PKGDIR) ] || mkdir $(PKGDIR)
"$(NUGET)" restore packages.config -ConfigFile nuget.config \
-NonInteractive -OutputDirectory $(PKGDIR)
insdir:
[ -d $(INST) ] || mkdir $(INST)
[ -d $(INST_INC) ] || mkdir $(INST_INC)
[ -d $(INST_BIN) ] || mkdir $(INST_BIN)
[ -d $(INST_LIB) ] || mkdir $(INST_LIB)
##################################################################
## We place the expat headers in their own subdirectory.
## The custom is to reference <expat.h>, so compile with:
## -I$(INST_INC)/expat
EXPAT_VER=2.1.0.11
EXPAT_ROOT=$(PKGDIR)/expat.$(EXPAT_VER)/build/native
EXPAT_INC=$(EXPAT_ROOT)/include
EXPAT_LIB=$(EXPAT_ROOT)/lib/v110/x64/Release/dynamic/utf8
expat: insdir
[ -d $(INST_INC)/expat ] || mkdir $(INST_INC)/expat
cp -r $(EXPAT_INC)/* $(INST_INC)/expat/
cp -r $(EXPAT_LIB)/* $(INST_LIB)/
##################################################################
LIBICONV_VER=1.14.0.11
LIBICONV_ROOT=$(PKGDIR)/libiconv.$(LIBICONV_VER)/build/native
LIBICONV_INC=$(LIBICONV_ROOT)/include
LIBICONV_LIB=$(LIBICONV_ROOT)/lib/v110/x64/Release/dynamic/cdecl
libiconv: insdir
cp -r $(LIBICONV_INC)/* $(INST_INC)/
cp -r $(LIBICONV_LIB)/libiconv.lib $(INST_LIB)/iconv.lib
LIBICONV_REDIST_ROOT=$(PKGDIR)/libiconv.redist.$(LIBICONV_VER)/build/native
LIBICONV_REDIST_BIN=$(LIBICONV_REDIST_ROOT)/bin/v110/x64/Release/dynamic/cdecl
libiconv_redist: insdir
cp -r $(LIBICONV_REDIST_BIN)/* $(INST_BIN)/
##################################################################
LIBSSH_VER=1.4.3.3
LIBSSH_ROOT=$(PKGDIR)/libssh2.$(LIBSSH_VER)/build/native
LIBSSH_INC=$(LIBSSH_ROOT)/include
LIBSSH_LIB=$(LIBSSH_ROOT)/lib/v110/x64/Release/dynamic/cdecl
libssh: insdir
[ -d $(INST_INC)/libssh2 ] || mkdir $(INST_INC)/libssh2
cp -r $(LIBSSH_INC)/* $(INST_INC)/libssh2
cp -r $(LIBSSH_LIB)/* $(INST_LIB)/
LIBSSH_REDIST_ROOT=$(PKGDIR)/libssh2.redist.$(LIBSSH_VER)/build/native
LIBSSH_REDIST_BIN=$(LIBSSH_REDIST_ROOT)/bin/v110/x64/Release/dynamic/cdecl
libssh_redist: insdir
cp -r $(LIBSSH_REDIST_BIN)/* $(INST_BIN)/
##################################################################
## We place the curl headers in their own subdirectory.
## The custom is to reference <curl/curl.h>, so compile with:
## -I$(INST_INC)
CURL_VER=7.30.0.2
CURL_ROOT=$(PKGDIR)/curl.$(CURL_VER)/build/native
CURL_INC=$(CURL_ROOT)/include/curl
CURL_LIB=$(CURL_ROOT)/lib/v110/x64/Release/dynamic
curl: insdir
[ -d $(INST_INC)/curl ] || mkdir $(INST_INC)/curl
cp -r $(CURL_INC)/* $(INST_INC)/curl
cp -r $(CURL_LIB)/* $(INST_LIB)/
CURL_REDIST_ROOT=$(PKGDIR)/curl.redist.$(CURL_VER)/build/native
CURL_REDIST_BIN=$(CURL_REDIST_ROOT)/bin/v110/x64/Release/dynamic
curl_redist: insdir
cp -r $(CURL_REDIST_BIN)/* $(INST_BIN)/
##################################################################
## We place the openssl headers in their own subdirectory.
## The custom is to reference <openssl/sha.h>, so compile with:
## -I$(INST_INC)
OPENSSL_VER=1.0.2.1
OPENSSL_ROOT=$(PKGDIR)/openssl.v140.windesktop.msvcstl.dyn.rt-dyn.x64.$(OPENSSL_VER)
OPENSSL_INC=$(OPENSSL_ROOT)/build/native/include/openssl
OPENSSL_LIB=$(OPENSSL_ROOT)/lib/native/v140/windesktop/msvcstl/dyn/rt-dyn/x64/release
openssl: insdir
[ -d $(INST_INC)/openssl ] || mkdir $(INST_INC)/openssl
cp -r $(OPENSSL_INC)/* $(INST_INC)/openssl
cp -r $(OPENSSL_LIB)/*.lib $(INST_LIB)/
cp -r $(OPENSSL_LIB)/*.dll $(INST_BIN)/
cp -r $(OPENSSL_LIB)/*.pdb $(INST_BIN)/
##################################################################
## We place the zlib headers in their own subdirectory.
## The custom is to reference <zlib.h>, so compile with:
## -I$(INST_INC)/zlib
ZLIB_VER=1.2.8.8
ZLIB_ROOT=$(PKGDIR)/zlib.v140.windesktop.msvcstl.dyn.rt-dyn.$(ZLIB_VER)
ZLIB_INC=$(ZLIB_ROOT)/build/native/include
ZLIB_LIB=$(ZLIB_ROOT)/lib/native/v140/windesktop/msvcstl/dyn/rt-dyn/x64/RelWithDebInfo
zlib: insdir
[ -d $(INST_INC)/zlib ] || mkdir $(INST_INC)/zlib
cp -r $(ZLIB_INC)/* $(INST_INC)/zlib
cp -r $(ZLIB_LIB)/*.lib $(INST_LIB)/
cp -r $(ZLIB_LIB)/*.dll $(INST_BIN)/
cp -r $(ZLIB_LIB)/*.pdb $(INST_BIN)/
##################################################################
clean:
rm -rf $(INST)
clobber: clean
rm -rf $(PKGDIR)

View File

@@ -0,0 +1,54 @@
Instructions for building Git for Windows using VS2015.
================================================================
Installing third-party dependencies:
====================================
[1] Install nuget.exe somewhere on your system and add it to your PATH.
https://docs.nuget.org/consume/command-line-reference
https://dist.nuget.org/index.html
[2] Download required nuget packages for third-party libraries.
Using a terminal window, type:
make -C compat/vcbuild
This will download the packages, unpack them into GEN.PKGS,
and populate the {include, lib, bin} directories in GEN.DEPS.
Building Git for Windows using VS2015:
======================================
[3] Build 64-bit version of Git for Windows.
Using a terminal window:
make MSVC=1 DEBUG=1
[4] Add compat/vcbuild/GEN.DEPS/bin to your PATH.
[5] You should then be able to run the test suite and any interactive
commands.
[6] To debug/profile in VS, open the git.exe in VS and run/debug
it. (Be sure to add GEN.DEPS/bin to the PATH in the debug
dialog.)
TODO List:
==========
[A] config.mak.uname currently contains hard-coded paths
to the various MSVC and SDK libraries for the 64-bit
version of the compilers and libaries.
See: SANE_TOOL_PATH, MSVC_DEPS, MSVC_SDK*, MSVC_VCDIR.
Long term, we need to figure out how to properly import
values for %VCINSTALLDIR%, %LIB%, %LIBPATH%, and the
other values normally set by "vsvars32.bat" when a
developer command prompt is started. This would also
allow us to switch between 32- and 64-bit tool chains.
[B] We need to build SLN or VCPROJ files.

View File

@@ -0,0 +1,167 @@
@ECHO OFF
REM ================================================================
REM You can use either GCC (the default) or MSVC to build git
REM using the GIT-SDK command line tools.
REM $ make
REM $ make MSVC=1
REM
REM GIT-SDK BASH windows inherit environment variables with all of
REM the bin/lib/include paths for GCC. It DOES NOT inherit values
REM for the corresponding MSVC tools.
REM
REM During normal (non-git) Windows development, you launch one
REM of the provided "developer command prompts" to set environment
REM variables for the MSVC tools.
REM
REM Therefore, to allow MSVC command line builds of git from BASH
REM and MAKE, we must blend these two different worlds. This script
REM attempts to do that.
REM ================================================================
REM This BAT file starts in a plain (non-developer) command prompt,
REM searches for the "best" commmand prompt setup script, installs
REM it into the current CMD process, and exports the various MSVC
REM environment variables for use by MAKE.
REM
REM The output of this script should be written to a make "include
REM file" and referenced by the top-level Makefile.
REM
REM See "config.mak.uname" (look for GIT-MSVC-GEN).
REM ================================================================
REM The provided command prompts are custom to each VS release and
REM filled with lots of internal knowledge (such as Registry settings);
REM even their names vary by release, so it is not appropriate for us
REM to look inside them. Rather, just run them in a subordinate
REM process and extract the settings we need.
REM ================================================================
REM
REM Current (VS2017 and beyond)
REM -------------------
REM Visual Studio 2017 introduced a new installation layout and
REM support for side-by-side installation of multiple versions of
REM VS2017. Furthermore, these can all coexist with installations
REM of previous versions of VS (which have a completely different
REM layout on disk).
REM
REM VS2017 Update 2 introduced a "vswhere.exe" command:
REM https://github.com/Microsoft/vswhere
REM https://blogs.msdn.microsoft.com/heaths/2017/02/25/vswhere-available/
REM https://blogs.msdn.microsoft.com/vcblog/2017/03/06/finding-the-visual-c-compiler-tools-in-visual-studio-2017/
REM
REM VS2015
REM ------
REM Visual Studio 2015 uses the traditional VcVarsAll.
REM
REM Earlier Versions
REM ----------------
REM TODO
REM
REM ================================================================
REM Note: Throughout this script we use "dir <path> && <cmd>" rather
REM than "if exist <path>" because of script problems with pathnames
REM containing spaces.
REM ================================================================
REM Sanitize PATH to prevent git-sdk paths from confusing "wmic.exe"
REM (called internally in some of the system BAT files).
SET PATH=%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;
REM ================================================================
:current
SET vs_where=C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe
dir "%vs_where%" >nul 2>nul && GOTO have_vs_where
GOTO not_2017
:have_vs_where
REM Try to use VsWhere to get the location of VsDevCmd.
REM Keep VsDevCmd from cd'ing away.
SET VSCMD_START_DIR=.
REM Get the root of the VS product installation.
FOR /F "usebackq tokens=*" %%i IN (`"%vs_where%" -latest -requires Microsoft.VisualStudio.Workload.NativeDesktop -property installationPath`) DO @SET vs_ip=%%i
SET vs_devcmd=%vs_ip%\Common7\Tools\VsDevCmd.bat
dir "%vs_devcmd%" >nul 2>nul && GOTO have_vs_devcmd
GOTO not_2017
:have_vs_devcmd
REM Use VsDevCmd to setup the environment of this process.
REM Setup CL for building 64-bit apps using 64-bit tools.
@call "%vs_devcmd%" -no_logo -arch=x64 -host_arch=x64
SET tgt=%VSCMD_ARG_TGT_ARCH%
SET mn=%VCToolsInstallDir%
SET msvc_includes=-I"%mn%INCLUDE"
SET msvc_libs=-L"%mn%lib\%tgt%"
SET msvc_bin_dir=%mn%bin\Host%VSCMD_ARG_HOST_ARCH%\%tgt%
SET sdk_dir=%WindowsSdkDir%
SET sdk_ver=%WindowsSDKVersion%
SET si=%sdk_dir%Include\%sdk_ver%
SET sdk_includes=-I"%si%ucrt" -I"%si%um" -I"%si%shared"
SET sl=%sdk_dir%lib\%sdk_ver%
SET sdk_libs=-L"%sl%ucrt\%tgt%" -L"%sl%um\%tgt%"
SET vs_ver=%VisualStudioVersion%
GOTO print_vars
REM ================================================================
:not_2017
REM See if VS2015 is installed.
SET vs_2015_bat=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat
dir "%vs_2015_bat%" >nul 2>nul && GOTO have_vs_2015
GOTO not_2015
:have_vs_2015
REM Use VcVarsAll like the "x64 Native" command prompt.
REM Setup CL for building 64-bit apps using 64-bit tools.
@call "%vs_2015_bat%" amd64
REM Note that in VS2015 they use "x64" in some contexts and "amd64" in others.
SET mn=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\
SET msvc_includes=-I"%mn%INCLUDE"
SET msvc_libs=-L"%mn%lib\amd64"
SET msvc_bin_dir=%mn%bin\amd64
SET sdk_dir=%WindowsSdkDir%
SET sdk_ver=%WindowsSDKVersion%
SET si=%sdk_dir%Include\%sdk_ver%
SET sdk_includes=-I"%si%ucrt" -I"%si%um" -I"%si%shared" -I"%si%winrt"
SET sl=%sdk_dir%lib\%sdk_ver%
SET sdk_libs=-L"%sl%ucrt\x64" -L"%sl%um\x64"
SET vs_ver=%VisualStudioVersion%
GOTO print_vars
REM ================================================================
:not_2015
REM TODO....
echo TODO support older versions of VS. >&2
EXIT /B 1
REM ================================================================
:print_vars
REM Dump the essential vars to stdout to allow the main
REM Makefile to include it. See config.mak.uname.
REM Include DOS-style and BASH-style path for bin dir.
echo msvc_bin_dir=%msvc_bin_dir%
echo msvc_bin_dir_msys=%msvc_bin_dir:C:=/C%
echo msvc_includes=%msvc_includes%
echo msvc_libs=%msvc_libs%
echo sdk_includes=%sdk_includes%
echo sdk_libs=%sdk_libs%
echo vs_ver=%vs_ver%
EXIT /B 0

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<!--
Used to specify the default location to expand packages.
See: NuGet.exe help install
See: NuGet.exe help update
-->
<add key="repositoryPath" value="Nupkg" />
</config>
<packageSources>
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
</packageSources>
<packageRestore>
<!-- Allow NuGet to download missing packages -->
<add key="enabled" value="True" />
<!-- Automatically check for missing packages during build in Visual Studio -->
<add key="automatic" value="False" />
</packageRestore>
<bindingRedirects>
<add key="skip" value="False" />
</bindingRedirects>
<activePackageSource>
<!-- this tells only one given source is active -->
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
</activePackageSource>
</configuration>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="curl" version="7.30.0.2" />
<package id="curl.redist" version="7.30.0.2" />
<package id="expat" version="2.1.0.11" />
<package id="libiconv" version="1.14.0.11" />
<package id="libiconv.redist" version="1.14.0.11" />
<package id="libssh2" version="1.4.3.3" />
<package id="libssh2.redist" version="1.4.3.3" />
<package id="openssl" version="1.0.2.1" />
<package id="openssl.v120.windesktop.msvcstl.dyn.rt-dyn" version="1.0.2.1" />
<package id="openssl.v120.windesktop.msvcstl.dyn.rt-dyn.x64" version="1.0.2.0" />
<package id="openssl.v120.windesktop.msvcstl.dyn.rt-dyn.x86" version="1.0.2.1" />
<package id="openssl.v140.windesktop.msvcstl.dyn.rt-dyn" version="1.0.2.1" />
<package id="openssl.v140.windesktop.msvcstl.dyn.rt-dyn.x64" version="1.0.2.1" />
<package id="openssl.v140.windesktop.msvcstl.dyn.rt-dyn.x86" version="1.0.2.1" />
<package id="zlib" version="1.2.8.8" />
<package id="zlib.v120.windesktop.msvcstl.dyn.rt-dyn" version="1.2.8.8" />
<package id="zlib.v140.windesktop.msvcstl.dyn.rt-dyn" version="1.2.8.8" />
</packages>

View File

@@ -12,18 +12,22 @@
use strict;
my @args = ();
my @cflags = ();
my @lflags = ();
my $is_linking = 0;
while (@ARGV) {
my $arg = shift @ARGV;
if ("$arg" =~ /^-[DIMGO]/) {
if ("$arg" =~ /^-[DIMGOZ]/) {
push(@cflags, $arg);
} elsif ("$arg" eq "-o") {
my $file_out = shift @ARGV;
if ("$file_out" =~ /exe$/) {
$is_linking = 1;
# Create foo.exe and foo.pdb
push(@args, "-OUT:$file_out");
} else {
# Create foo.o and foo.o.pdb
push(@args, "-Fo$file_out");
push(@args, "-Fd$file_out.pdb");
}
} elsif ("$arg" eq "-lz") {
push(@args, "zlib.lib");
@@ -35,9 +39,11 @@ while (@ARGV) {
push(@args, "ssleay32.lib");
} elsif ("$arg" eq "-lcurl") {
push(@args, "libcurl.lib");
} elsif ("$arg" eq "-lexpat") {
push(@args, "libexpat.lib");
} elsif ("$arg" =~ /^-L/ && "$arg" ne "-LTCG") {
$arg =~ s/^-L/-LIBPATH:/;
push(@args, $arg);
push(@lflags, $arg);
} elsif ("$arg" =~ /^-R/) {
# eat
} else {
@@ -45,10 +51,11 @@ while (@ARGV) {
}
}
if ($is_linking) {
push(@args, @lflags);
unshift(@args, "link.exe");
} else {
unshift(@args, "cl.exe");
push(@args, @cflags);
}
#printf("**** @args\n");
printf(STDERR "**** @args\n\n\n") if (!defined($ENV{'QUIET_GEN'}));
exit (system(@args) != 0);

View File

@@ -540,7 +540,20 @@ static HANDLE swap_osfhnd(int fd, HANDLE new_handle)
#ifdef DETECT_MSYS_TTY
#include <winternl.h>
#if defined(_MSC_VER)
typedef struct _OBJECT_NAME_INFORMATION
{
UNICODE_STRING Name;
WCHAR NameBuffer[0];
} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;
#define ObjectNameInformation 1
#else
#include <ntstatus.h>
#endif
static void detect_msys_tty(int fd)
{

View File

@@ -11,6 +11,12 @@ ifdef MSVC
# avoid the MingW and Cygwin configuration sections
uname_S := Windows
uname_O := Windows
# Generate and include makefile variables that point to the
# currently installed set of MSVC command line tools.
GIT-MSVC-GEN: ./compat/vcbuild/find_vs_env.bat
@./compat/vcbuild/find_vs_env.bat | sed 's|\\|/|g' >GIT-MSVC-GEN
-include GIT-MSVC-GEN
endif
# We choose to avoid "if .. else if .. else .. endif endif"
@@ -349,6 +355,19 @@ endif
ifeq ($(uname_S),Windows)
GIT_VERSION := $(GIT_VERSION).MSVC
pathsep = ;
# Assume that this is built in Git for Windows' SDK
ifeq (MINGW32,$(MSYSTEM))
prefix = /mingw32
else
prefix = /mingw64
endif
# Prepend MSVC 64-bit tool-chain to PATH.
#
# A regular Git Bash *does not* have cl.exe in its $PATH. As there is a
# link.exe next to, and required by, cl.exe, we have to prepend this
# onto the existing $PATH.
#
SANE_TOOL_PATH ?= $(msvc_bin_dir_msys)
HAVE_ALLOCA_H = YesPlease
NO_PREAD = YesPlease
NEEDS_CRYPTO_WITH_SSL = YesPlease
@@ -361,11 +380,16 @@ ifeq ($(uname_S),Windows)
NO_STRCASESTR = YesPlease
NO_STRLCPY = YesPlease
NO_MEMMEM = YesPlease
# NEEDS_LIBICONV = YesPlease
NO_ICONV = YesPlease
NEEDS_LIBICONV = YesPlease
NO_STRTOUMAX = YesPlease
NO_MKDTEMP = YesPlease
SNPRINTF_RETURNS_BOGUS = YesPlease
# VS2015 with UCRT claims that snprintf and friends are C99 compliant,
# so we don't need this.
#
# TODO If we want to support older compilers, we need to make this
# TODO conditional on the compiler version.
#
# SNPRINTF_RETURNS_BOGUS = YesPlease
NO_SVN_TESTS = YesPlease
RUNTIME_PREFIX = YesPlease
HAVE_WPGMPTR = YesWeDo
@@ -378,7 +402,6 @@ ifeq ($(uname_S),Windows)
NO_REGEX = YesPlease
NO_GETTEXT = YesPlease
NO_PYTHON = YesPlease
BLK_SHA1 = YesPlease
ETAGS_TARGET = ETAGS
NO_POSIX_GOODIES = UnfortunatelyYes
NATIVE_CRLF = YesPlease
@@ -387,24 +410,40 @@ ifeq ($(uname_S),Windows)
CC = compat/vcbuild/scripts/clink.pl
AR = compat/vcbuild/scripts/lib.pl
CFLAGS =
BASIC_CFLAGS = -nologo -I. -I../zlib -Icompat/vcbuild -Icompat/vcbuild/include -DWIN32 -D_CONSOLE -DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE
BASIC_CFLAGS = -nologo -I. -Icompat/vcbuild/include -DWIN32 -D_CONSOLE -DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE
COMPAT_OBJS = compat/msvc.o compat/winansi.o \
compat/win32/pthread.o compat/win32/syslog.o \
compat/win32/dirent.o compat/win32/fscache.o
COMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DNOGDI -DHAVE_STRING_H -Icompat -Icompat/regex -Icompat/win32 -DSTRIP_EXTENSION=\".exe\"
COMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DDETECT_MSYS_TTY -DNOGDI -DHAVE_STRING_H -Icompat -Icompat/regex -Icompat/win32 -DSTRIP_EXTENSION=\".exe\"
BASIC_LDFLAGS = -IGNORE:4217 -IGNORE:4049 -NOLOGO -SUBSYSTEM:CONSOLE
EXTLIBS = user32.lib advapi32.lib shell32.lib wininet.lib ws2_32.lib invalidcontinue.obj
EXTLIBS = user32.lib advapi32.lib shell32.lib wininet.lib ws2_32.lib invalidcontinue.obj kernel32.lib ntdll.lib
PTHREAD_LIBS =
lib =
# Path to the unpacked third-party libraries
MSVC_DEPS = compat/vcbuild/GEN.DEPS
BASIC_CFLAGS += \
-I$(MSVC_DEPS)/include -I$(MSVC_DEPS)/include/expat -I$(MSVC_DEPS)/include/zlib \
-L$(MSVC_DEPS)/lib \
$(sdk_includes) $(sdk_libs) \
$(msvc_includes) $(msvc_libs)
# Optionally enable memory leak reporting.
# BASIC_CLFAGS += -DUSE_MSVC_CRTDBG
BASIC_CFLAGS += -DPROTECT_NTFS_DEFAULT=1
# Always give "-Zi" to the compiler and "-debug" to linker (even in
# release mode) to force a PDB to be generated (like RelWithDebInfo).
BASIC_CFLAGS += -Zi
BASIC_LDFLAGS += -debug
ifndef DEBUG
BASIC_CFLAGS += -GL -Os -MD
BASIC_LDFLAGS += -LTCG
BASIC_CFLAGS += -GL -Gy -O2 -Oy- -MD -DNDEBUG
BASIC_LDFLAGS += -release -LTCG /OPT:REF /OPT:ICF /INCREMENTAL:NO /DEBUGTYPE:CV,FIXUP
AR += -LTCG
else
BASIC_CFLAGS += -Zi -MDd
BASIC_CFLAGS += -MDd -DDEBUG -D_DEBUG
endif
X = .exe
compat/msvc.o: compat/msvc.c compat/mingw.c GIT-CFLAGS
endif
ifeq ($(uname_S),Interix)
NO_INITGROUPS = YesPlease

View File

@@ -282,7 +282,7 @@ sub handleLibLine
# exit(1);
foreach (@objfiles) {
my $sourcefile = $_;
$sourcefile =~ s/\.o/.c/;
$sourcefile =~ s/\.o$/.c/;
push(@sources, $sourcefile);
push(@cflags, @{$compile_options{"${sourcefile}_CFLAGS"}});
push(@defines, @{$compile_options{"${sourcefile}_DEFINES"}});
@@ -326,8 +326,12 @@ sub handleLinkLine
} elsif ($part =~ /\.(a|lib)$/) {
$part =~ s/\.a$/.lib/;
push(@libs, $part);
} elsif ($part =~ /\.(o|obj)$/) {
} elsif ($part eq 'invalidcontinue.obj') {
# ignore - known to MSVC
} elsif ($part =~ /\.o$/) {
push(@objfiles, $part);
} elsif ($part =~ /\.obj$/) {
# do nothing, 'make' should not be producing .obj, only .o files
} else {
die "Unhandled lib option @ line $lineno: $part";
}
@@ -336,7 +340,7 @@ sub handleLinkLine
# exit(1);
foreach (@objfiles) {
my $sourcefile = $_;
$sourcefile =~ s/\.o/.c/;
$sourcefile =~ s/\.o$/.c/;
push(@sources, $sourcefile);
push(@cflags, @{$compile_options{"${sourcefile}_CFLAGS"}});
push(@defines, @{$compile_options{"${sourcefile}_DEFINES"}});

View File

@@ -1,6 +1,15 @@
#ifndef GIT_COMPAT_UTIL_H
#define GIT_COMPAT_UTIL_H
#ifdef USE_MSVC_CRTDBG
/*
* For these to work they must appear very early in each
* file -- before most of the standard header files.
*/
#include <stdlib.h>
#include <crtdbg.h>
#endif
#define _FILE_OFFSET_BITS 64
@@ -272,6 +281,33 @@ extern char *gitdirname(char *);
#ifndef NO_ICONV
#include <iconv.h>
#ifdef _MSC_VER
/*
* At least version 1.14.0.11 of the libiconv NuPkg at
* https://www.nuget.org/packages/libiconv/ does not set errno at all.
*
* Let's simulate it by testing whether we might have possibly run out of
* space.
*/
static inline size_t msvc_iconv(iconv_t conv,
const char **inpos, size_t *insize,
char **outpos, size_t *outsize)
{
int saved_errno = errno;
size_t res;
errno = ENOENT;
res = iconv(conv, inpos, insize, outpos, outsize);
if (!res)
errno = saved_errno;
else if (errno == ENOENT)
errno = *outsize < 16 ? E2BIG : 0;
return res;
}
#undef iconv
#define iconv msvc_iconv
#endif
#endif
#ifndef NO_OPENSSL

View File

@@ -332,7 +332,7 @@ test_expect_success 'difftool --extcmd cat arg1' '
test_expect_success 'difftool --extcmd cat arg2' '
echo branch >expect &&
git difftool --no-prompt \
--extcmd sh\ -c\ \"cat\ \$2\" branch >actual &&
--extcmd sh\ -c\ \"cat\ \\\"\$2\\\"\" branch >actual &&
test_cmp expect actual
'