Skip to content

Commit 7c049ab

Browse files
committed
Add full mingw-w64-git (i.e. regular MSYS2 ecosystem) support (#5971)
Every once in a while, there are bug reports in Git for Windows' bug tracker that describe an issue running [inside MSYS2 proper](https://gitforwindows.org/install-inside-msys2-proper), totally ignoring the big, honking warning on top of [the page](https://gitforwindows.org/install-inside-msys2-proper) that spells out clearly that this is an unsupported use case. At the same time, we cannot easily deflect and say "just use MSYS2 directly" (and leave the "and stop pestering us" out). We cannot do that because there is only an _MSYS_ `git` package in MSYS2 (i.e. a Git that uses the quite slow POSIX emulation layer provided by the MSYS2 runtime), but no `mingw-w64-git` package (which would be equivalent in speed to Git for Windows). In msys2/MINGW-packages#26470, I am preparing to change that. As part of that PR, I noticed and fixed a couple of issues _in `git-for-windows/git` that prevented full support for `mingw-w64-git` in MSYS2, such as problems with CLANG64 and UCRT64. While at it, I simplified the entire setup to trust MSYS2's `MINGW_PREFIX` & related environment variables instead of hard-coding values like the installation prefix and what `MSYSTEM` to fall back on if it is unset.
2 parents b0af2fa + aabc6fc commit 7c049ab

File tree

6 files changed

+68
-116
lines changed

6 files changed

+68
-116
lines changed

compat/mingw.c

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3620,7 +3620,7 @@ int xwcstoutf(char *utf, const wchar_t *wcs, size_t utflen)
36203620
}
36213621

36223622
#ifdef ENSURE_MSYSTEM_IS_SET
3623-
#if !defined(RUNTIME_PREFIX) || !defined(HAVE_WPGMPTR)
3623+
#if !defined(RUNTIME_PREFIX) || !defined(HAVE_WPGMPTR) || !defined(MINGW_PREFIX)
36243624
static size_t append_system_bin_dirs(char *path UNUSED, size_t size UNUSED)
36253625
{
36263626
return 0;
@@ -3638,25 +3638,16 @@ static size_t append_system_bin_dirs(char *path, size_t size)
36383638
/* strip trailing `git.exe` */
36393639
len = slash - prefix;
36403640

3641-
/* strip trailing `cmd` or `mingw64\bin` or `mingw32\bin` or `bin` or `libexec\git-core` */
3642-
if (strip_suffix_mem(prefix, &len, "\\mingw64\\libexec\\git-core") ||
3643-
strip_suffix_mem(prefix, &len, "\\mingw64\\bin"))
3641+
/* strip trailing `cmd` or `<mingw-prefix>\bin` or `bin` or `libexec\git-core` */
3642+
if (strip_suffix_mem(prefix, &len, "\\" MINGW_PREFIX "\\libexec\\git-core") ||
3643+
strip_suffix_mem(prefix, &len, "\\" MINGW_PREFIX "\\bin"))
36443644
off += xsnprintf(path + off, size - off,
3645-
"%.*s\\mingw64\\bin;", (int)len, prefix);
3646-
else if (strip_suffix_mem(prefix, &len, "\\clangarm64\\libexec\\git-core") ||
3647-
strip_suffix_mem(prefix, &len, "\\clangarm64\\bin"))
3648-
off += xsnprintf(path + off, size - off,
3649-
"%.*s\\clangarm64\\bin;", (int)len, prefix);
3650-
else if (strip_suffix_mem(prefix, &len, "\\mingw32\\libexec\\git-core") ||
3651-
strip_suffix_mem(prefix, &len, "\\mingw32\\bin"))
3652-
off += xsnprintf(path + off, size - off,
3653-
"%.*s\\mingw32\\bin;", (int)len, prefix);
3645+
"%.*s\\" MINGW_PREFIX "\\bin;", (int)len, prefix);
36543646
else if (strip_suffix_mem(prefix, &len, "\\cmd") ||
36553647
strip_suffix_mem(prefix, &len, "\\bin") ||
36563648
strip_suffix_mem(prefix, &len, "\\libexec\\git-core"))
36573649
off += xsnprintf(path + off, size - off,
3658-
"%.*s\\mingw%d\\bin;", (int)len, prefix,
3659-
(int)(sizeof(void *) * 8));
3650+
"%.*s\\" MINGW_PREFIX "\\bin;", (int)len, prefix);
36603651
else
36613652
return 0;
36623653

