Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix MSVC support, at long last #149

Closed
wants to merge 20 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitattributes
Expand Up @@ -5,6 +5,7 @@
*.pl eof=lf diff=perl
*.pm eol=lf diff=perl
*.py eol=lf diff=python
*.bat eol=crlf
/Documentation/**/*.txt eol=lf
/command-list.txt eol=lf
/GIT-VERSION-GEN eol=lf
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Expand Up @@ -226,6 +226,11 @@
*.user
*.idb
*.pdb
*.ilk
*.iobj
*.ipdb
*.dll
.vs/
/Debug/
/Release/
*.dSYM
42 changes: 41 additions & 1 deletion Makefile
Expand Up @@ -1240,7 +1240,7 @@ endif

dscho marked this conversation as resolved.
Show resolved Hide resolved
dscho marked this conversation as resolved.
Show resolved Hide resolved
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'
Expand Down Expand Up @@ -2873,6 +2873,33 @@ 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
# 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)'
ifndef DEBUG
$(INSTALL) $(vcpkg_rel_bin)/*.dll '$(DESTDIR_SQ)$(bindir_SQ)'
$(INSTALL) $(vcpkg_rel_bin)/*.pdb '$(DESTDIR_SQ)$(bindir_SQ)'
else
$(INSTALL) $(vcpkg_dbg_bin)/*.dll '$(DESTDIR_SQ)$(bindir_SQ)'
$(INSTALL) $(vcpkg_dbg_bin)/*.pdb '$(DESTDIR_SQ)$(bindir_SQ)'
endif
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)'
Expand Down Expand Up @@ -3085,6 +3112,19 @@ 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,%.iobj,$(OTHER_PROGRAMS))
$(RM) $(patsubst %.exe,%.ipdb,$(OTHER_PROGRAMS))
$(RM) $(patsubst %.exe,%.pdb,$(PROGRAMS))
$(RM) $(patsubst %.exe,%.iobj,$(PROGRAMS))
$(RM) $(patsubst %.exe,%.ipdb,$(PROGRAMS))
$(RM) $(patsubst %.exe,%.pdb,$(TEST_PROGRAMS))
$(RM) $(patsubst %.exe,%.iobj,$(TEST_PROGRAMS))
$(RM) $(patsubst %.exe,%.ipdb,$(TEST_PROGRAMS))
$(RM) compat/vcbuild/MSVC-DEFS-GEN
endif

.PHONY: all install profile-clean cocciclean clean strip
.PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
Expand Down
6 changes: 3 additions & 3 deletions builtin/blame.c
Expand Up @@ -59,8 +59,8 @@ static size_t blame_date_width;

static struct string_list mailmap = STRING_LIST_INIT_NODUP;

#ifndef DEBUG
#define DEBUG 0
#ifndef DEBUG_BLAME
#define DEBUG_BLAME 0
#endif

static unsigned blame_move_score;
Expand Down Expand Up @@ -1062,7 +1062,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
if (blame_copy_score)
sb.copy_score = blame_copy_score;

sb.debug = DEBUG;
sb.debug = DEBUG_BLAME;
sb.on_sanity_fail = &sanity_check_on_fail;

sb.show_root = show_root;
Expand Down
14 changes: 7 additions & 7 deletions cache-tree.c
Expand Up @@ -6,8 +6,8 @@
#include "object-store.h"
dscho marked this conversation as resolved.
Show resolved Hide resolved
dscho marked this conversation as resolved.
Show resolved Hide resolved
#include "replace-object.h"

#ifndef DEBUG
#define DEBUG 0
#ifndef DEBUG_CACHE_TREE
#define DEBUG_CACHE_TREE 0
#endif

struct cache_tree *cache_tree(void)
Expand Down Expand Up @@ -111,7 +111,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

Expand Down Expand Up @@ -398,7 +398,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
Expand All @@ -421,7 +421,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));
Expand Down Expand Up @@ -462,7 +462,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,
Expand Down Expand Up @@ -536,7 +536,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,
Expand Down
99 changes: 79 additions & 20 deletions compat/mingw.c
Expand Up @@ -1553,7 +1553,10 @@ static int try_shell_exec(const char *cmd, char *const *argv)
if (prog) {
dscho marked this conversation as resolved.
Show resolved Hide resolved
int exec_id;
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 */
Expand Down Expand Up @@ -2116,8 +2119,33 @@ int mingw_raise(int sig)
sigint_fn(SIGINT);
return 0;

#if defined(_MSC_VER)
case SIGILL:
case SIGFPE:
case SIGSEGV:
case SIGTERM:
case SIGBREAK:
case SIGABRT:
case SIGABRT_COMPAT:
/*
* The <signal.h> header in the MS C Runtime 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.
*/
return raise(sig);
default:
errno = EINVAL;
return -1;

#else

default:
return raise(sig);

#endif

}
}

Expand Down Expand Up @@ -2301,18 +2329,13 @@ static void setup_windows_environment(void)
setenv("TERM", "cygwin", 1);
}

#if !defined(_MSC_VER)
/*
* Disable MSVCRT command line wildcard expansion (__getmainargs called from
* mingw startup code, see init.c in mingw runtime).
*/
int _CRT_glob = 0;

typedef struct {
int newmode;
} _startupinfo;

extern int __wgetmainargs(int *argc, wchar_t ***argv, wchar_t ***env, int glob,
_startupinfo *si);
#endif

