Support for ARM64 Windows
Summary
I was wondering whether it would be possible to build an ARM64 Windows GHC. One thing I'm not immediately understanding is how do we bootstrap such a compiler? Do I need to build a cross compiler targeting arm64 windows to then build a native arm64 windows compiler?
This came up as I was trying to debug a windows issue with virtualization on my aarch64 M2 machine, and was using an aarch64 virtualized windows for performance... Emulating a x64 windows on arm is much more expensive unfortunately.
- Show closed items
Activity
-
Newest first Oldest first
-
Show all activity Show comments only Show history only
- Rodrigo Mesquita added needs triage label
added needs triage label
- Rodrigo Mesquita changed the description
Compare with previous version changed the description
- Maintainer
AArch64/Windows is currently not supported. It's not impossible to support, but it also is both non-trivial and not a high priority. The steps involved are essentially:
- Teach
ghc-toolchain
,configure
, and the compiler about the existence of the platform - Add STG register assignments to
MachRegs
- Optional: Upstream the STG register assignment to LLVM
- Teach the AArch64 NCG about the calling convention
- Add PE/AArch64 support to the RTS linker
Sady I don't see progress being made here unless someone steps up to take ownership of the platform.
Edited by Ben Gamari - Teach
- Ben Gamari removed needs triage label
removed needs triage label
- Ben Gamari added Tfeature request label and removed Tbug label
added Tfeature request label and removed Tbug label
- Maintainer
It seems Windows is starting to push Arm64 a bit harder. For example they are offering Arm-based surface notebooks now: https://www.theverge.com/2024/5/20/24160498/microsoft-arm-surface-laptop-6-qualcomm-snapdragon-x-elite
So we might want to prioritize this somewhat higher as those become more common.
1 - Rodrigo Mesquita changed milestone to %9.14.1
changed milestone to %9.14.1
- Developer
https://github.com/mstorsjo/llvm-mingw provides
aarch64-w64-mingw32-
prefixed llvm toolchain that can compile to aarch64 windows native binaries on linux. So a good first step would be trying to get a Haskell hello world working via unreg backend, then trying to bootstrap a non-threaded unreg GHC native build. The native build can useclangarm64
packages provided bymsys2
and later developments can happen on windows natively. 1 Collapse replies - Author Owner
Do you think this could reasonably be done by a beginner? Maybe it'd make for an interesting task at ZuriHac
- Developer
Only for the work that leads to a hello world but not anything beyond that. Also if you want to get people at zurihac working for this, do make sure they have a arm laptop with windows vm, because wine support for arm64 is still in its infancy.
Edited by Cheng Shao - Author Owner
OK, maybe I won't
- Developer
It seems arm on windows is documented here: https://learn.microsoft.com/en-us/windows/arm/overview
- Developer
Update: after applying this patch, I've managed to cross-compile the ghc api hello world to aarch64 executable and actually run it on aarch64 windows:
For anyone motivated enough to give it a try:
LLVM_MINGW_PATH=/workspace/llvm-mingw-20240518-ucrt-ubuntu-20.04-x86_64 export AR=$LLVM_MINGW_PATH/bin/aarch64-w64-mingw32-llvm-ar export CC=$LLVM_MINGW_PATH/bin/aarch64-w64-mingw32-clang export CXX=$LLVM_MINGW_PATH/bin/aarch64-w64-mingw32-clang++ export NM=$LLVM_MINGW_PATH/bin/aarch64-w64-mingw32-nm export OBJCOPY=$LLVM_MINGW_PATH/bin/aarch64-w64-mingw32-objcopy export OBJDUMP=$LLVM_MINGW_PATH/bin/aarch64-w64-mingw32-objdump export RANLIB=$LLVM_MINGW_PATH/bin/aarch64-w64-mingw32-llvm-ranlib export SIZE=$LLVM_MINGW_PATH/bin/aarch64-w64-mingw32-size export STRINGS=$LLVM_MINGW_PATH/bin/aarch64-w64-mingw32-strings export STRIP=$LLVM_MINGW_PATH/bin/aarch64-w64-mingw32-strip export WindresCmd=$LLVM_MINGW_PATH/bin/aarch64-w64-mingw32-windres export CONFIGURE_ARGS="--host=x86_64-unknown-linux --target=aarch64-unknown-mingw32 --enable-unregisterised --with-intree-gmp" hadrian/build --bignum=native
3 Collapse replies - Developer
Just signalling of successful reproduction!
I faced with:
d.lld: error: undefined symbol: ___chkstk_ms
I was needed to remove the following line:
RTS_WIN64_ONLY(SymI_NeedsProto(___chkstk_ms)) \
at
rts/RtsSymbols.c
.It compiled for
ARM64
:serge@DESKTOP-VSP1KUB CLANGARM64 /c/Users/serge/Workspace $ file ./T22455.exe ./T22455.exe: PE32+ executable for MS Windows 6.00 (console), ARM64, 15 sections
Also I was needed to disable windows security to let it run because it had been treated falsy positive as a backdoor ))
Edited by Serge S. Gulin - Developer
My diff:
diff --git a/libraries/base/src/System/CPUTime/Windows.hsc b/libraries/base/src/System/CPUTime/Windows.hsc index 547e7fa480..4bae075d46 100644 --- a/libraries/base/src/System/CPUTime/Windows.hsc +++ b/libraries/base/src/System/CPUTime/Windows.hsc @@ -60,7 +60,7 @@ type HANDLE = () #if defined(i386_HOST_ARCH) foreign import stdcall unsafe "GetCurrentProcess" getCurrentProcess :: IO (Ptr HANDLE) foreign import stdcall unsafe "GetProcessTimes" getProcessTimes :: Ptr HANDLE -> Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> IO CInt -#elif defined(x86_64_HOST_ARCH) +#elif defined(x86_64_HOST_ARCH) || defined(aarch64_HOST_ARCH) foreign import ccall unsafe "GetCurrentProcess" getCurrentProcess :: IO (Ptr HANDLE) foreign import ccall unsafe "GetProcessTimes" getProcessTimes :: Ptr HANDLE -> Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> IO CInt #else diff --git a/rts/RtsSymbols.c b/rts/RtsSymbols.c index d4ce9acb94..56e8c58faa 100644 --- a/rts/RtsSymbols.c +++ b/rts/RtsSymbols.c @@ -84,7 +84,7 @@ extern char **environ; #if defined(mingw32_HOST_OS) #define RTS_POSIX_ONLY_SYMBOLS /**/ -#if defined(x86_64_HOST_ARCH) +#if defined(x86_64_HOST_ARCH) || defined(aarch64_HOST_ARCH) #define RTS_WIN64_ONLY(X) X #else #define RTS_WIN64_ONLY(X) /**/ @@ -164,7 +164,6 @@ extern char **environ; SymI_HasProto(rts_IOManagerIsWin32Native) \ SymI_HasProto(rts_ConsoleHandlerDone) \ SymI_NeedsProto(__mingw_module_is_dll) \ - RTS_WIN64_ONLY(SymI_NeedsProto(___chkstk_ms)) \ SymI_HasProto(__stdio_common_vswprintf_s) \ SymI_HasProto(__stdio_common_vswprintf) \ SymI_HasProto(_errno) \ @@ -1020,7 +1019,7 @@ extern char **environ; #define SymI_NeedsDataProto(vvv) extern StgWord vvv[]; #if defined(COMPILING_WINDOWS_DLL) #define SymE_HasProto(vvv) SymE_HasProto(vvv); -# if defined(x86_64_HOST_ARCH) +# if defined(x86_64_HOST_ARCH) || defined(aarch64_HOST_ARCH) # define SymE_NeedsProto(vvv) extern void __imp_ ## vvv (void); # define SymE_NeedsDataProto(vvv) SymE_NeedsProto(vvv) # else
My commands:
$ ./configure --target=aarch64-unknown-mingw32 CC=$LLVM_MINGW_PATH/bin/aarch64-w64-mingw32-clang AR=$LLVM_MINGW_PATH/bin/aarch64-w64-mingw32-llvm-ar CXX=$LLVM_MINGW_PATH/bin/aarch64-w64-mingw32-clang++ NM=$LLVM_MINGW_PATH/bin/aarch64-w64-mingw32-nm OBJCOPY=$LLVM_MINGW_PATH/bin/aarch64-w64-mingw32-objcopy OBJDUMP=$LLVM_MINGW_PATH/bin/aarch64-w64-mingw32-objdump RANLIB=$LLVM_MINGW_PATH/bin/aarch64-w64-mingw32-llvm-ranlib SIZE=$LLVM_MINGW_PATH/bin/aarch64-w64-mingw32-size STRINGS=$LLVM_MINGW_PATH/bin/aarch64-w64-mingw32-strings STRIP=$LLVM_MINGW_PATH/bin/aarch64-w64-mingw32-strip WindresCmd=$LLVM_MINGW_PATH/bin/aarch64-w64-mingw32-windres LLVMAS=$LLVM_MINGW_PATH/bin/aarch64-w64-mingw32-clang --enable-unregisterised --with-intree-gmp $ hadrian/build --bignum=native --flavour=default+no_profiled_libs --docs=none -j
I used the
tag: ghc-9.12.1-release
from ghc repo. - Developer
Windows 11 ARM GHC build.
@TerrorJack Merry Christmas!
- Download 7z compiled by https://github.com/mstorsjo/llvm-mingw/releases/download/20241217/llvm-mingw-20241217-ucrt-macos-universal.tar.xz
- Add
mingw
folder with content from here. - Change your
settings
to setup windres and c compiler paths. - Use
stage0/bin
*.exe
files. NOTstage1
. By some reason it containsMacOS
but libraries should be OK.
Edited by Serge S. Gulin
- Developer
cc @angerman who might be interested in porting the AArch64 NCG to Windows :-)
- Cheng Shao mentioned in issue #24883 (closed)
mentioned in issue #24883 (closed)
- Cheng Shao mentioned in commit 812c9cea
mentioned in commit 812c9cea
- Cheng Shao mentioned in commit b056e326
mentioned in commit b056e326
- Developer
Next steps I have in mind:
-
Land !12767 (closed) - Land required changes in submodules
- Set up a special aarch64 deb12 image with
llvm-mingw
toolchain andwine
; I've verifiedwine
shipped by deb12 works for the example above. It's also possible to run it in x86_64 using qemu user mode but we might as well avoid an extra layer of emulation. - Set up a CI job (could be nightly only) to verify the minimum example works, similar to how the existing x86_64->aarch64 cross job is tested.
The above steps would give us a nice solid foundation to iterate on more complex stuff.
Edited by Cheng Shao -
Collapse replies - Developer
Land required changes in submodules
-
Cosmetic one https://github.com/haskell/terminfo/pull/58 -
https://github.com/haskell/cabal/pull/10705 -
https://github.com/haskell/win32/pull/238 -
https://github.com/haskell/directory/pull/196 -
https://github.com/haskell/haskeline/pull/193 -
https://github.com/haskell/hsc2hs/pull/98 -
https://github.com/haskell/process/pull/333 -
It is more about #25619 but noted only when Windows 11 ARM is used as a host platform https://github.com/haskell/unix/pull/334 with MSYS2 clangarm compilers and https://github.com/mstorsjo/llvm-mingw. May be it is related to usageLLVM
instead ofGCC
and could be reproduced at Windowsx86
as well.
The legend:
-
- received at least one response from maintainers, communication is in progress. -
- changes has been applied. - No mark - no information yet
Edited by Serge S. Gulin -
- Maintainer
Thanks for the ping, @Bodigrim. Yes, I'll have a look.
- Maintainer
I believe these should all now be merged. Thanks @gulin.serge !
1 - Developer
Added one more checks are greenThanks!
Edited by Serge S. Gulin - Developer
One more please!Thanks!
Edited by Serge S. Gulin
- Cheng Shao mentioned in merge request !12767 (closed)
mentioned in merge request !12767 (closed)
- Cheng Shao mentioned in merge request !12787 (closed)
mentioned in merge request !12787 (closed)
- Cheng Shao mentioned in commit ce8fb51e
mentioned in commit ce8fb51e