From 80eecdb49d9d7f32b2db7f68f14ae92b50dbcbb6 Mon Sep 17 00:00:00 2001 From: Enaium Date: Tue, 27 Oct 2026 13:13:29 +0800 Subject: [PATCH] feat(native): add Windows ARM64 support Add a windowsarm64 target to generateLibs using the LLVM-MinGW clang wrappers, with a shared createWindowsTarget() helper keeping the existing x86_64 path intact. LLVM-MinGW builds against libc++, which does not pull transitively, so patch imgui-node-editor's crude_json.cpp through the existing vendor patch flow. Bundle the LWJGL natives-windows-arm64 classifiers in imgui-app and document the direct Gradle build path. Co-authored-by: DeepSeek --- README.md | 11 +++++++- buildSrc/scripts/apply_vendor_patches.sh | 6 ++++ .../groovy/tool/generator/GenerateLibs.groovy | 28 ++++++++++++++++--- imgui-app/build.gradle | 2 +- .../imgui-node-editor-libcxx-exception.patch | 10 +++++++ 5 files changed, 51 insertions(+), 6 deletions(-) create mode 100644 patches/imgui-node-editor-libcxx-exception.patch diff --git a/README.md b/README.md index 360ad212..4c2c17eb 100644 --- a/README.md +++ b/README.md @@ -421,6 +421,15 @@ If you don't need FreeType or want a stock build under the project tree, call `g - Build: `./gradlew imgui-binding:generateLibs -Denvs=windows -Dlocal` - Run example: `./gradlew example:run -PlibPath="../imgui-binding/build/libsNative/windows64"` +### Windows ARM64 + +- Required on PATH: Ant, [LLVM-MinGW](https://github.com/mstorsjo/llvm-mingw) (the `aarch64-w64-mingw32-*` + wrappers). +- Build: `./gradlew imgui-binding:generateLibs -Denvs=windowsarm64 -Dlocal` +- Output: `imgui-binding/build/libsNative/windowsarm64/imgui-java64.dll` +- Run example: `./gradlew example:run -PlibPath="../imgui-binding/build/libsNative/windowsarm64"` +- The direct Gradle path builds without FreeType by default, matching the other platforms. + ### Linux - Install dependencies: `mingw-w64-gcc`, `ant`. (Package names vary by distro.) @@ -439,7 +448,7 @@ If you don't need FreeType or want a stock build under the project tree, call `g | Flag | Effect | |-------------------|-------------------------------------------------------------------------------------------------------------------------------| -| `-Denvs=` | Target platforms — any of `windows`, `linux`, `macos`, `macosarm64` | +| `-Denvs=` | Target platforms — any of `windows`, `windowsarm64`, `linux`, `linuxarm64`, `macos`, `macosarm64` | | `-Dlocal` | Output to `imgui-binding/build/libsNative/` instead of `/tmp/imgui/` | | `-Dfreetype=true` | Compile FreeType statically into the binary (requires `vendor_freetype.sh` to have been run; `build.sh` handles this for you) | diff --git a/buildSrc/scripts/apply_vendor_patches.sh b/buildSrc/scripts/apply_vendor_patches.sh index 7489a8fd..1b2bcf1c 100755 --- a/buildSrc/scripts/apply_vendor_patches.sh +++ b/buildSrc/scripts/apply_vendor_patches.sh @@ -30,3 +30,9 @@ apply_patch_idempotent() { apply_patch_idempotent \ "$(pwd)/patches/imgui-node-editor-imgui-1.92-operator-star.patch" \ include/imgui-node-editor + +# LLVM-MinGW's libc++ does not transitively include , so the +# Windows ARM64 build needs the explicit include for std::terminate(). +apply_patch_idempotent \ + "$(pwd)/patches/imgui-node-editor-libcxx-exception.patch" \ + include/imgui-node-editor diff --git a/buildSrc/src/main/groovy/tool/generator/GenerateLibs.groovy b/buildSrc/src/main/groovy/tool/generator/GenerateLibs.groovy index d7df6b0f..d57c7051 100644 --- a/buildSrc/src/main/groovy/tool/generator/GenerateLibs.groovy +++ b/buildSrc/src/main/groovy/tool/generator/GenerateLibs.groovy @@ -31,6 +31,7 @@ class GenerateLibs extends DefaultTask { private final String[] buildEnvs = System.getProperty('envs')?.split(',') private final boolean forWindows = buildEnvs?.contains('windows') + private final boolean forWindowsArm64 = buildEnvs?.contains('windowsarm64') private final boolean forLinux = buildEnvs?.contains('linux') private final boolean forLinuxArm64 = buildEnvs?.contains('linuxarm64') private final boolean forMac = buildEnvs?.contains('macos') @@ -114,10 +115,11 @@ class GenerateLibs extends DefaultTask { BuildTarget[] buildTargets = [] if (forWindows) { - def win64 = BuildTarget.newDefaultTarget(Os.Windows, Architecture.Bitness._64) - requireCpp17(win64) - addFreeTypeIfEnabled(win64) - buildTargets += win64 + buildTargets += createWindowsTarget(Architecture.x86) + } + + if (forWindowsArm64) { + buildTargets += createWindowsTarget(Architecture.ARM) } if (forLinux) { @@ -145,6 +147,8 @@ class GenerateLibs extends DefaultTask { if (forWindows) BuildExecutor.executeAnt(jniDir + '/build-windows64.xml', commonParams) + if (forWindowsArm64) + BuildExecutor.executeAnt(jniDir + '/build-windowsarm64.xml', commonParams) if (forLinux) BuildExecutor.executeAnt(jniDir + '/build-linux64.xml', commonParams) if (forLinuxArm64) @@ -158,6 +162,8 @@ class GenerateLibs extends DefaultTask { if (forWindows) checkLibExist("windows64/imgui-java64.dll") + if (forWindowsArm64) + checkLibExist("windowsarm64/imgui-java64.dll") if (forLinux) checkLibExist("linux64/libimgui-java64.so") if (forLinuxArm64) @@ -191,6 +197,20 @@ class GenerateLibs extends DefaultTask { return linuxTarget } + BuildTarget createWindowsTarget(Architecture arch) { + def windowsTarget = BuildTarget.newDefaultTarget(Os.Windows, Architecture.Bitness._64, arch) + windowsTarget.libName = "imgui-java64.dll" // Lib for arm64 will be named the same for consistency. + if (arch == Architecture.ARM) { + // Windows on ARM needs an LLVM/Clang based MinGW toolchain; GCC does not ship a + // Windows ARM64 target. LLVM-MinGW provides the aarch64-w64-mingw32- wrappers. + windowsTarget.cCompiler = "clang" + windowsTarget.cppCompiler = "clang++" + } + requireCpp17(windowsTarget) + addFreeTypeIfEnabled(windowsTarget) + return windowsTarget + } + BuildTarget createMacTarget(Architecture arch) { def minMacOsVersion = '10.15' def macTarget = BuildTarget.newDefaultTarget(Os.MacOsX, Architecture.Bitness._64, arch) diff --git a/imgui-app/build.gradle b/imgui-app/build.gradle index daef6c93..2ad07b5b 100644 --- a/imgui-app/build.gradle +++ b/imgui-app/build.gradle @@ -24,7 +24,7 @@ dependencies { api 'org.lwjgl:lwjgl-opengl' api 'org.lwjgl:lwjgl-sdl' - ['natives-linux', 'natives-windows', 'natives-macos', 'natives-macos-arm64'].each { + ['natives-linux', 'natives-windows', 'natives-windows-arm64', 'natives-macos', 'natives-macos-arm64'].each { api "org.lwjgl:lwjgl::$it" api "org.lwjgl:lwjgl-glfw::$it" api "org.lwjgl:lwjgl-opengl::$it" diff --git a/patches/imgui-node-editor-libcxx-exception.patch b/patches/imgui-node-editor-libcxx-exception.patch new file mode 100644 index 00000000..376c6e5d --- /dev/null +++ b/patches/imgui-node-editor-libcxx-exception.patch @@ -0,0 +1,10 @@ +--- a/crude_json.cpp ++++ b/crude_json.cpp +@@ -6,6 +6,7 @@ + // CREDITS + // Written by Michal Cichon + # include "crude_json.h" ++# include + # include + # include + # include