Skip to content

Fix MSVC + CUDA 13.3 build and bump dependencies#10

Merged
zfergus merged 19 commits into
mainfrom
fix/msvc-cuda13-build
Jul 16, 2026
Merged

Fix MSVC + CUDA 13.3 build and bump dependencies#10
zfergus merged 19 commits into
mainfrom
fix/msvc-cuda13-build

Conversation

@zfergus

@zfergus zfergus commented Jul 16, 2026

Copy link
Copy Markdown
Member

Get the project building with MSVC (VS 18 / cl 14.51) and CUDA 13.3:

  • Patch spdlog's bundled fmt for NVCC: its device front-end (EDG) never sees the host /utf-8 flag, so fmt's compile-time UTF-8 probe misfires, and EDG rejects the char32_t rounding-threshold table (hex escapes with the high bit set). Guard both behind CUDACC via CPM PATCHES (cmake/patches/fmt-nvcc-compat.patch).
  • Forward /utf-8 and /Zc:preprocessor to the CUDA host compiler; CCCL (thrust/cub) requires the conforming preprocessor. CXX gets /utf-8 transitively from spdlog's PUBLIC export.
  • Fix a Win64 std::max type mismatch in cuda/broad_phase/utils.cu (unsigned long is 32-bit on Windows): use size_t(1).

Dependency bumps: spdlog 1.15.3 -> 1.17.0, Eigen -> 5.0.1, libigl -> 2.6.0, oneTBB 2022.1.0 -> 2022.3.0.

Also add CMakePresets.json, ignore *.vs, and stop leaking /FS to NVCC.

Get the project building with MSVC (VS 18 / cl 14.51) and CUDA 13.3:

- Patch spdlog's bundled fmt for NVCC: its device front-end (EDG) never
  sees the host /utf-8 flag, so fmt's compile-time UTF-8 probe misfires,
  and EDG rejects the char32_t rounding-threshold table (hex escapes with
  the high bit set). Guard both behind __CUDACC__ via CPM PATCHES
  (cmake/patches/fmt-nvcc-compat.patch).
- Forward /utf-8 and /Zc:preprocessor to the CUDA host compiler; CCCL
  (thrust/cub) requires the conforming preprocessor. CXX gets /utf-8
  transitively from spdlog's PUBLIC export.
- Fix a Win64 std::max type mismatch in cuda/broad_phase/utils.cu
  (unsigned long is 32-bit on Windows): use size_t(1).

Dependency bumps: spdlog 1.15.3 -> 1.17.0, Eigen -> 5.0.1,
libigl -> 2.6.0, oneTBB 2022.1.0 -> 2022.3.0.

Also add CMakePresets.json, ignore *.vs, and stop leaking /FS to NVCC.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 16, 2026 18:28

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aims to restore/ensure successful builds on Windows MSVC with CUDA 13.3 by adjusting NVCC/MSVC flag forwarding, patching spdlog’s bundled fmt for NVCC’s EDG frontend behavior, and updating several third-party dependencies. It also adds developer quality-of-life improvements (CMake presets, gitignore).

Changes:

  • Add an NVCC compatibility patch for spdlog’s bundled fmt and forward required MSVC host flags for CUDA builds.
  • Fix a Windows-specific CUDA broad-phase std::max type mismatch and refine MSVC /FS usage to avoid leaking to NVCC.
  • Bump spdlog/Eigen/libigl/oneTBB versions and add CMakePresets.json plus *.vs ignore.

