Skip to content

Commit

Permalink
git: add ARM64 runtime detection
Browse files Browse the repository at this point in the history
In order to support native Git for Windows ARM64 binaries,
this commit introduces ARM64 runtime detection. Git-wrapper itself will
remain an i686 or x86_64 executable for now, but since Windows on ARM
has built-in i686 emulation, it can run the file.

If an ARM64 system is detected, we set MSYSTEM=ARM64. Next to that,
because many binaries like curl aren't available natively for ARM64 yet,
we add /mingw32/bin to the path, so that we'll fallback to i686
executables in that case.

Signed-off-by: Tommy Vercetti <7903172+tommyvct@users.noreply.github.com>
Signed-off-by: Dennis Ameling <dennis@dennisameling.com>
  • Loading branch information
tommyvct authored and dennisameling committed Jan 22, 2021
1 parent 7e70f25 commit ed2aad9
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 6 deletions.
2 changes: 1 addition & 1 deletion mingw-w64-git/PKGBUILD
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ sha256sums=('SKIP'
'62f455747f33953a723ff7b070d43f0ed03c1d8d0749d7bb06288e14d356b637'
'f16b345aba17acd124ab5940635dfa2d87445df73eedbeb80e0285f29c85415a'
'80b0b11efe5a2f9b4cd92f28c260d0b3aad8b809c34ed95237c59b73e08ade0b'
'6696add21808e35ac171567e0286867ca9da8722c853af1295268869db84a602'
'fc99081d915161e9b7a4353bf7f0439782e000d966557852d256e3f9c67e6444'
'ee0ed30b2601413a6efcd15f236747404cd2d576dcfad77fb5b1700852cde857'
'c975292adae1f2666f07f8ee9b7d50576da249d9151c6bd211602adc8d37b6ab'
'a7e80489af33468e67a39d4c9c2fbf396e1f1e9533bb447f26432951ccf5e77c'
Expand Down
45 changes: 40 additions & 5 deletions mingw-w64-git/git-wrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <shellapi.h>
#include <stdio.h>
#include <wchar.h>
#include <stdbool.h>

/* Let the system deal with it if the path is too long */
#undef MAX_PATH
Expand Down Expand Up @@ -113,15 +114,35 @@ static void my_path_append(LPWSTR list, LPCWSTR path, size_t alloc)
}
}

bool IsRunningOnARM64()
{
USHORT process_machine = 0;
USHORT native_machine = 0;

// Note: IsWow64Process2 is only available in Windows 10 1511+
BOOL (WINAPI* IsWow64Process2)(HANDLE, PUSHORT, PUSHORT) =
GetProcAddress(GetModuleHandle(L"kernel32"), "IsWow64Process2");

return IsWow64Process2 &&
IsWow64Process2(GetCurrentProcess(), &process_machine, &native_machine) &&
native_machine == 0xaa64;
}

static void setup_environment(LPWSTR top_level_path, int full_path)
{
WCHAR msystem[64];
LPWSTR path2 = NULL;
int len;

/* Set MSYSTEM */
swprintf(msystem, sizeof(msystem),
L"MINGW%d", (int) sizeof(void *) * 8);
if (IsRunningOnARM64()) {
swprintf(msystem, sizeof(msystem),
L"ARM64");
} else {
swprintf(msystem, sizeof(msystem),
L"MINGW%d", (int)sizeof(void*) * 8);
}

SetEnvironmentVariable(L"MSYSTEM", msystem);

/* if not set, set PLINK_PROTOCOL to ssh */
Expand Down Expand Up @@ -164,13 +185,22 @@ static void setup_environment(LPWSTR top_level_path, int full_path)

/* extend the PATH */
len = GetEnvironmentVariable(L"PATH", NULL, 0);
len = sizeof(WCHAR) * (len + 3 * MAX_PATH);
len = sizeof(WCHAR) * (len + 4 * MAX_PATH);
path2 = (LPWSTR)malloc(len);
wcscpy(path2, top_level_path);
if (!full_path)
my_path_append(path2, L"cmd;", len);
else {
my_path_append(path2, msystem_bin, len);
if (IsRunningOnARM64()) {
/*
* Many modules aren't available natively for ARM64 yet, but we can leverage i686 emulation.
* Therefore we add /minw32/bin to the path.
*/
wcscat(path2, L";");
wcscat(path2, top_level_path);
my_path_append(path2, L"mingw32\\bin;", len);
}
if (_waccess(path2, 0) != -1) {
/* We are in an MSys2-based setup */
int len2 = GetEnvironmentVariable(L"HOME", NULL, 0);
Expand Down Expand Up @@ -658,8 +688,13 @@ int main(void)
LPWSTR working_directory = NULL;

/* Determine MSys2-based Git path. */
swprintf(msystem_bin, sizeof(msystem_bin),
L"mingw%d\\bin", (int) sizeof(void *) * 8);
if (IsRunningOnARM64()) {
swprintf(msystem_bin, sizeof(msystem_bin),
L"arm64\\bin");
} else {
swprintf(msystem_bin, sizeof(msystem_bin),
L"mingw%d\\bin", (int) sizeof(void *) * 8);
}
*top_level_path = L'\0';

/* get the installation location */
Expand Down

0 comments on commit ed2aad9

Please sign in to comment.