feat: support building for Windows on ARM (aarch64) via MSYS2 CLANGARM64 - #1811
Open
sci42 wants to merge 6 commits into
Open
feat: support building for Windows on ARM (aarch64) via MSYS2 CLANGARM64#1811sci42 wants to merge 6 commits into
sci42 wants to merge 6 commits into
Conversation
Take the architecture dependent parts of the Windows build from the MSYS2 environment instead of hardcoding x86_64/mingw64, so the same recipes serve MINGW64 and CLANGARM64: - package prefix from $MINGW_PACKAGE_PREFIX - install prefix from $MSYSTEM_PREFIX, replacing the hardcoded C:/msys64/mingw64 - Inno-Setup ArchitecturesAllowed from host_machine.cpu_family() - openssl DLLs by glob, since the file name carries the architecture (libcrypto-3-x64.dll vs libcrypto-3-arm64.dll) - the ldd filter in inno_build.py from the environment name, so it matches /clangarm64/ as well as /mingw64/ The existing MINGW64 workarounds are unchanged and now sit behind an explicit MSYSTEM check, so the x86_64 path keeps its previous behaviour. CLANGARM64 needs the same gtk/libadwaita/gettext pinning as MINGW64, for the same reasons: without it GSK cannot realize GL or Vulkan on a GdkWin32Toplevel and silently falls back to software rendering, and those older gtk/libadwaita builds import DllMain from libintl-8.dll. It does not need the libpthread.dll.a rename, linking with lld works as is. Also adds `just setup-win-dev`, a devel build that installs into $MSYSTEM_PREFIX instead of /usr, so the app can be run locally without building the installer.
`ldd` resolves imports by actually loading the binary. ANGLE's libGLESv2.dll blocks while being loaded, so `meson compile build-installer` hangs there indefinitely - no error, no CPU usage, which reads as a slow build rather than a deadlock. Read the PE import table with `objdump -p` and walk it transitively instead, which executes nothing. DLLs that are not present in the build environment are Windows system DLLs and stay unpackaged, matching the previous filter. The collected set is verified to be closed: nothing reachable from the binaries or the gdk-pixbuf loaders is missing. Whether the old code hangs on x86_64 depends only on how that ANGLE build behaves at load time, so this is not specific to aarch64.
Windows on ARM ships no native desktop OpenGL driver, so WGL is serviced by
Microsoft's OpenGLOn12.dll, which translates OpenGL onto Direct3D 12. GTK picks
that path by default and reports "Renderer: D3D12 (Qualcomm(R) Adreno(TM) X1-85
GPU)".
That layer crashes: after a few minutes of ordinary drawing and changing
settings the process dies with an access violation and the event log points at
OpenGLOn12.dll (0xc0000005).
Default GDK_DISABLE to "wgl" on aarch64, which makes GDK pick EGL and with it
the ANGLE already shipped alongside the app, mapping GL ES onto Direct3D 11:
- Vendor: Google Inc. (Qualcomm)
- Version: 1.5 (ANGLE 2.1.25748)
Using renderer 'GskGLRenderer'
GPU rendering is fully preserved and the crashes are gone, verified over ten
minutes of normal use where the WGL path died after about two.
Set only as a default so GDK_DISABLE from the environment still wins, and scoped
to aarch64 because x86_64 has real OpenGL drivers where ANGLE would be a detour
rather than a fix.
pangocairo renders glyphs through cairo's win32 font backend, which goes to DirectWrite and Direct2D. On Windows on ARM that path is broken: pango logs "All font fallbacks failed" once per layout (219 times during a single startup) and rendering text dies with an access violation in d2d1.dll (0xc0000005). It reliably takes the app down when a document containing a text stroke is opened, or when the typewriter is used. Opening misc/file-tests/v0-15-0-test.rnote crashed 3 of 3 runs. This is not a missing font: fontconfig sees 724 fonts in the same environment and fc-match resolves correctly, and patching a document's font_family from "serif" to "Noto Serif" changes nothing. Only the DirectWrite path fails. Default PANGOCAIRO_BACKEND to "fc", which selects the fontconfig/freetype backend the Linux builds use anyway. The same document then opens cleanly in 5 of 5 runs with no font warnings, and text still renders correctly - verified by exporting to PNG and comparing. Note that std::env::set_var does not work for this, unlike for the GDK_DISABLE default above. On Windows it only calls SetEnvironmentVariableW, which updates the Win32 environment block; GDK reads its variables with g_getenv and sees that, but pangocairo uses plain getenv, which returns the copy the C runtime builds at startup. _putenv_s updates that copy, and libpangocairo resolves to the same UCRT as the app. Set only as a default so PANGOCAIRO_BACKEND from the environment still wins, and scoped to aarch64 because x86_64 was not tested.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Makes the Windows build work in the MSYS2 CLANGARM64 environment, so Rnote runs
natively on Windows on ARM devices, with GPU rendering.
Approach
Rather than adding aarch64 branches, the Windows recipes now take the
architecture-dependent parts from the MSYS2 environment itself:
$MINGW_PACKAGE_PREFIX$MSYSTEM_PREFIX(viacygpath -m), replacing thehardcoded
C:/msys64/mingw64ArchitecturesAllowedfromhost_machine.cpu_family()(
libcrypto-3-x64.dllvslibcrypto-3-arm64.dll)Separately,
inno_build.pyno longer useslddto find the DLLs to package.lddresolves imports by loading the binary, and ANGLE'slibGLESv2.dllblockswhile loading, which made the installer build hang indefinitely. It now reads the
PE import table with
objdump -pand walks it transitively; the resulting set isverified to be closed. That commit is independent of ARM and can be taken on its
own.
The existing MINGW64 workarounds are unchanged and now sit behind an explicit
MSYSTEM == MINGW64check, so the x86_64 path keeps its exact previous behaviour.CLANGARM64 needs the gtk/libadwaita/gettext pinning for the same reasons MINGW64
does, but not the
libpthread.dll.arename — linking withlldworks as is.New
just setup-win-dev— devel build installing into$MSYSTEM_PREFIXinstead of/usr, so the app can be run locally without building the installer.misc/building/rnote-windows-arm64-build.mdTested
On a Surface Pro 11 (Snapdragon X Elite
X1E80100, Adreno X1-85, Windows 11):rnote-cli test misc/file-tests/*.rnotepasses for all six fixturesGSK_DEBUG=rendererreportsUsing renderer 'GskGLRenderer'on ANGLE, drawingis smooth and the rendering artifacts seen under the cairo fallback are gone
of ordinary use (drawing, settings, zooming) — the same usage crashed the app
after roughly two minutes before the
GDK_DISABLE=wglchangePANGOCAIRO_BACKEND=fcchange, 5 of 5 clean after, with the crash reproducingidentically on the meson-installed build and on the installed app from the
installer. Forcing
PANGOCAIRO_BACKEND=win32back on brings the crash back,which also confirms the environment still overrides the default
Not tested by me:
a CI run or a second pair of eyes.
hardware available, which is why both env defaults are scoped to aarch64
rather than to Windows in general. If it turns out to be broken there too,
widening the scope is a one-line change.
PANGOCAIRO_BACKENDdefault lives inrnote-ui, sornote-clidoes not get it. CLI export worked with either backend in mytests, but I did not investigate why it is unaffected.