Reviewed changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/scalable_ccd/cuda/broad_phase/utils.cu Fixes a Windows type mismatch in CUDA setup logic.
CMakePresets.json Adds presets for common release/debug and CUDA configurations.
CMakeLists.txt Adds MSVC host-flag forwarding for CUDA builds and related documentation.
cmake/scalable_ccd/scalable_ccd_use_colors.cmake Restricts /FS to avoid applying it to CUDA compilation.
cmake/recipes/spdlog.cmake Bumps spdlog and applies an NVCC-focused fmt patch via CPM.
cmake/recipes/onetbb.cmake Bumps oneTBB version.
cmake/recipes/libigl.cmake Switches libigl dependency to the 2.6.0 tag.
cmake/recipes/eigen.cmake Bumps Eigen and adjusts related compile definitions.
cmake/patches/fmt-nvcc-compat.patch Introduces fmt guards/workarounds for NVCC’s EDG frontend.
.gitignore Ignores Visual Studio *.vs directory.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread CMakePresets.json Outdated
Comment thread cmake/scalable_ccd/scalable_ccd_use_colors.cmake Outdated
zfergus and others added 18 commits July 16, 2026 14:40
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Adding nvcc to PATH was not enough: msvc-dev-cmd re-exports PATH via
GITHUB_ENV before the CUDA toolkit step, so the GITHUB_PATH prepend does
not reliably take effect and check_language(CUDA) still reports
"No CUDA support found!". Set CUDACXX to the nvcc full path (honored by
CMake before any PATH search) in addition to the PATH entry.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Setting CUDACXX was not enough for check_language(CUDA). Pass
-DCMAKE_CUDA_COMPILER directly (a cache var check_language forwards to
its probe project) and assert nvcc.exe actually exists after install so
a silent no-op install surfaces clearly instead of a vague
"No CUDA support found!".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The nvcc verification confirmed nvcc.exe installs fine and
-DCMAKE_CUDA_COMPILER lets check_language(CUDA) find it, but the compiler
probe then fails with "Cannot open include file: 'cuda_runtime.h'". On
Windows the toolkit is componentized finer than on Linux: the nvcc
sub-package excludes the runtime headers and thrust/cub. Make
sub-packages OS-specific and add cudart/thrust/cub/cccl on Windows; also
log include/ contents for diagnosis.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Passing thrust/cub/cccl aborted the installer (exit 3772776473) — an
invalid component name fails the whole install, and CUDA 13 dropped the
classic thrust/cub components in favor of CCCL. Keep the list to the
known-valid nvcc + cudart; the include/ listing will reveal whether
thrust/cub headers ship with those before adding more.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Component-by-component selection turned into header whack-a-mole
(nvcc -> cudart -> crt/host_config.h -> thrust/cub ...), and an invalid
component name aborts the whole installer. Install the full toolkit on
Windows (empty sub-packages = no -s filter) so every header is present.
Linux keeps the fast nvcc-only install via the OS-specific matrix value.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The 'network' method only fetches packages named in sub-packages, so an
empty list does not produce a full install. Per the action docs, a full
install is 'local' method + empty sub-packages. Make method OS-specific:
Linux keeps 'network' (required for its nvcc-only filter), Windows uses
'local' to install the complete toolkit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Per the cuda-toolkit source (update-path.ts), the action already adds
its bin dir to PATH via core.addPath. Our workarounds only existed
because msvc-dev-cmd ran first and snapshotted PATH into GITHUB_ENV
before nvcc was added. Install CUDA before msvc-dev-cmd so the snapshot
includes nvcc; CMake's check_language(CUDA) then finds it with no hints.

Removes the manual "Locate CUDA compiler" PATH/CUDACXX step and the
-DCMAKE_CUDA_COMPILER override; the Windows configure now mirrors Linux.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The full 'local' install was slow (>5 min downloading the whole
installer). NVIDIA's redist manifest for 13.2 shows the headers we were
missing live in separate components: cuda_crt (crt/host_config.h) and
cuda_cccl (thrust/cub/libcudacxx; the standalone thrust/cub components
were dropped in CUDA 13). Switch Windows back to the fast network method
with the exact set nvcc + cudart + crt + cccl (redist names minus the
cuda_ prefix, matching the proven nvcc/cudart mapping). Both OSes now use
network, so the method is no longer matrix-specific.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
cccl_13.2 aborted the installer: per NVIDIA's Windows silent-install
subpackage list, "cccl"/"cub" are not valid installer component names,
but "thrust" is (and it ships the CUB/libcudacxx headers it depends on).
Use nvcc + cudart + crt + thrust.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ect)

The network install now succeeds fast (~20s) with nvcc+cudart+crt+thrust,
and the step reorder puts nvcc on PATH, but CMake's check_language(CUDA)
still reports NOTFOUND on this runner even with nvcc on PATH. Restore the
explicit -DCMAKE_CUDA_COMPILER so enable_language uses nvcc directly; with
crt now installed, the compiler probe's earlier header failure is gone.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
With crt installed, the compiler probe reached nvcc's device backend and
failed: cicc (in nvvm/bin) was not found because the nvcc subpackage
ships only the front-end. NVIDIA's Windows subpackage table lists "nvvm"
(NVVM Compiler Library) separately, which provides cicc. Add it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The CUDA job pinned older action versions (checkout@v4.0.0, cache@v4,
cpu-cores@v2.0.0) than the main job (@v6, @v5, @v2). Bump them to match
for consistency and to clear the Node 20 deprecation warnings from those
actions. Also name the previously unnamed cuda-toolkit step.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@zfergus
zfergus merged commit 8f9347c into main Jul 16, 2026
8 checks passed
@zfergus
zfergus deleted the fix/msvc-cuda13-build branch July 16, 2026 20:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants