From 0f08fd5333de840996af70b8e836b6a8df10cf0d Mon Sep 17 00:00:00 2001 From: "Martin Hinshelwood NKDAgility.com" Date: Thu, 30 Oct 2025 15:16:10 -0500 Subject: [PATCH] Add support for Windows ARM64 builds and update related configurations --- .github/workflows/build-project.yaml | 53 +++++++++++++++++++-- CMakePresets.json | 70 ++++++++++++++++++++++++++++ buildspec.json | 12 +++-- cmake/FetchOnnxruntime.cmake | 32 +++++++++++-- src/ort-utils/ort-session-utils.cpp | 4 +- 5 files changed, 159 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build-project.yaml b/.github/workflows/build-project.yaml index 9385cb13..18afab56 100644 --- a/.github/workflows/build-project.yaml +++ b/.github/workflows/build-project.yaml @@ -170,7 +170,7 @@ jobs: # - name: Bootstrap vcpkg # working-directory: ${{ env.VCPKG_ROOT }} # run: ./bootstrap-vcpkg.sh - + # - name: Install mono # run: brew install mono @@ -273,7 +273,7 @@ jobs: # - name: Bootstrap vcpkg # working-directory: ${{ env.VCPKG_ROOT }} # run: ./bootstrap-vcpkg.sh - + # - name: Install mono # run: sudo apt-get -y install mono-devel @@ -374,7 +374,7 @@ jobs: # shell: pwsh # run: | # $NUGET_EXE_PATH = & "${{ env.VCPKG_ROOT }}/vcpkg" fetch nuget | Select-Object -Last 1 - + # & $NUGET_EXE_PATH sources add ` # -Source "https://nuget.pkg.github.com/kaito-tokyo/index.json" ` # -StorePasswordInClearText ` @@ -406,3 +406,50 @@ jobs: with: name: ${{ steps.setup.outputs.pluginName }}-${{ steps.setup.outputs.pluginVersion }}-windows-x64-${{ needs.check-event.outputs.commitHash }} path: ${{ github.workspace }}/release/${{ steps.setup.outputs.pluginName }}-${{ steps.setup.outputs.pluginVersion }}-windows-x64*.* + + windows-arm64-build: + name: Build for Windows ARM64 🪟 + runs-on: windows-2022 + needs: check-event + defaults: + run: + shell: pwsh + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + fetch-depth: 0 + + - name: Set Up Environment 🔧 + id: setup + run: | + # Set Up Environment 🔧 + if ( $Env:RUNNER_DEBUG -ne $null ) { + Set-PSDebug -Trace 1 + } + + $BuildSpec = Get-Content -Path buildspec.json -Raw | ConvertFrom-Json + $ProductName = $BuildSpec.name + $ProductVersion = $BuildSpec.version + + "pluginName=${ProductName}" >> $env:GITHUB_OUTPUT + "pluginVersion=${ProductVersion}" >> $env:GITHUB_OUTPUT + + - name: Build Plugin 🧱 + uses: ./.github/actions/build-plugin + with: + target: arm64 + config: ${{ needs.check-event.outputs.config }} + + - name: Package Plugin 📀 + uses: ./.github/actions/package-plugin + with: + target: arm64 + config: ${{ needs.check-event.outputs.config }} + package: ${{ fromJSON(needs.check-event.outputs.package) }} + + - name: Upload Artifacts 📡 + uses: actions/upload-artifact@v4 + with: + name: ${{ steps.setup.outputs.pluginName }}-${{ steps.setup.outputs.pluginVersion }}-windows-arm64-${{ needs.check-event.outputs.commitHash }} + path: ${{ github.workspace }}/release/${{ steps.setup.outputs.pluginName }}-${{ steps.setup.outputs.pluginVersion }}-windows-arm64*.* diff --git a/CMakePresets.json b/CMakePresets.json index b57f1af3..f69a7383 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -74,6 +74,55 @@ "CMAKE_COMPILE_WARNING_AS_ERROR": false } }, + { + "name": "windows-arm64", + "displayName": "Windows ARM64", + "description": "Build for Windows ARM64 using Visual Studio 2022", + "inherits": ["template"], + "binaryDir": "${sourceDir}/build_arm64", + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + }, + "generator": "Visual Studio 17 2022", + "architecture": "ARM64,version=10.0.22621", + "warnings": {"dev": true, "deprecated": true}, + "cacheVariables": { + "CMAKE_BUILD_TYPE": "RelWithDebInfo", + "ENABLE_FRONTEND_API": false, + "ENABLE_QT": false + } + }, + { + "name": "windows-arm64-insiders", + "displayName": "Windows ARM64 (VS 2026 Insiders)", + "description": "Build for Windows ARM64 using Visual Studio 2026 Insiders", + "inherits": ["template"], + "binaryDir": "${sourceDir}/build_arm64", + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + }, + "generator": "Visual Studio 18 2026", + "architecture": "ARM64,version=10.0.22621", + "warnings": {"dev": true, "deprecated": true}, + "cacheVariables": { + "CMAKE_BUILD_TYPE": "RelWithDebInfo", + "ENABLE_FRONTEND_API": false, + "ENABLE_QT": false + } + }, + { + "name": "windows-ci-arm64", + "inherits": ["windows-arm64"], + "displayName": "Windows ARM64 CI build", + "description": "Build for Windows ARM64 on CI", + "cacheVariables": { + "CMAKE_COMPILE_WARNING_AS_ERROR": false + } + }, { "name": "ubuntu-x86_64", "displayName": "Ubuntu x86_64", @@ -133,6 +182,27 @@ "description": "Windows CI build for x64 (RelWithDebInfo configuration)", "configuration": "RelWithDebInfo" }, + { + "name": "windows-arm64", + "configurePreset": "windows-arm64", + "displayName": "Windows ARM64", + "description": "Windows build for ARM64 using VS 2022", + "configuration": "RelWithDebInfo" + }, + { + "name": "windows-arm64-insiders", + "configurePreset": "windows-arm64-insiders", + "displayName": "Windows ARM64 (VS 2026 Insiders)", + "description": "Windows build for ARM64 using VS 2026 Insiders", + "configuration": "RelWithDebInfo" + }, + { + "name": "windows-ci-arm64", + "configurePreset": "windows-ci-arm64", + "displayName": "Windows ARM64 CI", + "description": "Windows CI build for ARM64 (RelWithDebInfo configuration)", + "configuration": "RelWithDebInfo" + }, { "name": "ubuntu-x86_64", "configurePreset": "ubuntu-x86_64", diff --git a/buildspec.json b/buildspec.json index d8c321f0..fe94955c 100644 --- a/buildspec.json +++ b/buildspec.json @@ -6,7 +6,8 @@ "label": "OBS sources", "hashes": { "macos": "39751f067bacc13d44b116c5138491b5f1391f91516d3d590d874edd21292291", - "windows-x64": "2c8427c10b55ac6d68008df2e9a3e82f4647aaad18f105e30d4713c2de678ccf" + "windows-x64": "2c8427c10b55ac6d68008df2e9a3e82f4647aaad18f105e30d4713c2de678ccf", + "windows-ARM64": "2c8427c10b55ac6d68008df2e9a3e82f4647aaad18f105e30d4713c2de678ccf" } }, "prebuilt": { @@ -15,7 +16,8 @@ "label": "Pre-Built obs-deps", "hashes": { "macos": "495687e63383d1a287684b6e2e9bfe246bb8f156fe265926afb1a325af1edd2a", - "windows-x64": "c8c642c1070dc31ce9a0f1e4cef5bb992f4bff4882255788b5da12129e85caa7" + "windows-x64": "c8c642c1070dc31ce9a0f1e4cef5bb992f4bff4882255788b5da12129e85caa7", + "windows-ARM64": "f581cc61e8f734a8b12d485fc8662a408ca59d222814e4b37bce115bd442fb04" } }, "qt6": { @@ -24,10 +26,12 @@ "label": "Pre-Built Qt6", "hashes": { "macos": "d3f5f04b6ea486e032530bdf0187cbda9a54e0a49621a4c8ba984c5023998867", - "windows-x64": "0e76bf0555dd5382838850b748d3dcfab44a1e1058441309ab54e1a65b156d0a" + "windows-x64": "0e76bf0555dd5382838850b748d3dcfab44a1e1058441309ab54e1a65b156d0a", + "windows-ARM64": "7aab240504931f32ea8e8d208a912a0d6ddbd78c16858f2e559c7c9b29ab9326" }, "debugSymbols": { - "windows-x64": "11b7be92cf66a273299b8f3515c07a5cfb61614b59a4e67f7fc5ecba5e2bdf21" + "windows-x64": "11b7be92cf66a273299b8f3515c07a5cfb61614b59a4e67f7fc5ecba5e2bdf21", + "windows-ARM64": "TBD" } } }, diff --git a/cmake/FetchOnnxruntime.cmake b/cmake/FetchOnnxruntime.cmake index 1d9080c6..ba336b0d 100644 --- a/cmake/FetchOnnxruntime.cmake +++ b/cmake/FetchOnnxruntime.cmake @@ -35,8 +35,14 @@ if(USE_PREDEFINED_ONNXRUNTIME) set(Onnxruntime_URL "${Onnxruntime_BASEURL}/onnxruntime-osx-universal2-${Onnxruntime_VERSION}.tgz") set(Onnxruntime_HASH SHA256=9FA57FA6F202A373599377EF75064AE568FDA8DA838632B26A86024C7378D306) elseif(MSVC) - set(Onnxruntime_URL "${Onnxruntime_WINDOWS_BASEURL}/onnxruntime-windows-${Onnxruntime_WINDOWS_VERSION}-Release.zip") - set(OOnnxruntime_HASH SHA256=39E63850D9762810161AE1B4DEAE5E3C02363521273E4B894A9D9707AB626C38) + if(CMAKE_VS_PLATFORM_NAME STREQUAL "ARM64") + # Use official Microsoft ONNX Runtime for ARM64 (no static build available yet) + set(Onnxruntime_URL "${Onnxruntime_BASEURL}/onnxruntime-win-arm64-${Onnxruntime_VERSION}.zip") + set(Onnxruntime_HASH "") + else() + set(Onnxruntime_URL "${Onnxruntime_WINDOWS_BASEURL}/onnxruntime-windows-${Onnxruntime_WINDOWS_VERSION}-Release.zip") + set(OOnnxruntime_HASH SHA256=39E63850D9762810161AE1B4DEAE5E3C02363521273E4B894A9D9707AB626C38) + endif() else() if(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") set(Onnxruntime_URL "${Onnxruntime_BASEURL}/onnxruntime-linux-aarch64-${Onnxruntime_VERSION}.tgz") @@ -69,7 +75,26 @@ if(APPLE) "@loader_path/../Frameworks/libonnxruntime.${Onnxruntime_VERSION}.dylib" $ ) elseif(MSVC) - add_library(Ort INTERFACE) + if(CMAKE_VS_PLATFORM_NAME STREQUAL "ARM64") + # ARM64 uses dynamic ONNX Runtime (no static build with DirectML available yet) + set(Onnxruntime_LIB "${onnxruntime_SOURCE_DIR}/lib/onnxruntime.dll") + target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE "${onnxruntime_SOURCE_DIR}/lib/onnxruntime.lib") + target_include_directories(${CMAKE_PROJECT_NAME} SYSTEM PUBLIC "${onnxruntime_SOURCE_DIR}/include") + target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE DISABLE_ONNXRUNTIME_GPU) + + # Copy DLL to output directory + add_custom_command( + TARGET ${CMAKE_PROJECT_NAME} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + "${onnxruntime_SOURCE_DIR}/lib/onnxruntime.dll" + "$" + COMMENT "Copying ONNX Runtime DLL for ARM64" + ) + + install(FILES "${onnxruntime_SOURCE_DIR}/lib/onnxruntime.dll" DESTINATION "obs-plugins/64bit") + else() + # x64 uses static ONNX Runtime with DirectML + add_library(Ort INTERFACE) set( Onnxruntime_LIB_NAMES session;providers_shared;providers_dml;optimizer;providers;framework;graph;util;mlas;common;flatbuffers @@ -106,6 +131,7 @@ elseif(MSVC) target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE Ort) install(IMPORTED_RUNTIME_ARTIFACTS Ort::DirectML DESTINATION "obs-plugins/64bit") + endif() else() if(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") set(Onnxruntime_LINK_LIBS "${onnxruntime_SOURCE_DIR}/lib/libonnxruntime.so.${Onnxruntime_VERSION}") diff --git a/src/ort-utils/ort-session-utils.cpp b/src/ort-utils/ort-session-utils.cpp index 4ef0a0f2..869eabbc 100644 --- a/src/ort-utils/ort-session-utils.cpp +++ b/src/ort-utils/ort-session-utils.cpp @@ -6,7 +6,7 @@ #include #endif -#ifdef _WIN32 +#if defined(_WIN32) && !defined(DISABLE_ONNXRUNTIME_GPU) #include #include #include @@ -100,7 +100,7 @@ int createOrtSession(filter_data *tf) Ort::ThrowOnError(OrtSessionOptionsAppendExecutionProvider_CUDA(sessionOptions, 0)); } #endif -#ifdef _WIN32 +#if defined(_WIN32) && !defined(DISABLE_ONNXRUNTIME_GPU) if (tf->useGPU == USEGPU_DML) { auto &api = Ort::GetApi(); OrtDmlApi *dmlApi = nullptr;