static NORETURN void die_startup(void)
{
Expand Down Expand Up @@ -2390,21 +2413,40 @@ static void maybe_redirect_std_handles(void)
GENERIC_WRITE, FILE_FLAG_NO_BUFFERING);
}

void mingw_startup(void)
#ifdef _MSC_VER
#ifdef _DEBUG
#include <crtdbg.h>
#endif
#endif

/*
* We implement wmain() and compile with -municode, which would
* normally ignore main(), but we call the latter from the former
* so that we can handle non-ASCII command-line parameters
* appropriately.
*
* To be more compatible with the core git code, we convert
* argv into UTF8 and pass them directly to main().
*/
int wmain(int argc, const wchar_t **wargv)
{
int i, maxlen, argc;
char *buffer;
wchar_t **wenv, **wargv;
_startupinfo si;
int i, maxlen, exit_status;
char *buffer, **save;
const char **argv;

trace2_initialize_clock();

maybe_redirect_std_handles();
#ifdef _MSC_VER
#ifdef _DEBUG
_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG);
#endif

/* get wide char arguments and environment */
si.newmode = 0;
if (__wgetmainargs(&argc, &wargv, &wenv, _CRT_glob, &si) < 0)
die_startup();
#ifdef USE_MSVC_CRTDBG
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
#endif

maybe_redirect_std_handles();

/* determine size of argv and environ conversion buffer */
maxlen = wcslen(wargv[0]);
Expand All @@ -2415,9 +2457,16 @@ void mingw_startup(void)
maxlen = 3 * maxlen + 1;
buffer = malloc_startup(maxlen);

/* convert command line arguments and environment to UTF-8 */
/*
* 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(argv, argc + 1);
ALLOC_ARRAY(save, argc + 1);
for (i = 0; i < argc; i++)
__argv[i] = wcstoutfdup_startup(buffer, wargv[i], maxlen);
argv[i] = save[i] = wcstoutfdup_startup(buffer, wargv[i], maxlen);
argv[i] = save[i] = NULL;
free(buffer);

/* fix Windows specific environment settings */
Expand All @@ -2436,6 +2485,16 @@ void mingw_startup(void)

/* initialize Unicode console */
winansi_init();

/* invoke the real main() using our utf8 version of argv. */
exit_status = main(argc, argv);

for (i = 0; i < argc; i++)
free(save[i]);
free(save);
free(argv);

return exit_status;
}

int uname(struct utsname *buf)
Expand Down
24 changes: 13 additions & 11 deletions compat/mingw.h
Expand Up @@ -352,11 +352,13 @@ static inline int getrlimit(int resource, struct rlimit *rlp)
#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

struct mingw_stat {
_dev_t st_dev;
Expand Down Expand Up @@ -562,18 +564,18 @@ int xwcstoutf(char *utf, const wchar_t *wcs, size_t utflen);
extern CRITICAL_SECTION pinfo_cs;

/*
* A replacement of main() that adds win32 specific initialization.
* Git, like most portable C applications, implements a main() function. On
* Windows, this main() function would receive parameters encoded in the
* current locale, but Git for Windows would prefer UTF-8 encoded parameters.
*
* To make that happen, we still declare main() here, and then declare and
* implement wmain() (which is the Unicode variant of main()) and compile with
* -municode. This wmain() function reencodes the parameters from UTF-16 to
* UTF-8 format, sets up a couple of other things as required on Windows, and
* then hands off to the main() function.
*/

void mingw_startup(void);
#define main(c,v) dummy_decl_mingw_main(void); \
static int mingw_main(c,v); \
int main(int argc, const char **argv) \
{ \
mingw_startup(); \
return mingw_main(__argc, (void *)__argv); \
} \
static int mingw_main(c,v)
int wmain(int argc, const wchar_t **w_argv);
int main(int argc, const char **argv);

/*
* Used by Pthread API implementation for Windows
Expand Down
10 changes: 10 additions & 0 deletions compat/msvc.h
Expand Up @@ -6,6 +6,10 @@
#include <malloc.h>
#include <io.h>

#pragma warning(disable: 4018) /* signed/unsigned comparison */
#pragma warning(disable: 4244) /* type conversion, possible loss of data */
#pragma warning(disable: 4090) /* 'function' : different 'const' qualifiers (ALLOC_GROW etc.)*/

/* porting function */
#define inline __inline
#define __inline__ __inline
Expand All @@ -18,6 +22,12 @@

#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
2 changes: 1 addition & 1 deletion compat/obstack.h
Expand Up @@ -496,7 +496,7 @@ __extension__ \
( (h)->temp.tempint = (char *) (obj) - (char *) (h)->chunk, \
((((h)->temp.tempint > 0 \
&& (h)->temp.tempint < (h)->chunk_limit - (char *) (h)->chunk)) \
? (int) ((h)->next_free = (h)->object_base \
? (ptrdiff_t) ((h)->next_free = (h)->object_base \
= (h)->temp.tempint + (char *) (h)->chunk) \
: (((obstack_free) ((h), (h)->temp.tempint + (char *) (h)->chunk), 0), 0)))

Expand Down
3 changes: 3 additions & 0 deletions compat/vcbuild/.gitignore
@@ -0,0 +1,3 @@
/vcpkg/
/MSVC-DEFS-GEN
/VCPKG-DEFS