gnustep / libobjc2

Objective-C runtime library intended for use with Clang.
http://www.gnustep.org/
MIT License
426 stars 116 forks source link

Initial Windows on ARM (AArch64) Support #249

Closed hmelder closed 7 months ago

hmelder commented 7 months ago

This pull request provides initial support for Windows on ARM.

The code was tested on the following Systems:

  1. Windows 10 Version 22598 MP (5 procs) Free ARM 64-bit (AArch64) Edition build lab: 22598.1.arm64fre.ni_release.220408-1503
  2. Debian GNU/Linux trixie/sid aarch64 (Kernel: 6.5.0-3-arm64)

I have documented the use of the SEH directives at the beginning of the file.

Further reading material (sorted by relevance):

Thank you @mstorsjo for the detailed explaination of the .seh* directives and the link to the LLVM commit.

hmelder commented 7 months ago

I need to rebase the branch.

CMake reports the wrong CPU architecture as we run it as an Intel process:

-- Selecting Windows SDK version 10.0.22621.0 to target Windows 10.0.22598.
-- The C compiler identification is MSVC 19.33.31517.0
-- The CXX compiler identification is MSVC 19.33.31517.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files/Microsoft Visual Studio/2022/Preview/VC/Tools/MSVC/14.33.31517/bin/HostARM64/ARM64/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files/Microsoft Visual Studio/2022/Preview/VC/Tools/MSVC/14.33.31517/bin/HostARM64/ARM64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
CMAKE_SYSTEM_PROCESSOR: AMD64
-- Configuring done (3.4s)
-- Generating done (0.0s)
-- Build files have been written to: C:/Users/vm/test/build

The check https://github.com/gnustep/libobjc2/commit/226455bd10d8b4a0a090449b5b7ebf1e42daf0a5 fails

hmelder commented 7 months ago

Arch check is now fixed for https://github.com/gnustep/libobjc2/issues/247

anthony-linaro commented 7 months ago

Repost from correct account :)

How are tests run? An option is docker+qemu+wine on an ubuntu x64 machine, such as here in sse2neon: https://github.com/DLTcollab/sse2neon/pull/598

Might not work in all cases, but possibly worth a try

hmelder commented 7 months ago

Repost from correct account :)

How are tests run? An option is docker+qemu+wine on an ubuntu x64 machine, such as here in sse2neon: DLTcollab/sse2neon#598

Might not work in all cases, but possibly worth a try

That would be an interesting approach! Self-hosting is also an option but requires someone to pay for an arm64 VM :/

hmelder commented 7 months ago

We could try the CMAKE_HOST_SYSTEM_PROCESSOR variable as well but this will cause problems when cross compiling.

I found this in the CMAKE_SYSTEM_PROCESSOR documentation which is related to our problem:

In many cases, this will correspond to the target architecture for the build, but this is not guaranteed. (E.g. on Windows, the host may be AMD64 even when using a MSVC cl compiler with a 32-bit target.)

I will open an issue, but I have low expectations.

hmelder commented 7 months ago

It comes down to how CMake retrieves the architecture from the compiler.

anthony-linaro commented 7 months ago

Repost from correct account (again, sorry all)

You guys are running inside a vcvarsall window, right? In blender, where I did something similar, I just checked "$ENV{VSCMD_ARG_TGT_ARCH}"

hmelder commented 7 months ago

Repost from correct account (again, sorry all)

You guys are running inside a vcvarsall window, right?

Yes:

vm@localhost's password:
**********************************************************************
** Visual Studio 2022 Developer Command Prompt v17.3.0-pre.2.0
** Copyright (c) 2022 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'arm64'
mstorsjo commented 7 months ago

It comes down to how CMake retrieves the architecture from the compiler.

For CMAKE_HOST_SYSTEM_PROCESSOR, cmake pretty much explicitly doesn’t check the compiler, only the host environment. And CMAKE_SYSTEM_PROCESSOR is a plain copy of the former, if not cross compiling.

For detecting things from the actual compiler, there’s only CMAKE_C_COMPILER_ARCHITECTURE_ID, which only is available in some cases.

anthony-linaro commented 7 months ago

If it's always going to be in a vcvarsall window on Windows, I would suggest "$ENV{VSCMD_ARG_TGT_ARCH}" then - avoids CMake completely

hmelder commented 7 months ago

If it's always going to be in a vcvarsall window on Windows, I would suggest "$ENV{VSCMD_ARG_TGT_ARCH}" then - avoids CMake completely

So we need to error out, when we do not detect a vcvarsall enviroment, or fall back to some other value. Also not an ideal solution.

It is ridiculous how such an elementary thing is just completely broken in CMake.

triplef commented 7 months ago

So we need to error out, when we do not detect a vcvarsall enviroment

That seems ok to me since I think one always needs a Visual Studio environment on Windows, right?

anthony-linaro commented 7 months ago

Yes, I think that's a reasonable assumption - I haven't come across anything that doesn't use it (although I'm happy to be proved wrong) - even stuff that doesn't use CL

mstorsjo commented 7 months ago

So we need to error out, when we do not detect a vcvarsall enviroment

That seems ok to me since I think one always needs a Visual Studio environment on Windows, right?

If using mingw based tools (either GNU tools, or llvm tools with mingw headers), then one does not use a visual studio environment at all.

triplef commented 7 months ago

If using mingw based tools (either GNU tools, or llvm tools with mingw headers), then one does not use a visual studio environment at all.

Good point, but libobjc2 doesn’t currently support MinGW.

mstorsjo commented 7 months ago

If using mingw based tools (either GNU tools, or llvm tools with mingw headers), then one does not use a visual studio environment at all.

Good point, but libobjc2 doesn’t currently support MinGW.

Oh, ok, fair enough.

triplef commented 7 months ago

As we now have suitable hardware I could provide a Windows ARM self-hosted runner for the CI here (still need to set it up but maybe next week). Would you be able to give me sufficient GH project access to set this up @davidchisnall? Feel free to ping me directly.

davidchisnall commented 7 months ago

@triplef, I've made you admin. I think that's sufficient to add runners.