diff --git a/CLAUDE.md b/CLAUDE.md index 1cbbd3e3e..b80c2c562 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -82,7 +82,7 @@ black . --line-length 100 ## Development Tips -- The project uses CMake with presets for different platforms (windows-msvc, linux-gcc, macos-arm64-clang) +- The project uses CMake with presets for different platforms (windows-msvc, windows-arm64-msvc, linux-gcc, macos-arm64-clang) - PyTorch integration is automatic when PyTorch is installed - Hot-reload is supported for shader development - Use `python tools/ci.py` for most build/test tasks - it handles platform-specific configuration diff --git a/CMakePresets.json b/CMakePresets.json index ba4afb768..0353a7147 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -91,6 +91,40 @@ "windows-clang-base" ] }, + { + "name": "windows-arm64-base", + "description": "Base Windows ARM64 configuration.", + "hidden": true, + "inherits": "windows-base", + "cacheVariables": { + "VCPKG_TARGET_TRIPLET": "arm64-windows-static-md-fix" + } + }, + { + "name": "windows-arm64-msvc-base", + "description": "Base Visual Studio 2022 ARM64 configuration.", + "hidden": true, + "inherits": "windows-arm64-base", + "generator": "Ninja Multi-Config", + "architecture": { + "value": "ARM64", + "strategy": "external" + }, + "cacheVariables": { + "CMAKE_C_COMPILER": "cl", + "CMAKE_CXX_COMPILER": "cl" + } + }, + { + "name": "windows-arm64-msvc", + "inherits": [ + "windows-arm64-msvc-base" + ], + "cacheVariables": { + "CMAKE_CXX_FLAGS": "/EHsc", + "SGL_WARNINGS_AS_ERRORS": "OFF" + } + }, { "name": "linux-base", "description": "Base Linux configuration.", @@ -190,6 +224,18 @@ "configurePreset": "windows-clang", "configuration": "Debug" }, + { + "name": "windows-arm64-msvc-release", + "displayName": "Release", + "configurePreset": "windows-arm64-msvc", + "configuration": "Release" + }, + { + "name": "windows-arm64-msvc-debug", + "displayName": "Debug", + "configurePreset": "windows-arm64-msvc", + "configuration": "Debug" + }, { "name": "linux-clang-release", "displayName": "Release", diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index 76664d564..38f58d247 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -162,7 +162,11 @@ function(sgl_add_library_slang) sgl_copy_binary(${SLANG_DIR}/bin/${slang_lib_base}.dll .) sgl_copy_binary(${SLANG_DIR}/bin/slang-glslang.dll .) sgl_copy_binary(${SLANG_DIR}/bin/slang-glsl-module.dll .) - sgl_copy_binary(${SLANG_DIR}/bin/slang-llvm.dll .) + # slang-llvm.dll is available in x64 prebuilt packages but not in ARM64 packages. + # Use conditional copy to support both architectures. + if(EXISTS ${SLANG_DIR}/bin/slang-llvm.dll) + sgl_copy_binary(${SLANG_DIR}/bin/slang-llvm.dll .) + endif() # Note: The downloaded debug-info archive has single top-level 'bin' # folder that is stripped out by FetchContent. set(slang_resolved_debug_info "${slang_lib_base}.pdb") diff --git a/external/vcpkg-triplets/arm64-windows-static-md-fix.cmake b/external/vcpkg-triplets/arm64-windows-static-md-fix.cmake new file mode 100644 index 000000000..6d88c9bc9 --- /dev/null +++ b/external/vcpkg-triplets/arm64-windows-static-md-fix.cmake @@ -0,0 +1,7 @@ +set(VCPKG_TARGET_ARCHITECTURE arm64) +set(VCPKG_CRT_LINKAGE dynamic) +set(VCPKG_LIBRARY_LINKAGE static) +# _DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR avoids the use of constexpr mutex constructor +# in vcpkg packages, which can lead to binary incompatibility issues. +set(VCPKG_C_FLAGS "-D_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR") +set(VCPKG_CXX_FLAGS "-D_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR") diff --git a/setup.py b/setup.py index 25a97d143..bcc44a76d 100644 --- a/setup.py +++ b/setup.py @@ -4,7 +4,7 @@ from __future__ import print_function -import sys, re, os, subprocess, shutil +import sys, re, os, subprocess, shutil, platform from pathlib import Path try: @@ -31,11 +31,24 @@ else: raise Exception(f"Unsupported platform: {sys.platform}") -CMAKE_PRESET = { - "windows": "windows-msvc", - "linux": "linux-gcc", - "macos": "macos-arm64-clang", -}[PLATFORM] +# Detect architecture for platform-specific CMake presets +if PLATFORM == "windows": + python_arch = platform.machine().lower() + is_arm64 = python_arch in ("arm64", "aarch64") + if is_arm64: + CMAKE_PRESET = "windows-arm64-msvc" + MSVC_PLAT_SPEC = "x86_arm64" + else: + CMAKE_PRESET = "windows-msvc" + MSVC_PLAT_SPEC = "x64" +elif PLATFORM == "linux": + CMAKE_PRESET = "linux-gcc" + MSVC_PLAT_SPEC = None +elif PLATFORM == "macos": + CMAKE_PRESET = "macos-arm64-clang" + MSVC_PLAT_SPEC = None +else: + raise RuntimeError(f"Unsupported platform: {PLATFORM}") CMAKE_CONFIG = "RelWithDebInfo" @@ -67,7 +80,7 @@ def build_extension(self, ext: CMakeExtension) -> None: sys.path.append(str(Path(__file__).parent / "tools")) import msvc # type: ignore - env = msvc.msvc14_get_vc_env("x64") + env = msvc.msvc14_get_vc_env(MSVC_PLAT_SPEC) build_dir = str(SOURCE_DIR / "build/pip") diff --git a/src/sgl/CMakeLists.txt b/src/sgl/CMakeLists.txt index f23875325..9f98b05f1 100644 --- a/src/sgl/CMakeLists.txt +++ b/src/sgl/CMakeLists.txt @@ -1,6 +1,8 @@ add_library(sgl SHARED) +option(SGL_WARNINGS_AS_ERRORS "Treat compiler warnings as errors" ON) + target_sources(sgl PRIVATE sgl.natvis @@ -201,7 +203,7 @@ target_compile_options(sgl /MP # enable multi-processor compilation /Zi # generate debug symbols # Configure warnings - /WX # warnings as errors + $<$:/WX> # warnings as errors /W4 # increase warning level /wd4251 # 'type' : class 'type1' needs to have dll-interface to be used by clients of class 'type2' /wd4201 # nonstandard extension used: nameless struct/union @@ -222,7 +224,7 @@ target_compile_options(sgl -fvisibility=hidden # hide symbols by default -Wall # set warning level -Wextra # enable extra warnings - -Werror # treat warnings as errors + $<$:-Werror> # treat warnings as errors -Wno-unused-function -Wno-unused-variable -Wno-unused-but-set-variable diff --git a/tools/ci.py b/tools/ci.py index 19b716ad5..abff0675e 100644 --- a/tools/ci.py +++ b/tools/ci.py @@ -38,7 +38,7 @@ def get_platform(): machine = platform.machine() if machine == "x86_64" or machine == "AMD64": return "x86_64" - elif machine == "aarch64" or machine == "arm64": + elif machine == "aarch64" or machine == "arm64" or machine == "ARM64": return "aarch64" else: raise NameError(f"Unsupported platform: {machine}") @@ -316,6 +316,8 @@ def main(): preset = preset.replace("macos", "macos-x64") elif args["platform"] == "aarch64": preset = preset.replace("macos", "macos-arm64") + elif args["os"] == "windows" and args["platform"] == "aarch64": + preset = "windows-arm64-" + args["compiler"] args["preset"] = preset # Determine binary directory.