diff --git a/.github/workflows/build_all.yml b/.github/workflows/build_all.yml index 3de2a9184b..fe4f10e81b 100644 --- a/.github/workflows/build_all.yml +++ b/.github/workflows/build_all.yml @@ -81,14 +81,15 @@ jobs: # SELF_HOSTED skips arm64 (the self-hosted Windows server is x64-only). matrix: include: ${{ fromJSON(vars.SELF_HOSTED - && '[{"arch":"x64","os":"orca-win-server"}]' - || '[{"arch":"x64","os":"windows-latest"},{"arch":"arm64","os":"windows-11-arm"}]') }} + && '[{"arch":"x64","os":"orca-win-server","compiler":"clang"}]' + || '[{"arch":"x64","os":"windows-latest","compiler":"clang"},{"arch":"arm64","os":"windows-11-arm","compiler":"clang"}]') }} # Don't run scheduled builds on forks: if: ${{ !cancelled() && (github.event_name != 'schedule' || github.repository == 'OrcaSlicer/OrcaSlicer') }} uses: ./.github/workflows/build_check_cache.yml with: os: ${{ matrix.os }} arch: ${{ matrix.arch }} + compiler: ${{ matrix.compiler }} build-deps-only: ${{ inputs.build-deps-only || false }} force-build: ${{ github.event_name == 'schedule' }} secrets: inherit diff --git a/.github/workflows/build_check_cache.yml b/.github/workflows/build_check_cache.yml index b5c5b28b95..91ea51ac60 100644 --- a/.github/workflows/build_check_cache.yml +++ b/.github/workflows/build_check_cache.yml @@ -9,6 +9,10 @@ on: arch: required: false type: string + compiler: + required: false + type: string + default: msvc build-deps-only: required: false type: boolean @@ -33,10 +37,10 @@ jobs: - name: set outputs id: set_outputs env: - # Keep macOS/Windows cache keys architecture-specific. amd64 Linux passes - # no arch (key stays 'linux-clang', preserving the existing cache); - # aarch64 gets its own 'linux-clang-aarch64' key. - cache-os: ${{ runner.os == 'macOS' && format('macos-{0}', inputs.arch) || (runner.os == 'Windows' && format('windows-{0}', inputs.arch) || format('linux-clang{0}', inputs.arch && format('-{0}', inputs.arch) || '')) }} + # Anything that changes how the tree is built belongs in the key, or a job + # restores one it cannot use. Linux amd64 passes no arch deliberately, so + # 'linux-clang' keeps the cache it already has. + cache-os: ${{ runner.os == 'macOS' && format('macos-{0}', inputs.arch) || (runner.os == 'Windows' && format('windows-{0}-{1}', inputs.arch, inputs.compiler) || format('linux-clang{0}', inputs.arch && format('-{0}', inputs.arch) || '')) }} # ARM64 builds use the build-arm64 tree (see build_release_vs.bat); x64/other use build. dep-folder-name: ${{ runner.os == 'macOS' && format('/{0}', inputs.arch) || (runner.os == 'Windows' && inputs.arch == 'arm64') && '-arm64/OrcaSlicer_dep' || '/OrcaSlicer_dep' }} output-cmd: ${{ runner.os == 'Windows' && '$env:GITHUB_OUTPUT' || '"$GITHUB_OUTPUT"'}} @@ -62,6 +66,7 @@ jobs: valid-cache: ${{ needs.check_cache.outputs.valid-cache == 'true' }} os: ${{ inputs.os }} arch: ${{ inputs.arch }} + compiler: ${{ inputs.compiler }} build-deps-only: ${{ inputs.build-deps-only }} force-build: ${{ inputs.force-build }} secrets: inherit diff --git a/.github/workflows/build_deps.yml b/.github/workflows/build_deps.yml index f9e5c57c34..f7082a8a06 100644 --- a/.github/workflows/build_deps.yml +++ b/.github/workflows/build_deps.yml @@ -16,6 +16,10 @@ on: arch: required: false type: string + compiler: + required: false + type: string + default: msvc build-deps-only: required: false type: boolean @@ -135,11 +139,22 @@ jobs: choco install strawberryperl } $arch = "${{ inputs.arch }}" + # -l selects clang-cl and -x Ninja; together they build the deps with clang. + $clang = "${{ inputs.compiler }}" -eq "clang" + $flags = if ($clang) { "-l", "-x" } else { @() } + if ($clang) { + # OpenSSL builds with nmake, which needs a VC environment. + $vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" + $vs = & $vswhere -latest -property installationPath + $devArch = if ($arch -eq "arm64") { "arm64" } else { "amd64" } + Import-Module "$vs\Common7\Tools\Microsoft.VisualStudio.DevShell.dll" + Enter-VsDevShell -VsInstallPath $vs -SkipAutomaticLocation -DevCmdArguments "-arch=$devArch" + } if ($arch -eq "arm64") { - .\build_release_vs.bat deps arm64 + .\build_release_vs.bat deps arm64 @flags .\build_release_vs.bat pack arm64 } else { - .\build_release_vs.bat deps + .\build_release_vs.bat deps @flags .\build_release_vs.bat pack } shell: pwsh @@ -204,4 +219,5 @@ jobs: cache-path: ${{ inputs.cache-path }} os: ${{ inputs.os }} arch: ${{ inputs.arch }} + compiler: ${{ inputs.compiler }} secrets: inherit diff --git a/.github/workflows/build_orca.yml b/.github/workflows/build_orca.yml index a9efaa7561..8e1e28db13 100644 --- a/.github/workflows/build_orca.yml +++ b/.github/workflows/build_orca.yml @@ -13,6 +13,10 @@ on: arch: required: false type: string + compiler: + required: false + type: string + default: msvc macos-combine-only: required: false type: boolean @@ -395,7 +399,18 @@ jobs: # "tests" builds the unit tests too; the unit_tests_windows_* jobs run them. run: | $arch = "${{ inputs.arch }}" - if ($arch -eq "arm64") { .\build_release_vs.bat slicer arm64 tests } else { .\build_release_vs.bat slicer tests } + # -l selects clang-cl and -x Ninja; together they build the slicer with clang. + $clang = "${{ inputs.compiler }}" -eq "clang" + $flags = if ($clang) { "-l", "-x" } else { @() } + if ($clang) { + # Build against the same VC toolchain and SDK as the dependencies. + $vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" + $vs = & $vswhere -latest -property installationPath + $devArch = if ($arch -eq "arm64") { "arm64" } else { "amd64" } + Import-Module "$vs\Common7\Tools\Microsoft.VisualStudio.DevShell.dll" + Enter-VsDevShell -VsInstallPath $vs -SkipAutomaticLocation -DevCmdArguments "-arch=$devArch" + } + if ($arch -eq "arm64") { .\build_release_vs.bat slicer arm64 @flags tests } else { .\build_release_vs.bat slicer @flags tests } shell: pwsh - name: Build system preset cache (Windows) diff --git a/deps/OCCT/OCCT.cmake b/deps/OCCT/OCCT.cmake index b4cd9facd2..62bfcf8e76 100644 --- a/deps/OCCT/OCCT.cmake +++ b/deps/OCCT/OCCT.cmake @@ -1,3 +1,10 @@ +# clang-cl cannot emit IGESAppli_GeneralModule.cxx on ARM64 +# (llvm/llvm-project#62081). cl and clang-cl share an ABI. +set(_occt_compiler_args "") +if ("${DEPS_ARCH}" STREQUAL "arm64" AND CMAKE_CXX_COMPILER_ID STREQUAL Clang) + set(_occt_compiler_args -DCMAKE_C_COMPILER:STRING=cl -DCMAKE_CXX_COMPILER:STRING=cl) +endif () + if(WIN32) set(library_build_type "Shared") else() @@ -31,6 +38,7 @@ orcaslicer_add_cmake_project(OCCT -DBUILD_MODULE_ModelingAlgorithms=OFF -DBUILD_MODULE_ModelingData=OFF -DBUILD_MODULE_Visualization=OFF + ${_occt_compiler_args} ) # add_dependencies(dep_OCCT ${FREETYPE_PKG}) diff --git a/deps/OpenCV/OpenCV.cmake b/deps/OpenCV/OpenCV.cmake index d8c7cbac3b..0290b3f47a 100644 --- a/deps/OpenCV/OpenCV.cmake +++ b/deps/OpenCV/OpenCV.cmake @@ -10,6 +10,13 @@ else () set(_options "") endif () +# carotene is OpenCV's ARM NEON HAL. It uses M_PI without _USE_MATH_DEFINES +# and does not compile with clang-cl. +set(_disable_carotene "") +if ("${DEPS_ARCH}" STREQUAL "arm64" AND CMAKE_CXX_COMPILER_ID STREQUAL Clang) + set(_disable_carotene "-DWITH_CAROTENE=OFF") +endif () + if (IN_GIT_REPO) set(OpenCV_DIRECTORY_FLAG --directory ${BINARY_DIR_REL}/dep_OpenCV-prefix/src/dep_OpenCV) endif () @@ -83,5 +90,6 @@ orcaslicer_add_cmake_project(OpenCV -DWITH_PROTOBUF=OFF -DWITH_WIN32UI=OFF -DHAVE_WIN32UI=FALSE + ${_disable_carotene} ) diff --git a/deps/OpenSSL/OpenSSL.cmake b/deps/OpenSSL/OpenSSL.cmake index ddeb680052..2fb4b51757 100644 --- a/deps/OpenSSL/OpenSSL.cmake +++ b/deps/OpenSSL/OpenSSL.cmake @@ -6,7 +6,7 @@ if(DEFINED OPENSSL_ARCH) set(_cross_arch ${OPENSSL_ARCH}) else() if(WIN32) - if("${CMAKE_GENERATOR_PLATFORM}" STREQUAL "ARM64") + if("${DEPS_ARCH}" STREQUAL "arm64") set(_cross_arch "VC-WIN64-ARM") else() set(_cross_arch "VC-WIN64A") diff --git a/deps/PNG/PNG.cmake b/deps/PNG/PNG.cmake index 332fdfe274..a73e96a0c9 100644 --- a/deps/PNG/PNG.cmake +++ b/deps/PNG/PNG.cmake @@ -1,6 +1,10 @@ if (APPLE) # Only disable NEON extension for Apple ARM builds, leave it enabled for Raspberry PI. set(_disable_neon_extension "-DPNG_ARM_NEON=off") +elseif ("${DEPS_ARCH}" STREQUAL "arm64" AND CMAKE_CXX_COMPILER_ID STREQUAL Clang) + # libpng's CMake ignores PNG_ARM_NEON on Windows ARM64 and skips the NEON + # sources, but pngpriv.h enables NEON anyway. + set(_disable_neon_extension "-DCMAKE_C_FLAGS=/DWIN32 /D_WINDOWS /DPNG_ARM_NEON_OPT=0") else () set(_disable_neon_extension "") endif ()