From d52b48cbbbd4a168802a7a466c5f769b72ee3f62 Mon Sep 17 00:00:00 2001 From: rc-swag <58423624+rc-swag@users.noreply.github.com> Date: Tue, 28 Oct 2025 16:40:42 +1000 Subject: [PATCH] feat(windows): handle arm64 complier environment Update the build.bat to handle configuring the build environment with vsdevcmd correctly for arm64 2019 doesn't work very well so have to have pretty weird if statement. also checked in some missed updates to function name change --- core/build.bat | 48 +++++++++++++++---- core/commands.inc.sh | 6 +-- windows/src/engine/keyman/UfrmKeyman7Main.pas | 2 +- .../src/global/delphi/general/utilwow64.pas | 3 +- 4 files changed, 46 insertions(+), 13 deletions(-) diff --git a/core/build.bat b/core/build.bat index 3ac50e83d9..446246c8d1 100644 --- a/core/build.bat +++ b/core/build.bat @@ -8,7 +8,7 @@ if "%1"=="" goto help if "%1"=="all" goto all if "%1"=="x86" goto build if "%1"=="x64" goto build -if "%1"=="ARM64" goto build +if "%1"=="arm64" goto build echo "Invalid parameter." goto help @@ -16,9 +16,9 @@ goto help rem ---------------------------------- :help -echo Usage: %0 x86^|x64^|ARM64^|all debug^|release [configure] [build] [test] [additional params for meson/ninja] +echo Usage: %0 x86^|x64^|arm64^|all debug^|release [configure] [build] [test] [additional params for meson/ninja] echo or -echo Usage: %0 x86^|x64^|ARM64^ -c +echo Usage: %0 x86^|x64^|arm64^ -c echo -c will leave your environment configured for Visual Studio for selected platform. echo. echo Otherwise, %0 is intended to be used by build.sh, not directly. @@ -37,7 +37,7 @@ cd %KEYMAN_ROOT%\core cmd /c build.bat x64 %2 %3 %4 %5 %6 %7 %8 %9 || exit !errorlevel! cd %KEYMAN_ROOT%\core -cmd /c build.bat ARM64 %2 %3 %4 %5 %6 %7 %8 %9 || exit !errorlevel! +cmd /c build.bat arm64 %2 %3 %4 %5 %6 %7 %8 %9 || exit !errorlevel! goto :eof @@ -45,11 +45,28 @@ rem ---------------------------------- :build +set "HOST_ARCH=%PROCESSOR_ARCHITECTURE%" + +rem Map Windows arch strings to VsDevCmd expected values +if /I "%HOST_ARCH%"=="AMD64" set "HOST_ARCH=amd64" +if /I "%HOST_ARCH%"=="x86" set "HOST_ARCH=x86" +if /I "%HOST_ARCH%"=="ARM64" set "HOST_ARCH=arm64" + + set ARCH=%1 shift if "%1"=="-c" goto :setup +rem Initialize MESON_CROSS_FILE as empty +set "MESON_CROSS_FILE=" + +rem Check if cross file exists (using %~dp0 for script directory) +if exist "%~dp0cross-%ARCH%.build" ( + echo [DEBUG] Using cross file cross-%ARCH%.build + set "MESON_CROSS_FILE=--cross-file cross-%ARCH%.build" +) + echo === Locating Visual Studio === rem From https://github.com/microsoft/vswhere @@ -69,8 +86,23 @@ if not exist "!VsDevCmd_Path!" ( echo === Configuring VC++ === set VSCMD_SKIP_SENDTELEMETRY=1 -call "!VsDevCmd_Path!" -arch=!ARCH! -no_logo -startdir=none || exit !errorlevel! - +rem vsdevcmd.bat -arch parameter for 2019 is can only be x86 or amd64. (arm64 is not supported till 2022) +rem -host_arch does support is required for arm64 builds on x86/amd64 hosts. +rem However on arm64 host we cant even use vsdevcmd -arch=arm64 as it fails.(2019) +rem for now we will have workaround this untill updating to VS2022 +if /I "%HOST_ARCH%"=="arm64" ( + if /I "%ARCH%"=="arm64" ( + call "!VsDevCmd_Path!" -no_logo -startdir=none || exit !errorlevel! + ) else ( + call "!VsDevCmd_Path!" -arch=!ARCH! -no_logo -startdir=none || exit !errorlevel! + ) +) else ( + if /I "%ARCH%"=="arm64" ( + call "!VsDevCmd_Path!" -arch=!ARCH! -host_arch=!HOST_ARCH! -no_logo -startdir=none || exit !errorlevel! + ) else ( + call "!VsDevCmd_Path!" -arch=!ARCH! -no_logo -startdir=none || exit !errorlevel! + ) +) cd %KEYMAN_ROOT%\core set BUILDTYPE=%1 @@ -85,9 +117,9 @@ if "!COMMAND!" == "configure" ( echo === Configuring Keyman Core for Windows !ARCH! !BUILDTYPE! === if exist build\!ARCH!\!BUILDTYPE! rd /s/q build\!ARCH!\!BUILDTYPE! if "%1" == "--no-tests" ( - meson setup build\!ARCH!\!BUILDTYPE! !STATIC_LIBRARY! --buildtype !BUILDTYPE! -Dkeyman_core_tests=false --werror %2 %3 %4 %5 %6 %7 %8 %9 || exit !errorlevel! + meson setup !MESON_CROSS_FILE! build\!ARCH!\!BUILDTYPE ! !STATIC_LIBRARY! --buildtype !BUILDTYPE! -Dkeyman_core_tests=false --werror %2 %3 %4 %5 %6 %7 %8 %9 || exit !errorlevel! ) else ( - meson setup build\!ARCH!\!BUILDTYPE! !STATIC_LIBRARY! --buildtype !BUILDTYPE! --werror %1 %2 %3 %4 %5 %6 %7 %8 %9 || exit !errorlevel! + meson setup !MESON_CROSS_FILE! build\!ARCH!\!BUILDTYPE! !STA T IC_LIBRARY! --buildtype !BUILDTYPE! --werror %1 %2 %3 %4 %5 %6 %7 %8 %9 || exit !errorlevel! ) shift ) diff --git a/core/commands.inc.sh b/core/commands.inc.sh index 9672244c86..4584b2dfd6 100644 --- a/core/commands.inc.sh +++ b/core/commands.inc.sh @@ -50,7 +50,7 @@ do_configure() { STANDARD_MESON_ARGS="$STANDARD_MESON_ARGS --cross-file wasm.defs.build --cross-file wasm.build --default-library static" fi - if [[ $target =~ ^(x86|x64|ARM64)$ ]]; then + if [[ $target =~ ^(x86|x64|arm64)$ ]]; then cmd //C build.bat $target $BUILDER_CONFIGURATION configure $BUILD_BAT_keyman_core_tests "${builder_extra_params[@]}" else pushd "$THIS_SCRIPT_PATH" > /dev/null @@ -69,7 +69,7 @@ do_configure() { do_build() { local target=$1 builder_start_action build:$target || return 0 - if [[ $target =~ ^(x86|x64|ARM64)$ ]]; then + if [[ $target =~ ^(x86|x64|arm64)$ ]]; then cmd //C build.bat $target $BUILDER_CONFIGURATION build "${builder_extra_params[@]}" elif $MESON_LOW_VERSION; then pushd "$MESON_PATH" > /dev/null @@ -88,7 +88,7 @@ do_build() { do_test() { local target=$1 builder_start_action test:$target || return 0 - if [[ $target =~ ^(x86|x64|ARM64)$ ]]; then + if [[ $target =~ ^(x86|x64|arm64)$ ]]; then cmd //C build.bat $target $BUILDER_CONFIGURATION test $testparams else if [[ $target == wasm ]] && builder_is_macos; then diff --git a/windows/src/engine/keyman/UfrmKeyman7Main.pas b/windows/src/engine/keyman/UfrmKeyman7Main.pas index 917ef6e6d5..a5f6e48be1 100644 --- a/windows/src/engine/keyman/UfrmKeyman7Main.pas +++ b/windows/src/engine/keyman/UfrmKeyman7Main.pas @@ -2001,7 +2001,7 @@ var sei: TShellExecuteInfoW; begin - if not IsNativeMachineWowArm64 then Exit; + if not IsNativeMachineArm64 then Exit; try // TODO: use TKeymanPaths to find keymanx64? diff --git a/windows/src/global/delphi/general/utilwow64.pas b/windows/src/global/delphi/general/utilwow64.pas index d46aa67246..93a59d6260 100644 --- a/windows/src/global/delphi/general/utilwow64.pas +++ b/windows/src/global/delphi/general/utilwow64.pas @@ -11,6 +11,7 @@ const {$ENDIF} function IsWow64: Boolean; +function IsNativeMachineArm64: Boolean; implementation @@ -33,7 +34,7 @@ end; Determines whether the current system's native architecture is ARM64. @returns: True if the native machine architecture is ARM64, False otherwise *) -function IsNativeMachineWowArm64: Boolean; +function IsNativeMachineArm64: Boolean; var processMachine: USHORT; nativeMachine: USHORT;