Run cmake subprocesses in the project directory so version-manager shims resolve correctly - #5006
Conversation
…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>
|
@microsoft-github-policy-service agree company="Bending Spoons" |
|
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! |
This change addresses item #5005
This changes visible behavior
The following changes are proposed:
clangbinary, so it hits shim users on Linux/macOS too).process.cwd().cwdthroughgetCMakeExecutableInformation(...)(thecmake --version/-E capabilitiesprobe) and pass the workspace/project folder from every caller (extension.ts,cmakeProject.ts,debuggerScriptDriver.ts).sourceDir, the build invocation tobinaryDir, and build tasks tobinaryDir || sourceDir || workspaceFolder.The purpose of this change
Users whose
cmakeis provided by a directory-based version manager (mise, asdf, vfox, ...) install a shim onPATH. 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 acwd, so the child inherits the extension host'sprocess.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.: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
cwdonly when the caller didn't already specify one, so existing behavior for explicitly-set working directories is unchanged.checkDebuggerinsrc/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.cmakeshim + 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.