@@ -3752,13 +3743,7 @@ static void setup_windows_environment(void)
37523743
char buf[32768];
37533744
size_t off = 0;
37543745

3755-
#if defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC)
3756-
setenv("MSYSTEM", "CLANGARM64", 1);
3757-
#elif defined(__MINGW64__) || defined(_M_AMD64)
3758-
setenv("MSYSTEM", "MINGW64", 1);
3759-
#else
3760-
setenv("MSYSTEM", "MINGW32", 1);
3761-
#endif
3746+
setenv("MSYSTEM", ENSURE_MSYSTEM_IS_SET, 1);
37623747

37633748
if (home)
37643749
off += xsnprintf(buf + off, sizeof(buf) - off,

config.mak.uname

Lines changed: 24 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -449,14 +449,8 @@ ifeq ($(uname_S),Windows)
449449
GIT_VERSION := $(GIT_VERSION).MSVC
450450
pathsep = ;
451451
# Assume that this is built in Git for Windows' SDK
452-
ifeq (MINGW32,$(MSYSTEM))
453-
prefix = /mingw32
454-
else
455-
ifeq (CLANGARM64,$(MSYSTEM))
456-
prefix = /clangarm64
457-
else
458-
prefix = /mingw64
459-
endif
452+
ifneq (,$(MSYSTEM))
453+
prefix = $(MINGW_PREFIX)
460454
endif
461455
# Prepend MSVC 64-bit tool-chain to PATH.
462456
#
@@ -510,7 +504,7 @@ ifeq ($(uname_S),Windows)
510504
NATIVE_CRLF = YesPlease
511505
DEFAULT_HELP_FORMAT = html
512506
SKIP_DASHED_BUILT_INS = YabbaDabbaDoo
513-
ifeq (/mingw64,$(subst 32,64,$(subst clangarm,mingw,$(prefix))))
507+
ifneq (,$(MINGW_PREFIX))
514508
# Move system config into top-level /etc/
515509
ETC_GITCONFIG = ../etc/gitconfig
516510
ETC_GITATTRIBUTES = ../etc/gitattributes
@@ -526,7 +520,9 @@ endif
526520
compat/win32/pthread.o compat/win32/syslog.o \
527521
compat/win32/trace2_win32_process_info.o \
528522
compat/win32/dirent.o compat/win32/fscache.o compat/win32/wsl.o
529-
COMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DDETECT_MSYS_TTY -DENSURE_MSYSTEM_IS_SET -DNOGDI -DHAVE_STRING_H -Icompat -Icompat/regex -Icompat/win32 -DSTRIP_EXTENSION=\".exe\"
523+
COMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DDETECT_MSYS_TTY \
524+
-DENSURE_MSYSTEM_IS_SET="\"$(MSYSTEM)\"" -DMINGW_PREFIX="\"$(patsubst /%,%,$(MINGW_PREFIX))\"" \
525+
-DNOGDI -DHAVE_STRING_H -Icompat -Icompat/regex -Icompat/win32 -DSTRIP_EXTENSION=\".exe\"
530526
BASIC_LDFLAGS = -IGNORE:4217 -IGNORE:4049 -NOLOGO
531527
# invalidcontinue.obj allows Git's source code to close the same file
532528
# handle twice, or to access the osfhandle of an already-closed stdout
@@ -744,26 +740,25 @@ ifeq ($(uname_S),MINGW)
744740
ifneq (,$(findstring -O,$(filter-out -O0 -Og,$(CFLAGS))))
745741
BASIC_LDFLAGS += -Wl,--dynamicbase
746742
endif
747-
ifeq (MINGW32,$(MSYSTEM))
748-
prefix = /mingw32
749-
HOST_CPU = i686
750-
BASIC_LDFLAGS += -Wl,--pic-executable,-e,_mainCRTStartup
751-
endif
752-
ifeq (MINGW64,$(MSYSTEM))
753-
prefix = /mingw64
754-
HOST_CPU = x86_64
755-
BASIC_LDFLAGS += -Wl,--pic-executable,-e,mainCRTStartup
756-
else ifeq (CLANGARM64,$(MSYSTEM))
757-
prefix = /clangarm64
758-
HOST_CPU = aarch64
759-
BASIC_LDFLAGS += -Wl,--pic-executable,-e,mainCRTStartup
760-
else
761-
COMPAT_CFLAGS += -D_USE_32BIT_TIME_T
762-
BASIC_LDFLAGS += -Wl,--large-address-aware
743+
ifneq (,$(MSYSTEM))
744+
ifeq ($(MINGW_PREFIX),$(filter-out /%,$(MINGW_PREFIX)))
745+
# Override if empty or does not start with a slash
746+
MINGW_PREFIX := /$(shell echo '$(MSYSTEM)' | tr A-Z a-z)
747+
endif
748+
prefix = $(MINGW_PREFIX)
749+
HOST_CPU = $(patsubst %-w64-mingw32,%,$(MINGW_CHOST))
750+
BASIC_LDFLAGS += -Wl,--pic-executable
751+
COMPAT_CFLAGS += -DDETECT_MSYS_TTY \
752+
-DENSURE_MSYSTEM_IS_SET="\"$(MSYSTEM)\"" \
753+
-DMINGW_PREFIX="\"$(patsubst /%,%,$(MINGW_PREFIX))\""
754+
ifeq (MINGW32,$(MSYSTEM))
755+
BASIC_LDFLAGS += -Wl,--large-address-aware
756+
endif
757+
# Move system config into top-level /etc/
758+
ETC_GITCONFIG = ../etc/gitconfig
759+
ETC_GITATTRIBUTES = ../etc/gitattributes
763760
endif
764-
CC = gcc
765-
COMPAT_CFLAGS += -D__USE_MINGW_ANSI_STDIO=0 -DDETECT_MSYS_TTY \
766-
-DENSURE_MSYSTEM_IS_SET -fstack-protector-strong
761+
COMPAT_CFLAGS += -D__USE_MINGW_ANSI_STDIO=0 -fstack-protector-strong
767762
EXTLIBS += -lntdll
768763
EXTRA_PROGRAMS += headless-git$X
769764
INSTALL = /bin/install
@@ -773,62 +768,6 @@ ifeq ($(uname_S),MINGW)
773768
USE_LIBPCRE = YesPlease
774769
USE_MIMALLOC = YesPlease
775770
NO_PYTHON =
776-
ifeq (/mingw64,$(subst 32,64,$(subst clangarm,mingw,$(prefix))))
777-
# Move system config into top-level /etc/
778-
ETC_GITCONFIG = ../etc/gitconfig
779-
ETC_GITATTRIBUTES = ../etc/gitattributes
780-
endif
781-
MINGW_PREFIX := $(subst /,,$(prefix))
782-
783-
DESTDIR_WINDOWS = $(shell cygpath -aw '$(DESTDIR_SQ)')
784-
DESTDIR_MIXED = $(shell cygpath -am '$(DESTDIR_SQ)')
785-
install-mingit-test-artifacts:
786-
install -m755 -d '$(DESTDIR_SQ)/usr/bin'
787-
printf '%s\n%s\n' >'$(DESTDIR_SQ)/usr/bin/perl' \
788-
"#!/mingw64/bin/busybox sh" \
789-
"exec \"$(shell cygpath -am /usr/bin/perl.exe)\" \"\$$@\""
790-
791-
install -m755 -d '$(DESTDIR_SQ)'
792-
printf '%s%s\n%s\n%s\n%s\n%s\n' >'$(DESTDIR_SQ)/init.bat' \
793-
"PATH=$(DESTDIR_WINDOWS)\\$(MINGW_PREFIX)\\bin;" \
794-
"C:\\WINDOWS;C:\\WINDOWS\\system32" \
795-
"@set GIT_TEST_INSTALLED=$(DESTDIR_MIXED)/$(MINGW_PREFIX)/bin" \
796-
"@`echo "$(DESTDIR_WINDOWS)" | sed 's/:.*/:/'`" \
797-
"@cd `echo "$(DESTDIR_WINDOWS)" | sed 's/^.://'`\\test-git\\t" \
798-
"@echo Now, run 'helper\\test-run-command testsuite'"
799-
800-
install -m755 -d '$(DESTDIR_SQ)/test-git'
801-
sed 's/^\(NO_PERL\|NO_PYTHON\)=.*/\1=YesPlease/' \
802-
<GIT-BUILD-OPTIONS >'$(DESTDIR_SQ)/test-git/GIT-BUILD-OPTIONS'
803-
804-
install -m755 -d '$(DESTDIR_SQ)/test-git/t/helper'
805-
install -m755 $(TEST_PROGRAMS) '$(DESTDIR_SQ)/test-git/t/helper'
806-
(cd t && $(TAR) cf - t[0-9][0-9][0-9][0-9] lib-diff) | \
807-
(cd '$(DESTDIR_SQ)/test-git/t' && $(TAR) xf -)
808-
install -m755 t/t556x_common t/*.sh '$(DESTDIR_SQ)/test-git/t'
809-
810-
install -m755 -d '$(DESTDIR_SQ)/test-git/templates'
811-
(cd templates && $(TAR) cf - blt) | \
812-
(cd '$(DESTDIR_SQ)/test-git/templates' && $(TAR) xf -)
813-
814-
# po/build/locale for t0200
815-
install -m755 -d '$(DESTDIR_SQ)/test-git/po/build/locale'
816-
(cd po/build/locale && $(TAR) cf - .) | \
817-
(cd '$(DESTDIR_SQ)/test-git/po/build/locale' && $(TAR) xf -)
818-
819-
# git-daemon.exe for t5802, git-http-backend.exe for t5560
820-
install -m755 -d '$(DESTDIR_SQ)/$(MINGW_PREFIX)/bin'
821-
install -m755 git-daemon.exe git-http-backend.exe \
822-
'$(DESTDIR_SQ)/$(MINGW_PREFIX)/bin'
823-
824-
# git-upload-archive (dashed) for t5000
825-
install -m755 -d '$(DESTDIR_SQ)/$(MINGW_PREFIX)/bin'
826-
install -m755 git-upload-archive.exe '$(DESTDIR_SQ)/$(MINGW_PREFIX)/bin'
827-
828-
# git-difftool--helper for t7800
829-
install -m755 -d '$(DESTDIR_SQ)/$(MINGW_PREFIX)/libexec/git-core'
830-
install -m755 git-difftool--helper \
831-
'$(DESTDIR_SQ)/$(MINGW_PREFIX)/libexec/git-core'
832771
endif
833772
ifeq ($(uname_S),QNX)
834773
COMPAT_CFLAGS += -DSA_RESTART=0

contrib/buildsystems/CMakeLists.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,14 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
282282
_CONSOLE DETECT_MSYS_TTY STRIP_EXTENSION=".exe" NO_SYMLINK_HEAD UNRELIABLE_FSTAT
283283
NOGDI OBJECT_CREATION_MODE=1 __USE_MINGW_ANSI_STDIO=0
284284
USE_NED_ALLOCATOR OVERRIDE_STRDUP MMAP_PREVENTS_DELETE USE_WIN32_MMAP
285-
HAVE_WPGMPTR ENSURE_MSYSTEM_IS_SET HAVE_RTLGENRANDOM)
285+
HAVE_WPGMPTR HAVE_RTLGENRANDOM)
286+
if(CMAKE_GENERATOR_PLATFORM STREQUAL "x64")
287+
add_compile_definitions(ENSURE_MSYSTEM_IS_SET="MINGW64" MINGW_PREFIX="mingw64")
288+
elseif(CMAKE_GENERATOR_PLATFORM STREQUAL "arm64")
289+
add_compile_definitions(ENSURE_MSYSTEM_IS_SET="CLANGARM64" MINGW_PREFIX="clangarm64")
290+
elseif(CMAKE_GENERATOR_PLATFORM STREQUAL "x86")
291+
add_compile_definitions(ENSURE_MSYSTEM_IS_SET="MINGW32" MINGW_PREFIX="mingw32")
292+
endif()
286293
list(APPEND compat_SOURCES
287294
compat/mingw.c
288295
compat/winansi.c

git-compat-util.h

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -615,17 +615,23 @@ static inline bool strip_suffix(const char *str, const char *suffix,
615615
* the stack overflow can occur.
616616
*/
617617
#define DEFAULT_MAX_ALLOWED_TREE_DEPTH 512
618-
#elif defined(GIT_WINDOWS_NATIVE) && defined(__clang__) && defined(__aarch64__)
618+
#elif defined(GIT_WINDOWS_NATIVE) && defined(__clang__)
619619
/*
620-
* Similar to Visual C, it seems that on Windows/ARM64 the clang-based
621-
* builds have a smaller stack space available. When running out of
622-
* that stack space, a `STATUS_STACK_OVERFLOW` is produced. When the
623-
* Git command was run from an MSYS2 Bash, this unfortunately results
624-
* in an exit code 127. Let's prevent that by lowering the maximal
625-
* tree depth; This value seems to be low enough.
620+
* Similar to Visual C, it seems that clang-based builds on Windows
621+
* have a smaller stack space available. When running out of that
622+
* stack space, a `STATUS_STACK_OVERFLOW` is produced. When the Git
623+
* command was run from an MSYS2 Bash, this unfortunately results in
624+
* an exit code 127. Let's prevent that by lowering the maximal tree
625+
* depth; Unfortunately, it seems that the exact limit differs for
626+
* aarch64 vs x86_64, and the difference is too large to simply use a
627+
* single limit.
626628
*/
629+
#if defined(__aarch64__)
627630
#define DEFAULT_MAX_ALLOWED_TREE_DEPTH 1280
628631
#else
632+
#define DEFAULT_MAX_ALLOWED_TREE_DEPTH 1152
633+
#endif
634+
#else
629635
#define DEFAULT_MAX_ALLOWED_TREE_DEPTH 2048
630636
#endif
631637

meson.build

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1274,7 +1274,6 @@ elif host_machine.system() == 'windows'
12741274

12751275
libgit_c_args += [
12761276
'-DDETECT_MSYS_TTY',
1277-
'-DENSURE_MSYSTEM_IS_SET',
12781277
'-DNATIVE_CRLF',
12791278
'-DNOGDI',
12801279
'-DNO_POSIX_GOODIES',
@@ -1284,6 +1283,18 @@ elif host_machine.system() == 'windows'
12841283
'-D__USE_MINGW_ANSI_STDIO=0',
12851284
]
12861285

1286+
msystem = get_option('msystem')
1287+
if msystem != ''
1288+
mingw_prefix = get_option('mingw_prefix')
1289+
if mingw_prefix == ''
1290+
mingw_prefix = '/' + msystem.to_lower()
1291+
endif
1292+
libgit_c_args += [
1293+
'-DENSURE_MSYSTEM_IS_SET="' + msystem + '"',
1294+
'-DMINGW_PREFIX="' + mingw_prefix + '"'
1295+
]
1296+
endif
1297+
12871298
libgit_dependencies += compiler.find_library('ntdll')
12881299
libgit_include_directories += 'compat/win32'
12891300
if compiler.get_id() == 'msvc'

meson_options.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ option('runtime_prefix', type: 'boolean', value: false,
2121
description: 'Resolve ancillary tooling and support files relative to the location of the runtime binary instead of hard-coding them into the binary.')
2222
option('sane_tool_path', type: 'array', value: [],
2323
description: 'An array of paths to pick up tools from in case the normal tools are broken or lacking.')
24+
option('msystem', type: 'string', value: '',
25+
description: 'Fall-back on Windows when MSYSTEM is not set.')
26+
option('mingw_prefix', type: 'string', value: '',
27+
description: 'Fall-back on Windows when MINGW_PREFIX is not set.')
2428

2529
# Build information compiled into Git and other parts like documentation.
2630
option('build_date', type: 'string', value: '',

0 commit comments

Comments
 (0)