Skip to content

Run cmake subprocesses in the project directory so version-manager shims resolve correctly - #5006

Open
Daniele Formichelli (danieleformichelli) wants to merge 3 commits into
microsoft:mainfrom
danieleformichelli:fix/version-manager-shim-cwd
Open

Run cmake subprocesses in the project directory so version-manager shims resolve correctly#5006
Daniele Formichelli (danieleformichelli) wants to merge 3 commits into
microsoft:mainfrom
danieleformichelli:fix/version-manager-shim-cwd

Conversation

@danieleformichelli

@danieleformichelli Daniele Formichelli (danieleformichelli) commented Jul 24, 2026

Copy link
Copy Markdown

This change addresses item #5005

This changes visible behavior

The following changes are proposed:

  • kits/kit.ts: probe cmake from the workspace folder during Clang/MSVC kit scanning (runs for any clang binary, so it hits shim users on Linux/macOS too).
  • Run the cmake subprocesses launched by the extension inside the project directory instead of inheriting the extension host's process.cwd().
  • Thread an optional cwd through getCMakeExecutableInformation(...) (the cmake --version / -E capabilities probe) and pass the workspace/project folder from every caller (extension.ts, cmakeProject.ts, debuggerScriptDriver.ts).
  • Default the working directory of driver subprocesses to sourceDir, the build invocation to binaryDir, and build tasks to binaryDir || sourceDir || workspaceFolder.
  • Default the CMake script debugger child process cwd to the project folder.

The purpose of this change

Users whose cmake is provided by a directory-based version manager (mise, asdf, vfox, ...) install a shim on PATH. These shims resolve the tool version by walking up from the current working directory to find the nearest config file. They do not have a "current" version baked in.

Today the extension launches cmake (the version/capabilities probe, the build, and the script debugger) without setting a cwd, so the child inherits the extension host's process.cwd(). Depending on how the editor was launched (e.g. from the OS GUI, Dock, or a Remote-WSL host started from the Windows GUI), that directory is often the user's home folder — outside the project. The shim then has no config to resolve against and fails, e.g.:

mise ERROR No version is set for shim: cmake

The result is that configuration intermittently succeeds (some paths already pass a cwd) while the version probe or the build fails, with an error that looks like a broken toolchain rather than a cwd issue.

Running these subprocesses in the project directory is the natural, correct behavior for a project-scoped build tool and makes shim-based toolchains resolve reliably, regardless of how the editor process was started.

Other Notes/Information

  • Scope is intentionally minimal: each call site defaults cwd only when the caller didn't already specify one, so existing behavior for explicitly-set working directories is unchanged.
  • The change is a no-op for users on absolute cmake paths or non-shim installs, since the working directory doesn't affect how those binaries resolve.
  • One related probe, checkDebugger in src/debug/debugger.ts, still runs without a cwd. It was deliberately left out of this PR to keep the change focused on the cmake execution paths; happy to include it if maintainers prefer.
  • A minimal standalone reproduction (a fake cwd-sensitive cmake shim + a tiny CMake project + a script showing the shim succeeding in-project and failing from $HOME) is available and can be linked/attached on request.

…ims resolve

CMake Tools spawns several cmake child processes without a `cwd`, so they
inherit the extension host's `process.cwd()`, which is not guaranteed to be
the workspace folder. Directory-based version managers (mise, asdf, vfox, ...)
resolve the tool version by walking up from the current working directory, so
when the host cwd is outside the project their shim fails with e.g.
"No version is set for shim: cmake" and CMake Tools reports a bad/missing
CMake executable. This is launch-dependent, which is why it commonly appears
on Remote-WSL when the editor is started from the Windows GUI rather than via
`code .` inside the repo.

Set a project-relative working directory for the cmake invocations that were
missing one:

- cmakeExecutable.ts: add an optional `cwd` to `getCMakeExecutableInformation`
  (the version/`-E capabilities` probe) and thread the workspace/project folder
  from its callers (cmakeProject, extension, debuggerScriptDriver).
- cmakeDriver.ts: pass `binaryDir` as the build cwd (matching configure, which
  already uses `?? binaryDir`), and default `executeCommand` to `sourceDir`
  when no cwd is provided, covering other driver-routed cmake calls.
- cmakeTaskProvider.ts: default the task cwd to binaryDir/sourceDir/workspace.
- debuggerScriptDriver.ts: run the CMake script debugger in the project folder.

Related: microsoft#4603 (mise), microsoft#3359 (asdf), microsoft#1731 (working directory during configure).

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
scanDirForClangForMSVCKits probes cmake via getCMakeExecutableInformation
without a cwd. It runs for any `clang`-named binary found in the search
directories (the VS installation list is only consulted afterwards), so on
Linux/macOS with a mise/asdf-provided `clang` it triggers the same shim
resolution failure ("No version is set for shim: cmake") during kit scanning.

Pass the workspace folder as the probe cwd, matching the other call sites, so
directory-based version managers can resolve the shim.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
@danieleformichelli

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree company="Bending Spoons"

@hanniavalera

Copy link
Copy Markdown
Contributor

Daniele Formichelli (@danieleformichelli) Thank you for contributing this fix! It is quite appreciated! I reviewed the subprocess working-directory changes across CMake probing, builds, tasks, kit scanning, and script debugging, with particular attention to multi-root and nested-source projects, external build directories, version-manager shim caching, and regression risk for existing CMake workflows.

The overall direction is sound and directly addresses the underlying problem in #5005. I left a few comments about using the source directory for shim resolution and making the executable-information cache project-context aware. Thanks again for the clear explanation, focused implementation, and work to improve the experience!

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