From eea27f530dd37d6212e9bc587cd0f19e3b37a8b7 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Fri, 21 Nov 2025 14:17:24 +0100 Subject: [PATCH] mingw: rely on MSYS2's metadata instead of hard-coding it MSYS2 defines some helpful environment variables, e.g. `MSYSTEM`. There is code in Git for Windows to ensure that that `MSYSTEM` variable is set, hard-coding a default. However, the existing solution jumps through hoops to reconstruct the proper default, and is even incomplete doing so, as we found out when we extended it to support CLANGARM64. This is absolutely unnecessary because there is already a perfectly valid `MSYSTEM` value we can use at build time. This is even true when building the MINGW32 variant on a MINGW64 system because `makepkg-mingw` will override the `MSYSTEM` value as per the `MINGW_ARCH` array. The same is equally true for the `/mingw64`, `/mingw32` and `/clangarm64` prefix: those values are already available via the `MINGW_PREFIX` environment variable, and we just need to pass that setting through. Only when `MINGW_PREFIX` is not set (as is the case in Git for Windows' minimal SDK, where only `MSYSTEM` is guaranteed to be set correctly), we use as fall-back the top-level directory whose name is the down-cased value of the `MSYSTEM` variable. Incidentally, this also broadens the support to all the configurations supported by the MSYS2 project, i.e. clang64 & ucrt64, too. Note: This keeps the same, hard-coded MSYSTEM platform support for CMake as before, but drops it for Meson (because it is unclear how Meson could do this in a more flexible manner). Signed-off-by: Johannes Schindelin --- compat/mingw.c | 29 +++++++---------------------- config.mak.uname | 22 ++++++++++++---------- contrib/buildsystems/CMakeLists.txt | 9 ++++++++- meson.build | 13 ++++++++++++- meson_options.txt | 4 ++++ 5 files changed, 43 insertions(+), 34 deletions(-) diff --git a/compat/mingw.c b/compat/mingw.c index 6accd26f2a..9891950d4e 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -3625,7 +3625,7 @@ int xwcstoutf(char *utf, const wchar_t *wcs, size_t utflen) } #ifdef ENSURE_MSYSTEM_IS_SET -#if !defined(RUNTIME_PREFIX) || !defined(HAVE_WPGMPTR) +#if !defined(RUNTIME_PREFIX) || !defined(HAVE_WPGMPTR) || !defined(MINGW_PREFIX) static size_t append_system_bin_dirs(char *path UNUSED, size_t size UNUSED) { return 0; @@ -3643,25 +3643,16 @@ static size_t append_system_bin_dirs(char *path, size_t size) /* strip trailing `git.exe` */ len = slash - prefix; - /* strip trailing `cmd` or `mingw64\bin` or `mingw32\bin` or `bin` or `libexec\git-core` */ - if (strip_suffix_mem(prefix, &len, "\\mingw64\\libexec\\git-core") || - strip_suffix_mem(prefix, &len, "\\mingw64\\bin")) + /* strip trailing `cmd` or `\bin` or `bin` or `libexec\git-core` */ + if (strip_suffix_mem(prefix, &len, "\\" MINGW_PREFIX "\\libexec\\git-core") || + strip_suffix_mem(prefix, &len, "\\" MINGW_PREFIX "\\bin")) off += xsnprintf(path + off, size - off, - "%.*s\\mingw64\\bin;", (int)len, prefix); - else if (strip_suffix_mem(prefix, &len, "\\clangarm64\\libexec\\git-core") || - strip_suffix_mem(prefix, &len, "\\clangarm64\\bin")) - off += xsnprintf(path + off, size - off, - "%.*s\\clangarm64\\bin;", (int)len, prefix); - else if (strip_suffix_mem(prefix, &len, "\\mingw32\\libexec\\git-core") || - strip_suffix_mem(prefix, &len, "\\mingw32\\bin")) - off += xsnprintf(path + off, size - off, - "%.*s\\mingw32\\bin;", (int)len, prefix); + "%.*s\\" MINGW_PREFIX "\\bin;", (int)len, prefix); else if (strip_suffix_mem(prefix, &len, "\\cmd") || strip_suffix_mem(prefix, &len, "\\bin") || strip_suffix_mem(prefix, &len, "\\libexec\\git-core")) off += xsnprintf(path + off, size - off, - "%.*s\\mingw%d\\bin;", (int)len, prefix, - (int)(sizeof(void *) * 8)); + "%.*s\\" MINGW_PREFIX "\\bin;", (int)len, prefix); else return 0; @@ -3757,13 +3748,7 @@ static void setup_windows_environment(void) char buf[32768]; size_t off = 0; -#if defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC) - setenv("MSYSTEM", "CLANGARM64", 1); -#elif defined(__MINGW64__) || defined(_M_AMD64) - setenv("MSYSTEM", "MINGW64", 1); -#else - setenv("MSYSTEM", "MINGW32", 1); -#endif + setenv("MSYSTEM", ENSURE_MSYSTEM_IS_SET, 1); if (home) off += xsnprintf(buf + off, sizeof(buf) - off, diff --git a/config.mak.uname b/config.mak.uname index 289ded45c7..1c8a32b2b1 100644 --- a/config.mak.uname +++ b/config.mak.uname @@ -452,14 +452,8 @@ 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 - ifeq (CLANGARM64,$(MSYSTEM)) - prefix = /clangarm64 - else - prefix = /mingw64 - endif + ifneq (,$(MSYSTEM)) + prefix = $(MINGW_PREFIX) endif # Prepend MSVC 64-bit tool-chain to PATH. # @@ -529,7 +523,9 @@ endif compat/win32/pthread.o compat/win32/syslog.o \ compat/win32/trace2_win32_process_info.o \ compat/win32/dirent.o compat/win32/fscache.o compat/win32/wsl.o - 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\" + COMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DDETECT_MSYS_TTY \ + -DENSURE_MSYSTEM_IS_SET="\"$(MSYSTEM)\"" -DMINGW_PREFIX="\"$(patsubst /%,%,$(MINGW_PREFIX))\"" \ + -DNOGDI -DHAVE_STRING_H -Icompat -Icompat/regex -Icompat/win32 -DSTRIP_EXTENSION=\".exe\" BASIC_LDFLAGS = -IGNORE:4217 -IGNORE:4049 -NOLOGO # invalidcontinue.obj allows Git's source code to close the same file # handle twice, or to access the osfhandle of an already-closed stdout @@ -748,10 +744,16 @@ ifeq ($(uname_S),MINGW) BASIC_LDFLAGS += -Wl,--dynamicbase endif ifneq (,$(MSYSTEM)) + ifeq ($(MINGW_PREFIX),$(filter-out /%,$(MINGW_PREFIX))) + # Override if empty or does not start with a slash + MINGW_PREFIX := /$(shell echo '$(MSYSTEM)' | tr A-Z a-z) + endif prefix = $(MINGW_PREFIX) HOST_CPU = $(patsubst %-w64-mingw32,%,$(MINGW_CHOST)) BASIC_LDFLAGS += -Wl,--pic-executable - COMPAT_CFLAGS += -DDETECT_MSYS_TTY -DENSURE_MSYSTEM_IS_SET + COMPAT_CFLAGS += -DDETECT_MSYS_TTY \ + -DENSURE_MSYSTEM_IS_SET="\"$(MSYSTEM)\"" \ + -DMINGW_PREFIX="\"$(patsubst /%,%,$(MINGW_PREFIX))\"" ifeq (MINGW32,$(MSYSTEM)) BASIC_LDFLAGS += -Wl,--large-address-aware endif diff --git a/contrib/buildsystems/CMakeLists.txt b/contrib/buildsystems/CMakeLists.txt index 6443dfbac5..c69f3a7ea9 100644 --- a/contrib/buildsystems/CMakeLists.txt +++ b/contrib/buildsystems/CMakeLists.txt @@ -282,7 +282,14 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Windows") _CONSOLE DETECT_MSYS_TTY STRIP_EXTENSION=".exe" NO_SYMLINK_HEAD UNRELIABLE_FSTAT NOGDI OBJECT_CREATION_MODE=1 __USE_MINGW_ANSI_STDIO=0 USE_NED_ALLOCATOR OVERRIDE_STRDUP MMAP_PREVENTS_DELETE USE_WIN32_MMAP - HAVE_WPGMPTR ENSURE_MSYSTEM_IS_SET HAVE_RTLGENRANDOM) + HAVE_WPGMPTR HAVE_RTLGENRANDOM) + if(CMAKE_GENERATOR_PLATFORM STREQUAL "x64") + add_compile_definitions(ENSURE_MSYSTEM_IS_SET="MINGW64" MINGW_PREFIX="mingw64") + elseif(CMAKE_GENERATOR_PLATFORM STREQUAL "arm64") + add_compile_definitions(ENSURE_MSYSTEM_IS_SET="CLANGARM64" MINGW_PREFIX="clangarm64") + elseif(CMAKE_GENERATOR_PLATFORM STREQUAL "x86") + add_compile_definitions(ENSURE_MSYSTEM_IS_SET="MINGW32" MINGW_PREFIX="mingw32") + endif() list(APPEND compat_SOURCES compat/mingw.c compat/winansi.c diff --git a/meson.build b/meson.build index 46b1369c45..03fa16012d 100644 --- a/meson.build +++ b/meson.build @@ -1271,7 +1271,6 @@ elif host_machine.system() == 'windows' libgit_c_args += [ '-DDETECT_MSYS_TTY', - '-DENSURE_MSYSTEM_IS_SET', '-DNATIVE_CRLF', '-DNOGDI', '-DNO_POSIX_GOODIES', @@ -1281,6 +1280,18 @@ elif host_machine.system() == 'windows' '-D__USE_MINGW_ANSI_STDIO=0', ] + msystem = get_option('msystem') + if msystem != '' + mingw_prefix = get_option('mingw_prefix') + if mingw_prefix == '' + mingw_prefix = '/' + msystem.to_lower() + endif + libgit_c_args += [ + '-DENSURE_MSYSTEM_IS_SET="' + msystem + '"', + '-DMINGW_PREFIX="' + mingw_prefix + '"' + ] + endif + libgit_dependencies += compiler.find_library('ntdll') libgit_include_directories += 'compat/win32' if compiler.get_id() == 'msvc' diff --git a/meson_options.txt b/meson_options.txt index e0be260ae1..c2d9f0bfc0 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -21,6 +21,10 @@ option('runtime_prefix', type: 'boolean', value: false, description: 'Resolve ancillary tooling and support files relative to the location of the runtime binary instead of hard-coding them into the binary.') option('sane_tool_path', type: 'array', value: [], description: 'An array of paths to pick up tools from in case the normal tools are broken or lacking.') +option('msystem', type: 'string', value: '', + description: 'Fall-back on Windows when MSYSTEM is not set.') +option('mingw_prefix', type: 'string', value: '', + description: 'Fall-back on Windows when MINGW_PREFIX is not set.') # Build information compiled into Git and other parts like documentation. option('build_date', type: 'string', value: '',