From 40947d3ef03e3489fb2abd4d99de03c8b665a20b Mon Sep 17 00:00:00 2001 From: Ryan Ewen Date: Fri, 17 Jul 2026 14:40:24 -0400 Subject: [PATCH 01/18] feat: complete native Windows ARM64 build support BambuStudio already carried most Windows-on-ARM64 plumbing (deps-windows.cmake DEP_PLATFORM/wxWidgets ARM64, Boost winfib, OpenCV IPP-off, OpenEXR arch, prebuilt GMP/MPFR win_arm64 libs, bambustudio_copy_dlls ARM64 branch, cross-compile detection, and full -ARCH support in build_win.bat). This fills the remaining gaps so an ARM64 target actually configures, compiles, and ships. Source (compile blockers on ARM64): - StackWalker.cpp: add _M_ARM64 branch (was #error "Platform not supported!") - BaseException.cpp: ARM64 CONTEXT has no EFlags; use Cpsr and add an ARM64 register dump for crash diagnostics - Int128.hpp: guard the x64-only _mul128 #pragma intrinsic (ARM64 already uses __umulh); silences a benign MSVC warning Dependencies: - OpenSSL.cmake: configure VC-WIN64-ARM (not VC-WIN64A) for Windows ARM64 - FindGLEW.cmake: ARM64 arch branch for the GLEW_ROOT binary-dist fallback CI (folds arm64 into the existing Windows build without touching the x64 path): - build_all.yml: add {os: windows-11-arm, arch: arm64} to the matrix - build_check_cache.yml: startsWith(windows) so arm64 gets the Windows cache path/shell (distinct cache key comes from inputs.os) - build_deps.yml / build_bambu.yml: ARM64 deps + app build steps using the Visual Studio 17 2022 generator (the arm runner has no VS 2026) with -A ARM64, runtime-resolved Win10 SDK, and arch-suffixed artifacts All ARM64 logic is gated; the x64/x86/macOS/Linux paths are unchanged. --- .github/workflows/build_all.yml | 2 ++ .github/workflows/build_bambu.yml | 37 ++++++++++++++++++++++--- .github/workflows/build_check_cache.yml | 4 +-- .github/workflows/build_deps.yml | 35 +++++++++++++++++++++-- cmake/modules/FindGLEW.cmake | 5 ++++ deps/OpenSSL/OpenSSL.cmake | 6 +++- src/BaseException.cpp | 12 ++++++++ src/StackWalker.cpp | 9 ++++++ src/libslic3r/Int128.hpp | 3 ++ 9 files changed, 103 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build_all.yml b/.github/workflows/build_all.yml index bce8d82aa3..023bf839d6 100644 --- a/.github/workflows/build_all.yml +++ b/.github/workflows/build_all.yml @@ -47,6 +47,8 @@ jobs: - os: ubuntu-24.04 - os: ubuntu-26.04 - os: windows-latest + - os: windows-11-arm + arch: arm64 - os: macos-15-intel arch: x86_64 - os: macos-15 diff --git a/.github/workflows/build_bambu.yml b/.github/workflows/build_bambu.yml index 51c795ca77..fe2ee392f5 100644 --- a/.github/workflows/build_bambu.yml +++ b/.github/workflows/build_bambu.yml @@ -37,7 +37,7 @@ jobs: fail-on-cache-miss: true - name: Get the version and date on Ubuntu and macOS - if: inputs.os != 'windows-latest' + if: ${{ !startsWith(inputs.os, 'windows') }} run: | ver_pure=$(grep 'set(SLIC3R_VERSION' version.inc | cut -d '"' -f2) if [[ "${{ github.event_name }}" == "pull_request" ]]; then @@ -51,7 +51,7 @@ jobs: shell: bash - name: Get the version and date on Windows - if: inputs.os == 'windows-latest' + if: startsWith(inputs.os, 'windows') run: | $date = Get-Date -Format 'yyyyMMdd' $ref = "${{ github.ref }}" @@ -114,11 +114,11 @@ jobs: # Windows - name: setup MSVC - if: inputs.os == 'windows-latest' + if: startsWith(inputs.os, 'windows') uses: microsoft/setup-msbuild@v2 - name: Install nsis and pkgconfig - if: inputs.os == 'windows-latest' + if: startsWith(inputs.os, 'windows') run: | dir "C:/Program Files (x86)/Windows Kits/10/Include" choco install nsis @@ -133,6 +133,22 @@ jobs: cmake .. -G "Visual Studio 18 2026" -A X64 -DBBL_RELEASE_TO_PUBLIC=1 -DBBL_INTERNAL_TESTING=0 -DCMAKE_PREFIX_PATH="${{ github.workspace }}\deps\build\BambuStudio_dep\usr\local" -DCMAKE_INSTALL_PREFIX="../install-dir" -DCMAKE_BUILD_TYPE=Release -DWIN10SDK_PATH="C:/Program Files (x86)/Windows Kits/10/Include/10.0.22000.0" cmake --build . --target install --config Release -- -m + # Windows on ARM64: VS 2022 generator (the arm runner has no VS 2026), and + # the newest installed 10.* SDK is resolved at runtime rather than pinned, + # since the arm image may not ship the exact SDK the x64 job hard-codes. + - name: Build slicer Win ARM64 + if: inputs.os == 'windows-11-arm' + working-directory: ${{ github.workspace }} + shell: pwsh + run: | + $sdkRoot = "C:/Program Files (x86)/Windows Kits/10/Include" + $sdk = (Get-ChildItem $sdkRoot -Directory | Where-Object { $_.Name -match '^10\.' } | Sort-Object Name -Descending | Select-Object -First 1).FullName + Write-Output "Using Windows SDK: $sdk" + mkdir build + cd build + cmake .. -G "Visual Studio 17 2022" -A ARM64 -DBBL_RELEASE_TO_PUBLIC=1 -DBBL_INTERNAL_TESTING=0 -DCMAKE_PREFIX_PATH="${{ github.workspace }}\deps\build\BambuStudio_dep\usr\local" -DCMAKE_INSTALL_PREFIX="../install-dir" -DCMAKE_BUILD_TYPE=Release -DWIN10SDK_PATH="$sdk" + cmake --build . --target install --config Release -- -m + # - name: Create installer Win # if: inputs.os == 'windows-latest' # working-directory: ${{ github.workspace }}/build @@ -145,6 +161,12 @@ jobs: shell: cmd run: '"C:/Program Files/7-Zip/7z.exe" a -tzip BambuStudio_Windows_${{ env.ver }}_portable.zip ${{ github.workspace }}/install-dir' + - name: Pack app ARM64 + if: inputs.os == 'windows-11-arm' + working-directory: ${{ github.workspace }} + shell: cmd + run: '"C:/Program Files/7-Zip/7z.exe" a -tzip BambuStudio_Windows_${{ env.ver }}_arm64_portable.zip ${{ github.workspace }}/install-dir' + # - name: Pack PDB # if: inputs.os == 'windows-latest' # working-directory: ${{ github.workspace }}/build/src/Release @@ -158,6 +180,13 @@ jobs: name: BambuStudio_Windows_${{ env.ver }}_portable path: ${{ github.workspace }}/BambuStudio_Windows_${{ env.ver }}_portable.zip + - name: Upload artifacts Win ARM64 zip + if: inputs.os == 'windows-11-arm' + uses: actions/upload-artifact@v6 + with: + name: BambuStudio_Windows_${{ env.ver }}_arm64_portable + path: ${{ github.workspace }}/BambuStudio_Windows_${{ env.ver }}_arm64_portable.zip + # Ubuntu - name: Install dependencies from BuildLinux.sh diff --git a/.github/workflows/build_check_cache.yml b/.github/workflows/build_check_cache.yml index fde82ebff8..0d5ff3bd28 100644 --- a/.github/workflows/build_check_cache.yml +++ b/.github/workflows/build_check_cache.yml @@ -30,8 +30,8 @@ jobs: - name: set outputs id: set_outputs env: - dep-folder-name: ${{ inputs.os == 'windows-latest' && '/BambuStudio_dep' || ((inputs.os == 'macos-15-intel' || inputs.os == 'macos-15' || inputs.os == 'macos-26') && '') || (inputs.os != 'macos-15-intel' && inputs.os != 'macos-15' && inputs.os != 'macos-26') && '/destdir' || '' }} - output-cmd: ${{ inputs.os == 'windows-latest' && '$env:GITHUB_OUTPUT' || '"$GITHUB_OUTPUT"'}} + dep-folder-name: ${{ startsWith(inputs.os, 'windows') && '/BambuStudio_dep' || ((inputs.os == 'macos-15-intel' || inputs.os == 'macos-15' || inputs.os == 'macos-26') && '') || (inputs.os != 'macos-15-intel' && inputs.os != 'macos-15' && inputs.os != 'macos-26') && '/destdir' || '' }} + output-cmd: ${{ startsWith(inputs.os, 'windows') && '$env:GITHUB_OUTPUT' || '"$GITHUB_OUTPUT"'}} run: | echo cache-key=${{ inputs.os }}-cache-bambustudio_deps-build-${{ hashFiles('deps/**') }} >> ${{ env.output-cmd }} echo cache-path=${{ github.workspace }}/deps/build${{ env.dep-folder-name }} >> ${{ env.output-cmd }} diff --git a/.github/workflows/build_deps.yml b/.github/workflows/build_deps.yml index aec57f398a..b614d93c16 100644 --- a/.github/workflows/build_deps.yml +++ b/.github/workflows/build_deps.yml @@ -42,16 +42,16 @@ jobs: key: ${{ inputs.cache-key }} - name: setup dev on Windows - if: inputs.os == 'windows-latest' + if: startsWith(inputs.os, 'windows') uses: microsoft/setup-msbuild@v2 - name: Get the date on Ubuntu and macOS - if: inputs.os != 'windows-latest' + if: ${{ !startsWith(inputs.os, 'windows') }} run: echo "date=$(date +'%Y%m%d')" >> $GITHUB_ENV shell: bash - name: Get the date on Windows - if: inputs.os == 'windows-latest' + if: startsWith(inputs.os, 'windows') run: echo "date=$(Get-Date -Format 'yyyyMMdd')" | Out-File -Append -FilePath $env:GITHUB_ENV -Encoding utf8 shell: pwsh @@ -74,6 +74,28 @@ jobs: working-directory: ${{ github.workspace }} run: Compress-Archive -Path "${{ github.workspace }}\deps\build\BambuStudio_dep\*" -DestinationPath "${{ github.workspace }}\deps\build\BambuStudio_dep_win64_${{ env.date }}_vs2022.zip" shell: pwsh + + # Windows on ARM64. The windows-11-arm runner ships Visual Studio 2022 + # (v17), not 2026, so the generator differs from the x64 job above. The + # GMP/MPFR/OpenSSL/Boost ARM64 dep handling lives in deps/*.cmake and is + # selected automatically from -A ARM64 (CMAKE_GENERATOR_PLATFORM). + - name: Build on Windows ARM64 + if: inputs.os == 'windows-11-arm' + working-directory: ${{ github.workspace }} + run: | + choco install strawberryperl + choco install pkgconfiglite + mkdir ${{ github.workspace }}\deps\build + mkdir ${{ github.workspace }}\deps\build\BambuStudio_dep + cd "${{ github.workspace }}\deps\build" + cmake ../ -G "Visual Studio 17 2022" -A ARM64 -DDESTDIR="./BambuStudio_dep" -DCMAKE_BUILD_TYPE=Release -DDEP_DEBUG=OFF + msbuild /m ALL_BUILD.vcxproj + + - name: pack deps on Windows ARM64 + if: inputs.os == 'windows-11-arm' + working-directory: ${{ github.workspace }} + run: Compress-Archive -Path "${{ github.workspace }}\deps\build\BambuStudio_dep\*" -DestinationPath "${{ github.workspace }}\deps\build\BambuStudio_dep_win-arm64_${{ env.date }}_vs2022.zip" + shell: pwsh - name: Fix python install error on mac if: inputs.os == 'macos-15-intel' @@ -167,6 +189,13 @@ jobs: name: BambuStudio_dep_win64_${{ env.date }} path: ${{ github.workspace }}/deps/build/BambuStudio_dep*.zip + - name: Upload Windows ARM64 artifacts + if: inputs.os == 'windows-11-arm' + uses: actions/upload-artifact@v6 + with: + name: BambuStudio_dep_win-arm64_${{ env.date }} + path: ${{ github.workspace }}/deps/build/BambuStudio_dep*.zip + - name: Upload Ubuntu artifacts if: ${{ ! env.ACT && (inputs.os == 'ubuntu-22.04' || inputs.os == 'ubuntu-24.04' || inputs.os == 'ubuntu-26.04') }} uses: actions/upload-artifact@v6 diff --git a/cmake/modules/FindGLEW.cmake b/cmake/modules/FindGLEW.cmake index a2b55c832d..67ef60fb64 100644 --- a/cmake/modules/FindGLEW.cmake +++ b/cmake/modules/FindGLEW.cmake @@ -134,6 +134,11 @@ endif() if("${CMAKE_GENERATOR_PLATFORM}" MATCHES "x64" OR "${CMAKE_GENERATOR}" MATCHES "Win64") set(_arch "x64") +elseif("${CMAKE_GENERATOR_PLATFORM}" MATCHES "ARM64") + # GLEW's binary distribution ships one 64-bit import-library layout; ARM64 + # reuses the x64 lib/Release path. (Bambu builds GLEW from source into the + # dep prefix, so this only affects the GLEW_ROOT binary-dist fallback.) + set(_arch "x64") else() set(_arch "Win32") endif() diff --git a/deps/OpenSSL/OpenSSL.cmake b/deps/OpenSSL/OpenSSL.cmake index 6e443dcfe0..24a21955a2 100644 --- a/deps/OpenSSL/OpenSSL.cmake +++ b/deps/OpenSSL/OpenSSL.cmake @@ -6,7 +6,11 @@ if(DEFINED OPENSSL_ARCH) set(_cross_arch ${OPENSSL_ARCH}) else() if(WIN32) - set(_cross_arch "VC-WIN64A") + if("${CMAKE_GENERATOR_PLATFORM}" STREQUAL "ARM64") + set(_cross_arch "VC-WIN64-ARM") + else() + set(_cross_arch "VC-WIN64A") + endif() elseif(APPLE) set(_cross_arch "darwin64-arm64-cc") endif() diff --git a/src/BaseException.cpp b/src/BaseException.cpp index 98406e44bd..ac0c91a46c 100644 --- a/src/BaseException.cpp +++ b/src/BaseException.cpp @@ -326,6 +326,13 @@ void CBaseException::ShowRegistorInformation(PCONTEXT pCtx) OutputString( _T("DS:%04X ES:%04X FS:%04X GS:%04X\r\n"), pCtx->SegDs, pCtx->SegEs, pCtx->SegFs, pCtx->SegGs ); OutputString( _T("Flags:%08X\r\n"), pCtx->EFlags ); +#elif defined(_M_ARM64) // Windows on ARM64 + OutputString(_T("\nRegisters:\r\n")); + OutputString(_T("PC:%016llX SP:%016llX FP:%016llX LR:%016llX\r\n"), + (unsigned long long)pCtx->Pc, (unsigned long long)pCtx->Sp, + (unsigned long long)pCtx->Fp, (unsigned long long)pCtx->Lr); + OutputString(_T("Cpsr:%08X\r\n"), pCtx->Cpsr); + #endif OutputString( _T("\r\n") ); @@ -349,7 +356,12 @@ void CBaseException::ShowExceptionInformation() OutputString(_T("Param %d :0x%x \n"), i, m_pEp->ExceptionRecord->ExceptionInformation[i]); } OutputString(_T("Context :%p \n"), m_pEp->ContextRecord); +#if defined(_M_ARM64) + // The ARM64 CONTEXT has no EFlags member; the status register is Cpsr. + OutputString(_T("ContextFlag : 0x%x, Cpsr: 0x%x \n"), m_pEp->ContextRecord->ContextFlags, m_pEp->ContextRecord->Cpsr); +#else OutputString(_T("ContextFlag : 0x%x, EFlags: 0x%x \n"), m_pEp->ContextRecord->ContextFlags, m_pEp->ContextRecord->EFlags); +#endif TCHAR szFaultingModule[MAX_PATH]; DWORD section, offset; diff --git a/src/StackWalker.cpp b/src/StackWalker.cpp index f625d23e73..6e5b7b39b1 100644 --- a/src/StackWalker.cpp +++ b/src/StackWalker.cpp @@ -457,6 +457,15 @@ LPSTACKINFO CStackWalker::StackWalker(HANDLE hThread, const CONTEXT* context) sf.AddrBStore.Mode = AddrModeFlat; sf.AddrStack.Offset = c.IntSp; sf.AddrStack.Mode = AddrModeFlat; + // ARM64 +#elif defined(_M_ARM64) + imageType = IMAGE_FILE_MACHINE_ARM64; + sf.AddrPC.Offset = c.Pc; + sf.AddrPC.Mode = AddrModeFlat; + sf.AddrFrame.Offset = c.Fp; + sf.AddrFrame.Mode = AddrModeFlat; + sf.AddrStack.Offset = c.Sp; + sf.AddrStack.Mode = AddrModeFlat; #else #error "Platform not supported!" #endif diff --git a/src/libslic3r/Int128.hpp b/src/libslic3r/Int128.hpp index 37d8443ffa..068dc4585a 100644 --- a/src/libslic3r/Int128.hpp +++ b/src/libslic3r/Int128.hpp @@ -59,7 +59,10 @@ #if defined(_MSC_VER) && defined(_WIN64) #include + // _mul128 exists only on x64; ARM64 MSVC uses __umulh (also from ). + #ifdef _M_X64 #pragma intrinsic(_mul128) + #endif #endif //------------------------------------------------------------------------------ From 45ebfda36603f1ef95bdfa160e9d37beccbfc604 Mon Sep 17 00:00:00 2001 From: Ryan Ewen Date: Fri, 17 Jul 2026 15:15:21 -0400 Subject: [PATCH 02/18] fix: detect ARM64 case-insensitively in OpenSSL/GLEW cmake build_win.bat passes -A arm64 (lowercase) while CI passes -A ARM64; CMake keeps CMAKE_GENERATOR_PLATFORM verbatim (no case normalization), so an uppercase-only STREQUAL/MATCHES check missed the local build_win.bat path. Match ARM64 case- insensitively and also honour CMAKE_SYSTEM_PROCESSOR on native ARM64 hosts, matching the pattern GMP/MPFR/OpenCV already use. --- cmake/modules/FindGLEW.cmake | 3 ++- deps/OpenSSL/OpenSSL.cmake | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/cmake/modules/FindGLEW.cmake b/cmake/modules/FindGLEW.cmake index 67ef60fb64..2c14733cb3 100644 --- a/cmake/modules/FindGLEW.cmake +++ b/cmake/modules/FindGLEW.cmake @@ -134,10 +134,11 @@ endif() if("${CMAKE_GENERATOR_PLATFORM}" MATCHES "x64" OR "${CMAKE_GENERATOR}" MATCHES "Win64") set(_arch "x64") -elseif("${CMAKE_GENERATOR_PLATFORM}" MATCHES "ARM64") +elseif("${CMAKE_GENERATOR_PLATFORM}" MATCHES "ARM64|arm64" OR CMAKE_SYSTEM_PROCESSOR MATCHES "^(ARM64|aarch64)$") # GLEW's binary distribution ships one 64-bit import-library layout; ARM64 # reuses the x64 lib/Release path. (Bambu builds GLEW from source into the # dep prefix, so this only affects the GLEW_ROOT binary-dist fallback.) + # Matched case-insensitively since build_win.bat passes -A arm64 (lowercase). set(_arch "x64") else() set(_arch "Win32") diff --git a/deps/OpenSSL/OpenSSL.cmake b/deps/OpenSSL/OpenSSL.cmake index 24a21955a2..b7e3cc2f91 100644 --- a/deps/OpenSSL/OpenSSL.cmake +++ b/deps/OpenSSL/OpenSSL.cmake @@ -6,7 +6,10 @@ if(DEFINED OPENSSL_ARCH) set(_cross_arch ${OPENSSL_ARCH}) else() if(WIN32) - if("${CMAKE_GENERATOR_PLATFORM}" STREQUAL "ARM64") + # Detect ARM64 whether the platform arrived as -A ARM64 (CI) or -A arm64 + # (build_win.bat lowercases it), and also honour the native host CPU. + string(TOUPPER "${CMAKE_GENERATOR_PLATFORM}" _win_gen_platform) + if(_win_gen_platform STREQUAL "ARM64" OR CMAKE_SYSTEM_PROCESSOR MATCHES "^(ARM64|aarch64)$") set(_cross_arch "VC-WIN64-ARM") else() set(_cross_arch "VC-WIN64A") From e7e1487ac06d6fae00fa6614083b387ab0cc59d7 Mon Sep 17 00:00:00 2001 From: Ryan Ewen Date: Fri, 17 Jul 2026 16:20:54 -0400 Subject: [PATCH 03/18] fix: alias libmpfr-4.lib on Windows ARM64 so CGAL FindMPFR succeeds The ARM64 dep prefix ships MPFR 4.x as libmpfr-6.lib, but CGAL's FindMPFR searches a fixed name list (mpfr, libmpfr-4, libmpfr-1) that predates the -6 ABI naming, so the app configure failed with 'Could NOT find MPFR' (observed on the windows-11-arm CI runner; GMP was found because libgmp-10 is in CGAL's FindGMP list). Install an aliased copy under the legacy libmpfr-4.lib name; an import library's filename does not affect runtime binding - it still references mpfr-6.dll internally, which is installed to bin/. --- deps/MPFR/MPFR.cmake | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/deps/MPFR/MPFR.cmake b/deps/MPFR/MPFR.cmake index f973802648..aaa5fb1a29 100644 --- a/deps/MPFR/MPFR.cmake +++ b/deps/MPFR/MPFR.cmake @@ -5,11 +5,18 @@ if (MSVC) if ((CMAKE_SYSTEM_PROCESSOR MATCHES "^(ARM64|aarch64)$") OR (CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64")) set(_output ${_dstdir}/include/mpfr.h ${_dstdir}/include/mpf2mpfr.h - ${_dstdir}/lib/libmpfr-6.lib + ${_dstdir}/lib/libmpfr-6.lib + ${_dstdir}/lib/libmpfr-4.lib ${_dstdir}/bin/mpfr-6.dll) set(_mpfrheader win_arm64) set(_mpfrlib win_arm64/libmpfr-6.lib) set(_mpfrdll win_arm64/mpfr-6.dll) + # CGAL's FindMPFR searches a fixed name list (mpfr, libmpfr-4, libmpfr-1) + # that predates the MPFR 4.x "-6" ABI naming, so it misses libmpfr-6.lib + # and the app configure fails with "Could NOT find MPFR". Install an + # aliased copy under the legacy name; the import library's filename does + # not affect runtime binding (it still references mpfr-6.dll internally). + set(_mpfrlib_alias ${_dstdir}/lib/libmpfr-4.lib) else () set(_output ${_dstdir}/include/mpfr.h ${_dstdir}/include/mpf2mpfr.h @@ -20,12 +27,18 @@ if (MSVC) set(_mpfrdll win${DEPS_BITS}/libmpfr-4.dll) endif () + set(_mpfr_alias_cmd "") + if (DEFINED _mpfrlib_alias) + set(_mpfr_alias_cmd COMMAND ${CMAKE_COMMAND} -E copy ${_srcdir}/lib/${_mpfrlib} ${_mpfrlib_alias}) + endif () + add_custom_command( OUTPUT ${_output} COMMAND ${CMAKE_COMMAND} -E copy ${_srcdir}/include/${_mpfrheader}/mpfr.h ${_dstdir}/include/ COMMAND ${CMAKE_COMMAND} -E copy ${_srcdir}/include/${_mpfrheader}/mpf2mpfr.h ${_dstdir}/include/ COMMAND ${CMAKE_COMMAND} -E copy ${_srcdir}/lib/${_mpfrlib} ${_dstdir}/lib/ COMMAND ${CMAKE_COMMAND} -E copy ${_srcdir}/lib/${_mpfrdll} ${_dstdir}/bin/ + ${_mpfr_alias_cmd} ) add_custom_target(dep_MPFR SOURCES ${_output}) From 18675a03d2160166c1e6b2f36d89cbb4cf477965 Mon Sep 17 00:00:00 2001 From: Ryan Ewen Date: Fri, 17 Jul 2026 16:42:34 -0400 Subject: [PATCH 04/18] fix: pin OpenCV_ARCH/OpenCV_RUNTIME for Windows ARM64 find_package OpenCVConfig.cmake's dispatcher matches CMAKE_GENERATOR_PLATFORM against 'ARM64' case-sensitively (build_win.bat passes lowercase arm64), and its MSVC_VERSION->runtime table predates VS2022 17.10+ (19.4x), so on ARM64 it computed ARCH=x64/RUNTIME=vc14 and failed with OpenCV_FOUND=FALSE despite the deps prefix containing ARM64/vc17/staticlib. The dispatcher only honours pre-set values when BOTH OpenCV_ARCH and OpenCV_RUNTIME are defined, so pin them together for any spelling of an ARM64 target. The existing >=1950 vc17 hint (x64/VS2026) is unchanged. --- src/libslic3r/CMakeLists.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index be7db427ff..9d7a93c63e 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -526,6 +526,22 @@ if(MSVC AND MSVC_VERSION GREATER_EQUAL 1950 AND NOT DEFINED OpenCV_RUNTIME) # explicitly here to match what find_package looks for. set(OpenCV_RUNTIME vc17) endif() +if(MSVC AND NOT DEFINED OpenCV_ARCH) + # OpenCVConfig.cmake's arch dispatcher matches CMAKE_GENERATOR_PLATFORM against + # "ARM64" case-sensitively, but build_win.bat passes -A arm64 (lowercase), so it + # falls back to x64 and misses the ARM64//staticlib install layout. + # Select the arch explicitly for any spelling of an ARM64 target. The dispatcher + # only honours pre-set values when BOTH OpenCV_ARCH and OpenCV_RUNTIME are + # defined, so pin the runtime too (our deps build installs the vc17 layout). + string(TOUPPER "${CMAKE_GENERATOR_PLATFORM}" _slic3r_gen_platform) + if(_slic3r_gen_platform STREQUAL "ARM64" OR CMAKE_SYSTEM_PROCESSOR MATCHES "^(ARM64|aarch64)$") + set(OpenCV_ARCH ARM64) + if(NOT DEFINED OpenCV_RUNTIME) + set(OpenCV_RUNTIME vc17) + endif() + endif() + unset(_slic3r_gen_platform) +endif() find_package(OpenCV REQUIRED core) find_package(assimp REQUIRED) cmake_policy(POP) From 874437ece1c26136d6b5864ea14551902d2b2040 Mon Sep 17 00:00:00 2001 From: Ryan Ewen Date: Fri, 17 Jul 2026 17:31:01 -0400 Subject: [PATCH 05/18] fix: use generic C minih264e path on MSVC ARM64 minih264e.h defined MINIH264_ONLY_SIMD for _M_ARM64 ('arm64 always have neon'), but its NEON implementation is only enabled for __ARM_NEON/__aarch64__ - GCC/Clang macros that MSVC never defines - so MSVC ARM64 fell through to '#error MINIH264_ONLY_SIMD used, but SSE/NEON not enabled'. Keep the portable C path available on MSVC ARM64; GCC/Clang arm64 (macOS) still uses NEON. --- src/minimp4/minih264e.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/minimp4/minih264e.h b/src/minimp4/minih264e.h index 7efd96c2ce..64a80b9bca 100644 --- a/src/minimp4/minih264e.h +++ b/src/minimp4/minih264e.h @@ -337,7 +337,11 @@ void H264E_set_vbv_state( #define MAX_LONG_TERM_FRAMES 8 // Max long-term frames count #endif -#if !defined(MINIH264_ONLY_SIMD) && (defined(_M_X64) || defined(_M_ARM64) || defined(__x86_64__) || defined(__aarch64__)) +/* Note: _M_ARM64 (MSVC on Windows ARM64) is deliberately NOT listed. The NEON + * implementation below is only enabled for __ARM_NEON/__aarch64__ (GCC/Clang + * macros that MSVC does not define), so MSVC ARM64 must keep the generic C + * path available or the MINIH264_ONLY_SIMD check below hits #error. */ +#if !defined(MINIH264_ONLY_SIMD) && (defined(_M_X64) || defined(__x86_64__) || defined(__aarch64__)) /* x64 always have SSE2, arm64 always have neon, no need for generic code */ #define MINIH264_ONLY_SIMD #endif /* SIMD checks... */ From e5b76d3f9a19e0ef9ad552764480eb72ac2c2fd7 Mon Sep 17 00:00:00 2001 From: Ryan Ewen Date: Fri, 17 Jul 2026 18:15:56 -0400 Subject: [PATCH 06/18] fix: use BtbN winarm64 FFmpeg prebuilt on Windows ARM64 bambulab's ffmpeg_prebuilts 7.0.2_msvc.zip contains x64-only import libs and DLLs; on ARM64 the link of BambuStudio.exe failed with unresolved av_*/sws_* externals from AVVideoDecoder.obj (the import libs are machine-type x64). Pin BtbN's FFmpeg-Builds winarm64 gpl-shared 7.1 autobuild instead: same bin/lib/include layout and identical library majors (avcodec-61, avutil-59, swscale-8), verified machine-type ARM64. x64 continues to use the bambulab package unchanged. --- deps/FFMPEG/FFMPEG.cmake | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/deps/FFMPEG/FFMPEG.cmake b/deps/FFMPEG/FFMPEG.cmake index aa1300be64..2152838069 100644 --- a/deps/FFMPEG/FFMPEG.cmake +++ b/deps/FFMPEG/FFMPEG.cmake @@ -1,11 +1,23 @@ set(_conf_cmd ./configure) if (MSVC) + # bambulab's ffmpeg_prebuilts are x64-only; linking them on ARM64 leaves + # every av*/sws* symbol unresolved. For Windows ARM64 use BtbN's winarm64 + # shared build (pinned autobuild tag). FFmpeg 7.0/7.1 share the same + # library majors (avcodec-61, avutil-59, swscale-8), so the layout and DLL + # names match what the x64 package ships and what the code links against. + set(_ffmpeg_msvc_url "https://github.com/bambulab/ffmpeg_prebuilts/releases/download/7.0.2/7.0.2_msvc.zip") + set(_ffmpeg_msvc_hash "SHA256=DF44AE6B97CE84C720695AE7F151B4A9654915D1841C68F10D62A1189E0E7181") + string(TOUPPER "${CMAKE_GENERATOR_PLATFORM}" _ffmpeg_gen_platform) + if (_ffmpeg_gen_platform STREQUAL "ARM64" OR CMAKE_SYSTEM_PROCESSOR MATCHES "^(ARM64|aarch64)$") + set(_ffmpeg_msvc_url "https://github.com/BtbN/FFmpeg-Builds/releases/download/autobuild-2026-07-17-13-22/ffmpeg-n7.1.5-2-g998de74adf-winarm64-gpl-shared-7.1.zip") + set(_ffmpeg_msvc_hash "SHA256=37e39b6f9115ec01a0ac6d7728e629e6be988d42495c850da4514930ad857f97") + endif () set(_dstdir ${DESTDIR}/usr/local) set(_source_dir "${CMAKE_BINARY_DIR}/dep_FFMPEG-prefix/src/dep_FFMPEG") ExternalProject_Add(dep_FFMPEG - URL https://github.com/bambulab/ffmpeg_prebuilts/releases/download/7.0.2/7.0.2_msvc.zip - URL_HASH SHA256=DF44AE6B97CE84C720695AE7F151B4A9654915D1841C68F10D62A1189E0E7181 + URL ${_ffmpeg_msvc_url} + URL_HASH ${_ffmpeg_msvc_hash} DOWNLOAD_DIR ${DEP_DOWNLOAD_DIR}/FFMPEG CONFIGURE_COMMAND "" BUILD_COMMAND "" From af6b48da450cbe81a80a38017e453dfbed638886 Mon Sep 17 00:00:00 2001 From: Ryan Ewen Date: Fri, 17 Jul 2026 22:01:16 -0400 Subject: [PATCH 07/18] fix: target-platform precedence in arch detection; ARM64EC groundwork Building x64 or ARM64EC targets on a native ARM64 host misrouted several arch checks: the CMAKE_SYSTEM_PROCESSOR fallback (host CPU) fired even when the generator platform (-A) said otherwise, staging ARM64 GMP/MPFR/FFmpeg blobs into x64 dep bundles and selecting ARM64 OpenCV/runtime-DLL layouts for non-ARM64 app targets. Give CMAKE_GENERATOR_PLATFORM precedence everywhere (GMP, MPFR, OpenSSL, FFMPEG, bambustudio_copy_dlls, libslic3r OpenCV hints), falling back to the host processor only when no platform is set. ARM64EC groundwork: deps-windows.cmake maps DEP_ARCH=ARM64EC to platform ARM64EC, and the libslic3r OpenCV hint selects the x64 dependency layout for ARM64EC app builds (EC links the x64 dep set; EC processes load x64 DLLs, which is what enables the closed-source x64 Bambu network plugin to work inside an otherwise-native ARM64 build). --- CMakeLists.txt | 10 +++++++++- deps/FFMPEG/FFMPEG.cmake | 10 ++++++++-- deps/GMP/GMP.cmake | 9 ++++++++- deps/MPFR/MPFR.cmake | 9 ++++++++- deps/OpenSSL/OpenSSL.cmake | 11 ++++++++--- deps/deps-windows.cmake | 5 +++++ src/libslic3r/CMakeLists.txt | 16 ++++++++++++++-- 7 files changed, 60 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e061482f61..fcc3750f64 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -636,7 +636,15 @@ function(bambustudio_copy_dlls target config postfix output_dlls) set(_bits 32) endif () - if ((CMAKE_SYSTEM_PROCESSOR MATCHES "^(ARM64|aarch64)$") OR (CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64")) + # Generator platform takes precedence over the host processor so an ARM64 + # host can build x64 or ARM64EC targets (both consume the x64 runtime DLLs; + # ARM64EC processes load x64 DLLs via emulation). + set(_copydll_plat "${CMAKE_GENERATOR_PLATFORM}") + if (NOT _copydll_plat) + set(_copydll_plat "${CMAKE_SYSTEM_PROCESSOR}") + endif () + string(TOUPPER "${_copydll_plat}" _copydll_plat) + if (_copydll_plat MATCHES "^(ARM64|AARCH64)$") set(_gmpdll win_arm64/gmp-10.dll) set(_mpfrdll win_arm64/mpfr-6.dll) set(output_gmpdll gmp-10.dll) diff --git a/deps/FFMPEG/FFMPEG.cmake b/deps/FFMPEG/FFMPEG.cmake index 2152838069..6c0f747611 100644 --- a/deps/FFMPEG/FFMPEG.cmake +++ b/deps/FFMPEG/FFMPEG.cmake @@ -8,8 +8,14 @@ if (MSVC) # names match what the x64 package ships and what the code links against. set(_ffmpeg_msvc_url "https://github.com/bambulab/ffmpeg_prebuilts/releases/download/7.0.2/7.0.2_msvc.zip") set(_ffmpeg_msvc_hash "SHA256=DF44AE6B97CE84C720695AE7F151B4A9654915D1841C68F10D62A1189E0E7181") - string(TOUPPER "${CMAKE_GENERATOR_PLATFORM}" _ffmpeg_gen_platform) - if (_ffmpeg_gen_platform STREQUAL "ARM64" OR CMAKE_SYSTEM_PROCESSOR MATCHES "^(ARM64|aarch64)$") + # Generator platform takes precedence over the host processor so an ARM64 + # host can still build x64 deps (and ARM64EC targets get the x64 package). + set(_ffmpeg_gen_platform "${CMAKE_GENERATOR_PLATFORM}") + if (NOT _ffmpeg_gen_platform) + set(_ffmpeg_gen_platform "${CMAKE_SYSTEM_PROCESSOR}") + endif () + string(TOUPPER "${_ffmpeg_gen_platform}" _ffmpeg_gen_platform) + if (_ffmpeg_gen_platform MATCHES "^(ARM64|AARCH64)$") set(_ffmpeg_msvc_url "https://github.com/BtbN/FFmpeg-Builds/releases/download/autobuild-2026-07-17-13-22/ffmpeg-n7.1.5-2-g998de74adf-winarm64-gpl-shared-7.1.zip") set(_ffmpeg_msvc_hash "SHA256=37e39b6f9115ec01a0ac6d7728e629e6be988d42495c850da4514930ad857f97") endif () diff --git a/deps/GMP/GMP.cmake b/deps/GMP/GMP.cmake index d7432743c0..9c59061a96 100644 --- a/deps/GMP/GMP.cmake +++ b/deps/GMP/GMP.cmake @@ -7,7 +7,14 @@ if (IN_GIT_REPO) endif () if (MSVC) - if ((CMAKE_SYSTEM_PROCESSOR MATCHES "^(ARM64|aarch64)$") OR (CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64")) + # Prefer the generator platform (-A ...) over the host processor so that an + # ARM64 host building an x64 (or ARM64EC) target stages the right blobs. + set(_gmp_plat "${CMAKE_GENERATOR_PLATFORM}") + if (NOT _gmp_plat) + set(_gmp_plat "${CMAKE_SYSTEM_PROCESSOR}") + endif () + string(TOUPPER "${_gmp_plat}" _gmp_plat) + if (_gmp_plat MATCHES "^(ARM64|AARCH64)$") set(_gmpheader win_arm64/gmp.h) set(_gmplib win_arm64/libgmp-10.lib) set(_gmpdll win_arm64/gmp-10.dll) diff --git a/deps/MPFR/MPFR.cmake b/deps/MPFR/MPFR.cmake index aaa5fb1a29..d2b6357667 100644 --- a/deps/MPFR/MPFR.cmake +++ b/deps/MPFR/MPFR.cmake @@ -2,7 +2,14 @@ set(_srcdir ${CMAKE_CURRENT_LIST_DIR}/mpfr) set(_dstdir ${DESTDIR}/usr/local) if (MSVC) - if ((CMAKE_SYSTEM_PROCESSOR MATCHES "^(ARM64|aarch64)$") OR (CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64")) + # Prefer the generator platform (-A ...) over the host processor so that an + # ARM64 host building an x64 (or ARM64EC) target stages the right blobs. + set(_mpfr_plat "${CMAKE_GENERATOR_PLATFORM}") + if (NOT _mpfr_plat) + set(_mpfr_plat "${CMAKE_SYSTEM_PROCESSOR}") + endif () + string(TOUPPER "${_mpfr_plat}" _mpfr_plat) + if (_mpfr_plat MATCHES "^(ARM64|AARCH64)$") set(_output ${_dstdir}/include/mpfr.h ${_dstdir}/include/mpf2mpfr.h ${_dstdir}/lib/libmpfr-6.lib diff --git a/deps/OpenSSL/OpenSSL.cmake b/deps/OpenSSL/OpenSSL.cmake index b7e3cc2f91..9dc9f34791 100644 --- a/deps/OpenSSL/OpenSSL.cmake +++ b/deps/OpenSSL/OpenSSL.cmake @@ -7,9 +7,14 @@ if(DEFINED OPENSSL_ARCH) else() if(WIN32) # Detect ARM64 whether the platform arrived as -A ARM64 (CI) or -A arm64 - # (build_win.bat lowercases it), and also honour the native host CPU. - string(TOUPPER "${CMAKE_GENERATOR_PLATFORM}" _win_gen_platform) - if(_win_gen_platform STREQUAL "ARM64" OR CMAKE_SYSTEM_PROCESSOR MATCHES "^(ARM64|aarch64)$") + # (build_win.bat lowercases it). The generator platform takes precedence + # over the host processor so an ARM64 host can still build x64 deps. + set(_win_target_plat "${CMAKE_GENERATOR_PLATFORM}") + if(NOT _win_target_plat) + set(_win_target_plat "${CMAKE_SYSTEM_PROCESSOR}") + endif() + string(TOUPPER "${_win_target_plat}" _win_target_plat) + if(_win_target_plat MATCHES "^(ARM64|AARCH64)$") set(_cross_arch "VC-WIN64-ARM") else() set(_cross_arch "VC-WIN64A") diff --git a/deps/deps-windows.cmake b/deps/deps-windows.cmake index a8165a900a..e28f43d967 100644 --- a/deps/deps-windows.cmake +++ b/deps/deps-windows.cmake @@ -52,6 +52,11 @@ else () if (DEP_ARCH STREQUAL "ARM64") set(DEP_PLATFORM "ARM64") + elseif (DEP_ARCH STREQUAL "ARM64EC") + # ARM64EC: native ARM64 code with an x64-compatible ABI, so an ARM64EC + # app can link these deps AND load x64-only DLLs (e.g. the Bambu + # network plugin) in-process. CMake-based deps build with -A ARM64EC. + set(DEP_PLATFORM "ARM64EC") else () set(DEP_PLATFORM "x64") endif () diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index 9d7a93c63e..82db9f5109 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -533,12 +533,24 @@ if(MSVC AND NOT DEFINED OpenCV_ARCH) # Select the arch explicitly for any spelling of an ARM64 target. The dispatcher # only honours pre-set values when BOTH OpenCV_ARCH and OpenCV_RUNTIME are # defined, so pin the runtime too (our deps build installs the vc17 layout). - string(TOUPPER "${CMAKE_GENERATOR_PLATFORM}" _slic3r_gen_platform) - if(_slic3r_gen_platform STREQUAL "ARM64" OR CMAKE_SYSTEM_PROCESSOR MATCHES "^(ARM64|aarch64)$") + set(_slic3r_gen_platform "${CMAKE_GENERATOR_PLATFORM}") + if(NOT _slic3r_gen_platform) + set(_slic3r_gen_platform "${CMAKE_SYSTEM_PROCESSOR}") + endif() + string(TOUPPER "${_slic3r_gen_platform}" _slic3r_gen_platform) + if(_slic3r_gen_platform MATCHES "^(ARM64|AARCH64)$") set(OpenCV_ARCH ARM64) if(NOT DEFINED OpenCV_RUNTIME) set(OpenCV_RUNTIME vc17) endif() + elseif(_slic3r_gen_platform STREQUAL "ARM64EC") + # ARM64EC links the x64 dependency set (EC and x64 code interoperate), + # so select the x64 OpenCV layout. MSVC 19.4x also falls in a gap in + # OpenCV 4.6's runtime table, so the runtime must be pinned here too. + set(OpenCV_ARCH x64) + if(NOT DEFINED OpenCV_RUNTIME) + set(OpenCV_RUNTIME vc17) + endif() endif() unset(_slic3r_gen_platform) endif() From fc468b9ced9bca8d998f325bc4880e14021caae3 Mon Sep 17 00:00:00 2001 From: Ryan Ewen Date: Fri, 17 Jul 2026 22:24:40 -0400 Subject: [PATCH 08/18] fix: pin Boost.Context target arch when building x64 deps on ARM64 host Boost 1.84's libs/context CMake derives its architecture from the host processor, so an -A x64 deps build on a Windows-on-ARM machine detected 'arm64 / armasm' and failed configure (armasm absent from the x64 toolchain env). Pass BOOST_CONTEXT_ARCHITECTURE=x86_64 explicitly for X64 targets, and use the assembler-free winfib implementation for ARM64EC targets. --- deps/Boost/Boost.cmake | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/deps/Boost/Boost.cmake b/deps/Boost/Boost.cmake index bc66a6b741..34ae84346d 100644 --- a/deps/Boost/Boost.cmake +++ b/deps/Boost/Boost.cmake @@ -29,6 +29,18 @@ if (MSVC) set(_context_arch_line "-DBOOST_CONTEXT_ARCHITECTURE:STRING=arm64") set(_context_impl_line "-DBOOST_CONTEXT_IMPLEMENTATION:STRING=winfib") message(STATUS "BOOST param: ${_context_abi_line} ${_context_arch_line} ${_context_impl_line}") + elseif (_msvc_target_arch STREQUAL "ARM64EC") + # ARM64EC uses the x64-compatible ABI; the Windows Fiber implementation + # needs no assembler, sidestepping fcontext arch detection entirely. + set(_context_impl_line "-DBOOST_CONTEXT_IMPLEMENTATION:STRING=winfib") + message(STATUS "BOOST param: ${_context_impl_line}") + elseif (_msvc_target_arch STREQUAL "X64") + # Pin arch AND abi: Boost.Context otherwise sniffs the HOST processor, + # so building x64 deps on an ARM64 host selects armasm/aapcs and fails + # (x86_64 + aapcs has no asm source; the x64 Windows ABI is 'ms'). + set(_context_abi_line "-DBOOST_CONTEXT_ABI:STRING=ms") + set(_context_arch_line "-DBOOST_CONTEXT_ARCHITECTURE:STRING=x86_64") + message(STATUS "BOOST param: ${_context_abi_line} ${_context_arch_line}") endif () endif () From 7dc3d66f53cccf4ca8ae2bf65d4348f50b176011 Mon Sep 17 00:00:00 2001 From: Ryan Ewen Date: Fri, 17 Jul 2026 23:03:58 -0400 Subject: [PATCH 09/18] fix: force-include intrin.h for ARM64EC builds On ARM64EC the x86 SIMD headers (immintrin.h and friends) error out unless included via , which sets up the softintrin emulation layer first. Several bundled libraries (eigen, imgui, clipper2, tinybvh, libigl, minih264) include them directly, so add /FIintrin.h globally for ARM64EC instead of patching each library. --- CMakeLists.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index fcc3750f64..27a97f464a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,6 +84,15 @@ elseif (MSVC) message(STATUS " is cross compile set to true.............") set(IS_CROSS_COMPILE TRUE) endif () + if (CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64EC") + # On ARM64EC the x86 SIMD headers (immintrin.h etc.) refuse direct + # inclusion - they must come via so the softintrin + # emulation layer is set up first. Several bundled libraries + # (eigen, imgui, clipper2, tinybvh, libigl, minih264) include them + # directly, so force-include intrin.h globally instead of patching + # each one. + add_compile_options(/FIintrin.h) + endif () endif () # Proposal for C++ unit tests and sandboxes From b620a213ad1d9f6d38db48643f831170833319e5 Mon Sep 17 00:00:00 2001 From: Ryan Ewen Date: Sat, 18 Jul 2026 00:46:34 -0400 Subject: [PATCH 10/18] fix: link softintrin.lib for ARM64EC builds Some x86 intrinsics used by bundled code (e.g. _mm_cvtsd_si64 in Clipper2) have no native ARM64EC lowering and compile to calls into the softintrin software-emulation library. MSBuild adds it for its own project types but not for CMake-generated ones, leaving unresolved '(EC Symbol)' externals at link. --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 27a97f464a..6fd6686650 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -92,6 +92,10 @@ elseif (MSVC) # directly, so force-include intrin.h globally instead of patching # each one. add_compile_options(/FIintrin.h) + # Software implementations of x86 intrinsics that have no native + # ARM64EC lowering (e.g. _mm_cvtsd_si64). MSBuild does not add this + # automatically for CMake-generated projects. + add_link_options(softintrin.lib) endif () endif () From 8f0b1c3614a12b7af1e65627d05f5b5c5ab53db6 Mon Sep 17 00:00:00 2001 From: Ryan Ewen Date: Sat, 18 Jul 2026 01:46:42 -0400 Subject: [PATCH 11/18] fix: use standard C math fallback in Clipper2 on ARM64EC clipper.engine.cpp swaps fmin/fmax/nearbyint for SSE2 intrinsics whenever _M_X64 is defined, but ARM64EC (which also defines _M_X64) has no native lowering for _mm_cvtsd_si64 and softintrin.lib provides no fallback, leaving an unresolved '(EC Symbol)' external. The standard functions compile to native ARM64 rounding/min/max instructions on EC, so exclude it there. --- src/clipper2/Clipper2Lib/src/clipper.engine.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/clipper2/Clipper2Lib/src/clipper.engine.cpp b/src/clipper2/Clipper2Lib/src/clipper.engine.cpp index fd77bda7bb..7dc04470a5 100644 --- a/src/clipper2/Clipper2Lib/src/clipper.engine.cpp +++ b/src/clipper2/Clipper2Lib/src/clipper.engine.cpp @@ -13,7 +13,10 @@ // https://github.com/AngusJohnson/Clipper2/discussions/334 // #discussioncomment-4248602 -#if defined(_MSC_VER) && ( defined(_M_AMD64) || defined(_M_X64) ) +// ARM64EC defines _M_X64 but _mm_cvtsd_si64 has neither a native EC lowering +// nor a softintrin fallback; the standard C functions compile to native ARM64 +// rounding/min/max instructions there anyway. +#if defined(_MSC_VER) && ( defined(_M_AMD64) || defined(_M_X64) ) && !defined(_M_ARM64EC) #include #include #define fmin(a,b) _mm_cvtsd_f64(_mm_min_sd(_mm_set_sd(a),_mm_set_sd(b))) From b709796c12a796216f3d25be12793f35e393283b Mon Sep 17 00:00:00 2001 From: Ryan Ewen Date: Sat, 18 Jul 2026 10:14:13 -0400 Subject: [PATCH 12/18] fix: patch oneTBB for ARM64EC (drop /GL, guard TSX intrinsics) oneTBB 2021.5 hard-codes /GL for MSVC release builds; x64 LTCG objects cannot participate in an ARM64EC link (C1905). It also assumes TSX transactional- memory intrinsics exist whenever _M_X64 is defined, but ARM64EC defines _M_X64 and softintrin cannot emulate _xbegin/_xend/_xabort, so they fail to link when TBB itself is compiled as ARM64EC. Apply both fixes via an idempotent PATCH_COMMAND script (the version knobs for these arrived in later oneTBB releases). --- deps/TBB/TBB.cmake | 6 ++++- deps/TBB/patch_tbb.cmake | 49 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 deps/TBB/patch_tbb.cmake diff --git a/deps/TBB/TBB.cmake b/deps/TBB/TBB.cmake index ba6c7c588a..2f82ce5d6d 100644 --- a/deps/TBB/TBB.cmake +++ b/deps/TBB/TBB.cmake @@ -3,7 +3,11 @@ bambustudio_add_cmake_project( URL "https://github.com/oneapi-src/oneTBB/archive/refs/tags/v2021.5.0.zip" URL_HASH SHA256=83ea786c964a384dd72534f9854b419716f412f9d43c0be88d41874763e7bb47 #PATCH_COMMAND ${PATCH_CMD} ${CMAKE_CURRENT_LIST_DIR}/0001-TBB-GCC13.patch - CMAKE_ARGS + # Removes the hard-coded /GL (blocks ARM64EC links) and guards TSX + # intrinsics against ARM64EC. Both no-ops for other targets' behaviour: + # dropping LTCG slightly reduces x64 optimization but keeps the same code. + PATCH_COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_LIST_DIR}/patch_tbb.cmake + CMAKE_ARGS -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -DTBB_BUILD_SHARED=OFF -DTBB_BUILD_TESTS=OFF diff --git a/deps/TBB/patch_tbb.cmake b/deps/TBB/patch_tbb.cmake new file mode 100644 index 0000000000..65c23e522a --- /dev/null +++ b/deps/TBB/patch_tbb.cmake @@ -0,0 +1,49 @@ +# Applied as PATCH_COMMAND for oneTBB. Two fixes, both idempotent: +# +# 1. Remove the hard-coded /GL (LTCG) from the MSVC release flags. oneTBB +# 2021.5 has no option for this (TBB_ENABLE_IPO came later). x64 LTCG +# objects cannot participate in an ARM64EC link (C1905 front end/back end +# mismatch), and this static lib is consumed by the ARM64EC BambuStudio +# build. +# +# 2. Guard the TSX (hardware transactional memory) intrinsics against +# ARM64EC. ARM64EC defines _M_X64, so TBB assumes _xbegin/_xend/_xabort +# exist, but softintrin cannot emulate hardware transactions and the +# symbols fail to link. + +set(_msvc_cmake "cmake/compilers/MSVC.cmake") +if(EXISTS "${_msvc_cmake}") + file(READ "${_msvc_cmake}" _content) + set(_old "set(TBB_IPO_COMPILE_FLAGS $<$>:/GL>)") + if(_content MATCHES "TBB_IPO_COMPILE_FLAGS \"\"") + message(STATUS "[TBB patch] /GL already removed") + else() + string(REPLACE "${_old}" "set(TBB_IPO_COMPILE_FLAGS \"\")" _patched "${_content}") + if(_patched STREQUAL _content) + message(FATAL_ERROR "[TBB patch] failed to match /GL line in ${_msvc_cmake}") + endif() + file(WRITE "${_msvc_cmake}" "${_patched}") + message(STATUS "[TBB patch] removed /GL from MSVC release flags") + endif() +else() + message(FATAL_ERROR "[TBB patch] not found: ${_msvc_cmake}") +endif() + +set(_config_h "include/oneapi/tbb/detail/_config.h") +if(EXISTS "${_config_h}") + file(READ "${_config_h}" _content) + set(_old "#define __TBB_TSX_INTRINSICS_PRESENT (__RTM__ || __INTEL_COMPILER || (_MSC_VER>=1700 && (__TBB_x86_64 || __TBB_x86_32)))") + set(_new "#define __TBB_TSX_INTRINSICS_PRESENT ((__RTM__ || __INTEL_COMPILER || (_MSC_VER>=1700 && (__TBB_x86_64 || __TBB_x86_32))) && !defined(_M_ARM64EC))") + if(_content MATCHES "_M_ARM64EC") + message(STATUS "[TBB patch] TSX guard already applied") + else() + string(REPLACE "${_old}" "${_new}" _patched "${_content}") + if(_patched STREQUAL _content) + message(FATAL_ERROR "[TBB patch] failed to match TSX guard in ${_config_h}") + endif() + file(WRITE "${_config_h}" "${_patched}") + message(STATUS "[TBB patch] guarded TSX intrinsics against ARM64EC") + endif() +else() + message(FATAL_ERROR "[TBB patch] not found: ${_config_h}") +endif() From 81373756fae8ec61147bc11bc56fe2326e9f8e13 Mon Sep 17 00:00:00 2001 From: Ryan Ewen Date: Sat, 18 Jul 2026 12:41:43 -0400 Subject: [PATCH 13/18] fix: Ninja-generator debug info: /Z7 for debug configs only The unconditional /Zi makes every target's compiles share a per-target .pdb; under Ninja's parallelism that fails with C1041 (the VS generator serializes PDB access via /FS+mspdbsrv, Ninja does not) and defeats compiler-launcher caches like sccache. Use /Z7 (debug info embedded in objects; the linker still emits the final .pdb) and only for RelWithDebInfo/Debug: embedding into every object of a Release build pushes libslic3r_gui.lib past the 4 GB .lib format limit (LNK1248), and plain Release omits debug info under standard CMake semantics anyway. VS-generator builds keep /Zi unchanged. --- CMakeLists.txt | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6fd6686650..e4cc40eb08 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -145,7 +145,19 @@ if (MSVC) # /bigobj (Increase Number of Sections in .Obj file) # error C3859: virtual memory range for PCH exceeded; please recompile with a command line option of '-Zm90' or greater # Generate symbols at every build target, even for the release. - add_compile_options(-bigobj -Zm520 /Zi) + if (CMAKE_GENERATOR MATCHES "Ninja") + # /Z7 embeds debug info in the objects instead of writing per-target + # .pdb files during compilation: /Zi's shared-PDB writes fail with + # C1041 under Ninja's parallelism (the VS generator serializes them + # via /FS+mspdbsrv) and defeat compiler-launcher caches like sccache. + # Only debug-carrying configs get it - embedding into every object of + # a Release build pushes libslic3r_gui.lib past the 4 GB .lib format + # limit (LNK1248), and plain Release omits debug info in standard + # CMake semantics anyway. + add_compile_options(-bigobj -Zm520 "$<$,$>:/Z7>") + else () + add_compile_options(-bigobj -Zm520 /Zi) + endif () # Disable STL4007: Many result_type typedefs and all argument_type, first_argument_type, and second_argument_type typedefs are deprecated in C++17. #FIXME Remove this line after eigen library adapts to the new C++17 adaptor rules. add_compile_options(-D_SILENCE_CXX17_ADAPTOR_TYPEDEFS_DEPRECATION_WARNING) From a2c6b1cdf24e74f347ae9fde773d4abd7aeb7bde Mon Sep 17 00:00:00 2001 From: Ryan Ewen Date: Sat, 18 Jul 2026 14:43:25 -0400 Subject: [PATCH 14/18] feat: in-repo ARM64EC dependency bundle support Configuring deps with -A ARM64EC now produces an EC bundle without manual steps: deps-windows.cmake injects the EC compile flags into every CMake-based dep (restating the MSVC defaults - CMAKE_ARGS replaces rather than appends - plus /FIintrin.h for direct x86-SIMD-header includes and /wd4996 /wd4005 for the define-before-include idiom /FI breaks); Boost excludes json/cobalt on EC (ryu needs __shiftright128, which has no EC lowering); TBB gains a link-time TSX stub TU (rtm code calls _xbegin unconditionally but is unreachable under emulation); OpenSSL builds its x64 flavor under the x64 cross environment via a generated wrapper (x64 static libs link into EC images); OpenCV treats EC like arm64 (no IPP); JPEG disables SIMD deterministically. Binary-only deps (GMP/MPFR/FFmpeg) keep their x64 artifacts, which EC processes load natively through the emulation layer. --- deps/Boost/Boost.cmake | 6 +++++- deps/JPEG/JPEG.cmake | 9 ++++++++- deps/OpenCV/OpenCV.cmake | 6 ++++++ deps/OpenSSL/OpenSSL.cmake | 23 +++++++++++++++++++++++ deps/TBB/patch_tbb.cmake | 37 +++++++++++++++++++++++++++++++++++++ deps/deps-windows.cmake | 14 ++++++++++++++ 6 files changed, 93 insertions(+), 2 deletions(-) diff --git a/deps/Boost/Boost.cmake b/deps/Boost/Boost.cmake index 34ae84346d..0f870d55f1 100644 --- a/deps/Boost/Boost.cmake +++ b/deps/Boost/Boost.cmake @@ -33,6 +33,10 @@ if (MSVC) # ARM64EC uses the x64-compatible ABI; the Windows Fiber implementation # needs no assembler, sidestepping fcontext arch detection entirely. set(_context_impl_line "-DBOOST_CONTEXT_IMPLEMENTATION:STRING=winfib") + # Boost.JSON's ryu needs __shiftright128, which ARM64EC lacks (no + # native lowering, no softintrin fallback); cobalt is in the same + # C++20-era boat. Neither is used by BambuStudio. + set(_boost_ec_extra_excludes "|json|cobalt") message(STATUS "BOOST param: ${_context_impl_line}") elseif (_msvc_target_arch STREQUAL "X64") # Pin arch AND abi: Boost.Context otherwise sniffs the HOST processor, @@ -50,7 +54,7 @@ bambustudio_add_cmake_project(Boost LIST_SEPARATOR | PATCH_COMMAND git apply --verbose --ignore-space-change --whitespace=fix ${CMAKE_CURRENT_LIST_DIR}/0001-FIX-OBS-cannot-start-streaming-on-MAC.patch CMAKE_ARGS - -DBOOST_EXCLUDE_LIBRARIES:STRING=contract|fiber|numpy|wave|test + -DBOOST_EXCLUDE_LIBRARIES:STRING=contract|fiber|numpy|wave|test${_boost_ec_extra_excludes} -DBOOST_LOCALE_ENABLE_ICU:BOOL=OFF # do not link to libicu, breaks compatibility between distros -DBUILD_TESTING:BOOL=OFF "${_context_abi_line}" diff --git a/deps/JPEG/JPEG.cmake b/deps/JPEG/JPEG.cmake index 1e654e9e91..e89b303e58 100644 --- a/deps/JPEG/JPEG.cmake +++ b/deps/JPEG/JPEG.cmake @@ -12,7 +12,14 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux") endif() if (MSVC) - if ((CMAKE_SYSTEM_PROCESSOR MATCHES "^(ARM64|aarch64)$") OR (CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64")) + # Generator platform takes precedence over the host processor; SIMD is off + # for ARM64 (no x86 asm) and ARM64EC (deterministic pure-C build). + set(_jpeg_plat "${CMAKE_GENERATOR_PLATFORM}") + if (NOT _jpeg_plat) + set(_jpeg_plat "${CMAKE_SYSTEM_PROCESSOR}") + endif () + string(TOUPPER "${_jpeg_plat}" _jpeg_plat) + if (_jpeg_plat MATCHES "^(ARM64|AARCH64|ARM64EC)$") set(_use_SIMD "-DWITH_SIMD=OFF") endif () endif () diff --git a/deps/OpenCV/OpenCV.cmake b/deps/OpenCV/OpenCV.cmake index 7bd0d895e7..3b19e82685 100644 --- a/deps/OpenCV/OpenCV.cmake +++ b/deps/OpenCV/OpenCV.cmake @@ -15,6 +15,12 @@ if (MSVC) if (_msvc_target_arch STREQUAL "ARM64" OR _msvc_target_arch STREQUAL "AARCH64") set(_is_arm64 TRUE) endif () + if (_msvc_target_arch STREQUAL "ARM64EC") + # Intel IPP has no ARM64EC-linkable distribution (prebuilt x64 IPP + # members fail to resolve in an EC link), and softintrin'd SSE dispatch + # would be slower than plain C++ compiled native - treat like arm64. + set(_is_arm64 TRUE) + endif () else () if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(ARM64|aarch64)$") set(_is_arm64 TRUE) diff --git a/deps/OpenSSL/OpenSSL.cmake b/deps/OpenSSL/OpenSSL.cmake index 9dc9f34791..85a5c94820 100644 --- a/deps/OpenSSL/OpenSSL.cmake +++ b/deps/OpenSSL/OpenSSL.cmake @@ -29,6 +29,29 @@ if(WIN32) set(_cross_comp_prefix_line "") set(_make_cmd nmake) set(_install_cmd nmake install_sw ) + if(_win_target_plat STREQUAL "ARM64EC") + # ARM64EC links the x64 OpenSSL static libs (EC and x64 objects mix), + # but VC-WIN64A requires an x64-targeting cl. The deps environment + # targets arm64, so run the OpenSSL steps under the x64 cross tools + # via a generated wrapper batch file. + set(_vsdevcmd "$ENV{VSINSTALLDIR}Common7\\Tools\\vsdevcmd.bat") + if(NOT EXISTS "${_vsdevcmd}") + execute_process( + COMMAND "$ENV{ProgramFiles\(x86\)}\\Microsoft Visual Studio\\Installer\\vswhere.exe" + -latest -products * -property installationPath + OUTPUT_VARIABLE _vs_root OUTPUT_STRIP_TRAILING_WHITESPACE) + set(_vsdevcmd "${_vs_root}\\Common7\\Tools\\vsdevcmd.bat") + endif() + if(NOT EXISTS "${_vsdevcmd}") + message(FATAL_ERROR "OpenSSL ARM64EC: cannot locate vsdevcmd.bat for the x64 cross environment") + endif() + set(_x64env_bat "${CMAKE_CURRENT_BINARY_DIR}/openssl_x64env.bat") + file(WRITE "${_x64env_bat}" "@echo off\r\ncall \"${_vsdevcmd}\" -arch=x64 -host_arch=arm64 -no_logo\r\n%*\r\n") + set(_cross_arch "VC-WIN64A") + set(_conf_cmd "${_x64env_bat}" perl Configure ) + set(_make_cmd "${_x64env_bat}" nmake) + set(_install_cmd "${_x64env_bat}" nmake install_sw ) + endif() else() if(APPLE) set(_conf_cmd export MACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET} && ./Configure -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET} ) diff --git a/deps/TBB/patch_tbb.cmake b/deps/TBB/patch_tbb.cmake index 65c23e522a..0dc2ba9598 100644 --- a/deps/TBB/patch_tbb.cmake +++ b/deps/TBB/patch_tbb.cmake @@ -29,6 +29,43 @@ else() message(FATAL_ERROR "[TBB patch] not found: ${_msvc_cmake}") endif() +# 3. Provide link-time definitions of the TSX intrinsics for ARM64EC builds. +# rtm_mutex.cpp/rtm_rw_mutex.cpp call _xbegin/_xend/_xabort unconditionally; +# on ARM64EC those lower to extern calls with no softintrin implementation. +# The code paths are unreachable at runtime (the governor only enables RTM +# when CPUID reports TSX, which the x64 emulator never does), but the +# symbols must resolve. A separate stub TU avoids touching the RTM sources. +set(_stub "src/tbb/arm64ec_tsx_stub.cpp") +set(_tbb_cml "src/tbb/CMakeLists.txt") +if(NOT EXISTS "${_stub}") + file(WRITE "${_stub}" [=[ +// Link-time stubs for Intel TSX intrinsics on ARM64EC (no hardware TSX, no +// softintrin fallback). Unreachable at runtime: TBB only takes RTM paths when +// CPUID reports TSX support, which the x64/EC emulator never does. +#if defined(_M_ARM64EC) +extern "C" unsigned int _xbegin(void) { return 0u; /* abort, no retry */ } +extern "C" void _xend(void) {} +extern "C" void _xabort(unsigned int) {} +#endif +]=]) + message(STATUS "[TBB patch] wrote ${_stub}") +endif() +if(EXISTS "${_tbb_cml}") + file(READ "${_tbb_cml}" _content) + if(_content MATCHES "arm64ec_tsx_stub") + message(STATUS "[TBB patch] stub already registered") + else() + string(REPLACE "rtm_mutex.cpp" "rtm_mutex.cpp\n arm64ec_tsx_stub.cpp" _patched "${_content}") + if(_patched STREQUAL _content) + message(FATAL_ERROR "[TBB patch] failed to register stub in ${_tbb_cml}") + endif() + file(WRITE "${_tbb_cml}" "${_patched}") + message(STATUS "[TBB patch] registered arm64ec_tsx_stub.cpp") + endif() +else() + message(FATAL_ERROR "[TBB patch] not found: ${_tbb_cml}") +endif() + set(_config_h "include/oneapi/tbb/detail/_config.h") if(EXISTS "${_config_h}") file(READ "${_config_h}" _content) diff --git a/deps/deps-windows.cmake b/deps/deps-windows.cmake index e28f43d967..39b270dfba 100644 --- a/deps/deps-windows.cmake +++ b/deps/deps-windows.cmake @@ -66,6 +66,20 @@ set(DEP_CMAKE_OPTS "-DCMAKE_POLICY_VERSION_MINIMUM=3.5") if (DEP_PLATFORM STREQUAL "ARM64") list(APPEND DEP_CMAKE_OPTS "-DCMAKE_SYSTEM_PROCESSOR=ARM64") endif () +if (DEP_PLATFORM STREQUAL "ARM64EC") + # ARM64EC defines _M_X64, and the x86 SIMD headers (emmintrin.h etc.) + # refuse direct inclusion there - they must arrive via so the + # softintrin emulation layer is set up first; /FIintrin.h forces that for + # third-party code that includes them directly. /FI in turn breaks the + # common "#define _CRT_SECURE_NO_WARNINGS before includes" idiom (the CRT + # headers are already in), so silence C4996/C4005 which several deps + # (boost.nowide among them) promote to errors. The flag strings must + # restate CMake's default MSVC flags: CMAKE_ARGS replaces, not appends, + # and losing /EHsc breaks any dep that requires exception handling. + list(APPEND DEP_CMAKE_OPTS + "-DCMAKE_C_FLAGS=/DWIN32 /D_WINDOWS /W3 /wd4996 /wd4005 /FIintrin.h" + "-DCMAKE_CXX_FLAGS=/DWIN32 /D_WINDOWS /W3 /GR /EHsc /wd4996 /wd4005 /FIintrin.h") +endif () if (${DEP_DEBUG}) set(DEP_BOOST_DEBUG "debug") From a4d0ed628a69d7b6554644cc0eaf1a81256ea436 Mon Sep 17 00:00:00 2001 From: Ryan Ewen Date: Sat, 18 Jul 2026 14:46:25 -0400 Subject: [PATCH 15/18] ci: build and publish the Windows ARM64EC variant Adds {os: windows-11-arm, arch: arm64ec} to the matrix. The two Windows-on-ARM variants share a runner label, so the deps cache key now includes the arch (one-time cache rebuild for existing arm64 keys). The deps and app steps are parameterized to pass -A ARM64EC for the new variant, and artifacts are suffixed with the arch (BambuStudio_Windows__arm64ec_portable.zip). The arm64ec build is the fully-featured one: native ARM64 code with the x64-compatible ABI, able to load Bambu's closed x64 network plugin in-process (cloud login, device management, camera). The pure arm64 build remains for comparison and as the maximum-native variant. --- .github/workflows/build_all.yml | 2 ++ .github/workflows/build_bambu.yml | 19 +++++++++++-------- .github/workflows/build_check_cache.yml | 5 ++++- .github/workflows/build_deps.yml | 24 ++++++++++++++---------- 4 files changed, 31 insertions(+), 19 deletions(-) diff --git a/.github/workflows/build_all.yml b/.github/workflows/build_all.yml index 023bf839d6..f64b3ee650 100644 --- a/.github/workflows/build_all.yml +++ b/.github/workflows/build_all.yml @@ -49,6 +49,8 @@ jobs: - os: windows-latest - os: windows-11-arm arch: arm64 + - os: windows-11-arm + arch: arm64ec - os: macos-15-intel arch: x86_64 - os: macos-15 diff --git a/.github/workflows/build_bambu.yml b/.github/workflows/build_bambu.yml index fe2ee392f5..ed3c5e6b6d 100644 --- a/.github/workflows/build_bambu.yml +++ b/.github/workflows/build_bambu.yml @@ -133,10 +133,12 @@ jobs: cmake .. -G "Visual Studio 18 2026" -A X64 -DBBL_RELEASE_TO_PUBLIC=1 -DBBL_INTERNAL_TESTING=0 -DCMAKE_PREFIX_PATH="${{ github.workspace }}\deps\build\BambuStudio_dep\usr\local" -DCMAKE_INSTALL_PREFIX="../install-dir" -DCMAKE_BUILD_TYPE=Release -DWIN10SDK_PATH="C:/Program Files (x86)/Windows Kits/10/Include/10.0.22000.0" cmake --build . --target install --config Release -- -m - # Windows on ARM64: VS 2022 generator (the arm runner has no VS 2026), and - # the newest installed 10.* SDK is resolved at runtime rather than pinned, - # since the arm image may not ship the exact SDK the x64 job hard-codes. - - name: Build slicer Win ARM64 + # Windows on ARM64/ARM64EC: VS 2022 generator (the arm runner has no VS + # 2026), and the newest installed 10.* SDK is resolved at runtime rather + # than pinned, since the arm image may not ship the exact SDK the x64 job + # hard-codes. arm64ec produces the variant that can load the x64-only + # Bambu network plugin in-process at native speed. + - name: Build slicer Win ARM64/ARM64EC if: inputs.os == 'windows-11-arm' working-directory: ${{ github.workspace }} shell: pwsh @@ -144,9 +146,10 @@ jobs: $sdkRoot = "C:/Program Files (x86)/Windows Kits/10/Include" $sdk = (Get-ChildItem $sdkRoot -Directory | Where-Object { $_.Name -match '^10\.' } | Sort-Object Name -Descending | Select-Object -First 1).FullName Write-Output "Using Windows SDK: $sdk" + $platform = "${{ inputs.arch }}" -eq "arm64ec" ? "ARM64EC" : "ARM64" mkdir build cd build - cmake .. -G "Visual Studio 17 2022" -A ARM64 -DBBL_RELEASE_TO_PUBLIC=1 -DBBL_INTERNAL_TESTING=0 -DCMAKE_PREFIX_PATH="${{ github.workspace }}\deps\build\BambuStudio_dep\usr\local" -DCMAKE_INSTALL_PREFIX="../install-dir" -DCMAKE_BUILD_TYPE=Release -DWIN10SDK_PATH="$sdk" + cmake .. -G "Visual Studio 17 2022" -A $platform -DBBL_RELEASE_TO_PUBLIC=1 -DBBL_INTERNAL_TESTING=0 -DCMAKE_PREFIX_PATH="${{ github.workspace }}\deps\build\BambuStudio_dep\usr\local" -DCMAKE_INSTALL_PREFIX="../install-dir" -DCMAKE_BUILD_TYPE=Release -DWIN10SDK_PATH="$sdk" cmake --build . --target install --config Release -- -m # - name: Create installer Win @@ -165,7 +168,7 @@ jobs: if: inputs.os == 'windows-11-arm' working-directory: ${{ github.workspace }} shell: cmd - run: '"C:/Program Files/7-Zip/7z.exe" a -tzip BambuStudio_Windows_${{ env.ver }}_arm64_portable.zip ${{ github.workspace }}/install-dir' + run: '"C:/Program Files/7-Zip/7z.exe" a -tzip BambuStudio_Windows_${{ env.ver }}_${{ inputs.arch }}_portable.zip ${{ github.workspace }}/install-dir' # - name: Pack PDB # if: inputs.os == 'windows-latest' @@ -184,8 +187,8 @@ jobs: if: inputs.os == 'windows-11-arm' uses: actions/upload-artifact@v6 with: - name: BambuStudio_Windows_${{ env.ver }}_arm64_portable - path: ${{ github.workspace }}/BambuStudio_Windows_${{ env.ver }}_arm64_portable.zip + name: BambuStudio_Windows_${{ env.ver }}_${{ inputs.arch }}_portable + path: ${{ github.workspace }}/BambuStudio_Windows_${{ env.ver }}_${{ inputs.arch }}_portable.zip # Ubuntu diff --git a/.github/workflows/build_check_cache.yml b/.github/workflows/build_check_cache.yml index 0d5ff3bd28..cb24d989eb 100644 --- a/.github/workflows/build_check_cache.yml +++ b/.github/workflows/build_check_cache.yml @@ -32,8 +32,11 @@ jobs: env: dep-folder-name: ${{ startsWith(inputs.os, 'windows') && '/BambuStudio_dep' || ((inputs.os == 'macos-15-intel' || inputs.os == 'macos-15' || inputs.os == 'macos-26') && '') || (inputs.os != 'macos-15-intel' && inputs.os != 'macos-15' && inputs.os != 'macos-26') && '/destdir' || '' }} output-cmd: ${{ startsWith(inputs.os, 'windows') && '$env:GITHUB_OUTPUT' || '"$GITHUB_OUTPUT"'}} + # Windows runs two variants (arm64/arm64ec) on the same runner label, + # so the arch must be part of the key or their caches collide. + arch-suffix: ${{ (startsWith(inputs.os, 'windows') && inputs.arch != '') && format('-{0}', inputs.arch) || '' }} run: | - echo cache-key=${{ inputs.os }}-cache-bambustudio_deps-build-${{ hashFiles('deps/**') }} >> ${{ env.output-cmd }} + echo cache-key=${{ inputs.os }}${{ env.arch-suffix }}-cache-bambustudio_deps-build-${{ hashFiles('deps/**') }} >> ${{ env.output-cmd }} echo cache-path=${{ github.workspace }}/deps/build${{ env.dep-folder-name }} >> ${{ env.output-cmd }} - name: load cache diff --git a/.github/workflows/build_deps.yml b/.github/workflows/build_deps.yml index b614d93c16..b0f34107f2 100644 --- a/.github/workflows/build_deps.yml +++ b/.github/workflows/build_deps.yml @@ -75,11 +75,13 @@ jobs: run: Compress-Archive -Path "${{ github.workspace }}\deps\build\BambuStudio_dep\*" -DestinationPath "${{ github.workspace }}\deps\build\BambuStudio_dep_win64_${{ env.date }}_vs2022.zip" shell: pwsh - # Windows on ARM64. The windows-11-arm runner ships Visual Studio 2022 - # (v17), not 2026, so the generator differs from the x64 job above. The - # GMP/MPFR/OpenSSL/Boost ARM64 dep handling lives in deps/*.cmake and is - # selected automatically from -A ARM64 (CMAKE_GENERATOR_PLATFORM). - - name: Build on Windows ARM64 + # Windows on ARM64/ARM64EC. The windows-11-arm runner ships Visual + # Studio 2022 (v17), not 2026, so the generator differs from the x64 job + # above. All per-dep arch handling lives in deps/*.cmake and is selected + # automatically from the -A platform (arm64ec = native ARM64 code with + # the x64-compatible ABI, which is what lets the app load the x64-only + # Bambu network plugin in-process). + - name: Build on Windows ARM64/ARM64EC if: inputs.os == 'windows-11-arm' working-directory: ${{ github.workspace }} run: | @@ -88,13 +90,15 @@ jobs: mkdir ${{ github.workspace }}\deps\build mkdir ${{ github.workspace }}\deps\build\BambuStudio_dep cd "${{ github.workspace }}\deps\build" - cmake ../ -G "Visual Studio 17 2022" -A ARM64 -DDESTDIR="./BambuStudio_dep" -DCMAKE_BUILD_TYPE=Release -DDEP_DEBUG=OFF + $platform = "${{ inputs.arch }}" -eq "arm64ec" ? "ARM64EC" : "ARM64" + cmake ../ -G "Visual Studio 17 2022" -A $platform -DDESTDIR="./BambuStudio_dep" -DCMAKE_BUILD_TYPE=Release -DDEP_DEBUG=OFF msbuild /m ALL_BUILD.vcxproj + shell: pwsh - - name: pack deps on Windows ARM64 + - name: pack deps on Windows ARM64/ARM64EC if: inputs.os == 'windows-11-arm' working-directory: ${{ github.workspace }} - run: Compress-Archive -Path "${{ github.workspace }}\deps\build\BambuStudio_dep\*" -DestinationPath "${{ github.workspace }}\deps\build\BambuStudio_dep_win-arm64_${{ env.date }}_vs2022.zip" + run: Compress-Archive -Path "${{ github.workspace }}\deps\build\BambuStudio_dep\*" -DestinationPath "${{ github.workspace }}\deps\build\BambuStudio_dep_win-${{ inputs.arch }}_${{ env.date }}_vs2022.zip" shell: pwsh - name: Fix python install error on mac @@ -189,11 +193,11 @@ jobs: name: BambuStudio_dep_win64_${{ env.date }} path: ${{ github.workspace }}/deps/build/BambuStudio_dep*.zip - - name: Upload Windows ARM64 artifacts + - name: Upload Windows ARM64/ARM64EC artifacts if: inputs.os == 'windows-11-arm' uses: actions/upload-artifact@v6 with: - name: BambuStudio_dep_win-arm64_${{ env.date }} + name: BambuStudio_dep_win-${{ inputs.arch }}_${{ env.date }} path: ${{ github.workspace }}/deps/build/BambuStudio_dep*.zip - name: Upload Ubuntu artifacts From 893f15c1a23f4a1c25dfd732170a25b6ad03abb7 Mon Sep 17 00:00:00 2001 From: Ryan Ewen Date: Sat, 18 Jul 2026 15:11:49 -0400 Subject: [PATCH 16/18] fix: disable TBB warnings-as-errors (C4163 under ARM64EC /FIintrin.h) The forced intrin.h include makes cl warn C4163 for x86-only intrinsics (__rdtsc, _mm_mfence) that softintrin provides at link time; oneTBB's default TBB_STRICT=ON promotes those to errors on the ARM64EC bundle build. --- deps/TBB/TBB.cmake | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/deps/TBB/TBB.cmake b/deps/TBB/TBB.cmake index 2f82ce5d6d..6c90e0c4a7 100644 --- a/deps/TBB/TBB.cmake +++ b/deps/TBB/TBB.cmake @@ -9,6 +9,10 @@ bambustudio_add_cmake_project( PATCH_COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_LIST_DIR}/patch_tbb.cmake CMAKE_ARGS -DCMAKE_POLICY_VERSION_MINIMUM=3.5 + # ARM64EC: /FIintrin.h makes cl warn C4163 for x86-only intrinsics + # (__rdtsc, _mm_mfence) that softintrin handles at link time; TBB's + # default warnings-as-errors turns those fatal. + -DTBB_STRICT=OFF -DTBB_BUILD_SHARED=OFF -DTBB_BUILD_TESTS=OFF -DTBB_TEST=OFF From e41780672cc2a9a9e136c217b269b1931786d6ea Mon Sep 17 00:00:00 2001 From: Ryan Ewen Date: Sat, 18 Jul 2026 15:46:29 -0400 Subject: [PATCH 17/18] fix: resolve OpenCV layout from the prefix on ARM64EC The in-repo ARM64EC deps bundle installs OpenCV under ARM64/vc17 (its recipe treats EC like arm64), while an x64 dependency prefix provides x64/vc17; an ARM64EC app links either flavor, so probe the prefix for which layout exists instead of assuming x64. --- src/libslic3r/CMakeLists.txt | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index 82db9f5109..b60ad95337 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -544,10 +544,19 @@ if(MSVC AND NOT DEFINED OpenCV_ARCH) set(OpenCV_RUNTIME vc17) endif() elseif(_slic3r_gen_platform STREQUAL "ARM64EC") - # ARM64EC links the x64 dependency set (EC and x64 code interoperate), - # so select the x64 OpenCV layout. MSVC 19.4x also falls in a gap in - # OpenCV 4.6's runtime table, so the runtime must be pinned here too. + # ARM64EC consumes either dependency flavor (EC and x64 code + # interoperate): the in-repo ARM64EC deps bundle installs OpenCV under + # ARM64/vc17 (its recipe treats EC like arm64), while an x64 deps + # prefix uses x64/vc17. Pick whichever layout the prefix provides. + # MSVC 19.4x also falls in a gap in OpenCV 4.6's runtime table, so the + # runtime must be pinned here too. set(OpenCV_ARCH x64) + foreach(_slic3r_prefix ${CMAKE_PREFIX_PATH}) + if(EXISTS "${_slic3r_prefix}/ARM64/vc17") + set(OpenCV_ARCH ARM64) + endif() + endforeach() + unset(_slic3r_prefix) if(NOT DEFINED OpenCV_RUNTIME) set(OpenCV_RUNTIME vc17) endif() From aadfe237690ca9272a70db70eca3fc619592f136 Mon Sep 17 00:00:00 2001 From: Ryan Ewen Date: Sat, 18 Jul 2026 18:47:42 -0400 Subject: [PATCH 18/18] fix: restrict TBB ARM64EC patches to MSVC (unbreak macOS deps) TBB_STRICT=OFF and the ARM64EC patch were applied on every platform. On macOS that regressed the deps build: oneTBB's non-strict path rewrites the compiler flags and mangles the macOS -Werror= options into bare '=partial-availability' tokens, which clang rejects as missing files (Linux is unaffected - it has no such flags). Both changes are only needed for the MSVC ARM64EC build, so gate them behind if(MSVC); macOS/Linux now build TBB exactly as before. Confirmed against CI history: macOS deps were green with the patch alone (run 29647625275) and only went red once TBB_STRICT=OFF landed. --- deps/TBB/TBB.cmake | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/deps/TBB/TBB.cmake b/deps/TBB/TBB.cmake index 6c90e0c4a7..874737a075 100644 --- a/deps/TBB/TBB.cmake +++ b/deps/TBB/TBB.cmake @@ -1,18 +1,29 @@ +# The ARM64EC fixes (drop the hard-coded /GL that blocks EC links, guard/stub +# the TSX intrinsics) are MSVC-only. Keep them off non-MSVC toolchains so +# macOS/Linux build TBB exactly as before: in particular TBB_STRICT=OFF makes +# oneTBB rewrite the compile flags, which mangles the macOS -Werror= +# flags into bare '=' tokens (LNK/compile failure). +set(_tbb_patch "") +set(_tbb_strict "") +if (MSVC) + # Removes the hard-coded /GL (blocks ARM64EC links) and guards TSX + # intrinsics against ARM64EC. On x64 this only drops LTCG (same code). + set(_tbb_patch PATCH_COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_LIST_DIR}/patch_tbb.cmake) + # ARM64EC: /FIintrin.h makes cl warn C4163 for x86-only intrinsics + # (__rdtsc, _mm_mfence) that softintrin handles at link time; TBB's default + # warnings-as-errors turns those fatal. + set(_tbb_strict -DTBB_STRICT=OFF) +endif () + bambustudio_add_cmake_project( TBB URL "https://github.com/oneapi-src/oneTBB/archive/refs/tags/v2021.5.0.zip" URL_HASH SHA256=83ea786c964a384dd72534f9854b419716f412f9d43c0be88d41874763e7bb47 #PATCH_COMMAND ${PATCH_CMD} ${CMAKE_CURRENT_LIST_DIR}/0001-TBB-GCC13.patch - # Removes the hard-coded /GL (blocks ARM64EC links) and guards TSX - # intrinsics against ARM64EC. Both no-ops for other targets' behaviour: - # dropping LTCG slightly reduces x64 optimization but keeps the same code. - PATCH_COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_LIST_DIR}/patch_tbb.cmake + ${_tbb_patch} CMAKE_ARGS -DCMAKE_POLICY_VERSION_MINIMUM=3.5 - # ARM64EC: /FIintrin.h makes cl warn C4163 for x86-only intrinsics - # (__rdtsc, _mm_mfence) that softintrin handles at link time; TBB's - # default warnings-as-errors turns those fatal. - -DTBB_STRICT=OFF + ${_tbb_strict} -DTBB_BUILD_SHARED=OFF -DTBB_BUILD_TESTS=OFF -DTBB_TEST=OFF