From 21b7c191ab0113b3e3009a8563531cd576bda528 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 2 Mar 2026 17:20:12 +0000 Subject: [PATCH 1/3] Initial plan From 3fb215892694e53b6181ea7a6f311f45000fa9b3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 2 Mar 2026 17:34:21 +0000 Subject: [PATCH 2/3] Improve automatic MSVC dev environment setup with presets Detect VS Developer Environment signals from preset structure (VS generator, external toolset/architecture strategy) without requiring explicit CMAKE_CXX_COMPILER in cacheVariables. Add log.info hint when auto mode skips VS Dev Env on Windows. Fixes #4225 Co-authored-by: hanniavalera <90047725+hanniavalera@users.noreply.github.com> --- docs/cmake-presets.md | 20 +++++++++++ src/presets/preset.ts | 46 ++++++++++++++++++++----- test/unit-tests/presets/presets.test.ts | 43 ++++++++++++++++++++++- 3 files changed, 100 insertions(+), 9 deletions(-) diff --git a/docs/cmake-presets.md b/docs/cmake-presets.md index 8099f64482..9e38f12343 100644 --- a/docs/cmake-presets.md +++ b/docs/cmake-presets.md @@ -148,6 +148,26 @@ You can specify the name of a compiler on your `PATH` instance or an environment When you build with the Visual C++ toolset, CMake Tools automatically sources the environment from the latest version of the Visual Studio Build Tools installed on your system. You can specify a compiler version with the `toolset` option in `CMakePresets.json`. For more information, see [Configure Presets and Toolset Selection](https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html). +CMake Tools can detect the need for the VS Developer Environment from several signals in your preset. You do **not** need to explicitly set `CMAKE_CXX_COMPILER` to `cl` if any of the following are true: + +- Your preset uses a **Visual Studio generator** (e.g. `"generator": "Visual Studio 17 2022"`) +- Your preset specifies `"toolset": { "strategy": "external" }` (which means the IDE should set up the environment) +- Your preset specifies `"architecture": { "strategy": "external" }` + +For example, a Ninja preset that relies on MSVC can use `strategy: "external"` without setting compilers explicitly: + +```json +"generator": "Ninja", +"architecture": { + "value": "x64", + "strategy": "external" +}, +"toolset": { + "value": "v143", + "strategy": "external" +} +``` + A preset that builds for 64-bit Windows with `cl.exe` and a Visual Studio Generator might set compilers like this: ```json diff --git a/src/presets/preset.ts b/src/presets/preset.ts index 1ddd5d8e89..0a02d2e56e 100644 --- a/src/presets/preset.ts +++ b/src/presets/preset.ts @@ -961,6 +961,25 @@ async function getVsDevEnv(opts: VsDevEnvOptions): Promise { expect(args).to.include('-j'); expect(args).to.not.include('--parallel'); }); + + test('hasVsDevEnvSignals detects Visual Studio generator', () => { + expect(hasVsDevEnvSignals({ name: 'test', generator: 'Visual Studio 17 2022' })).to.eq(true); + expect(hasVsDevEnvSignals({ name: 'test', generator: 'Visual Studio 16 2019' })).to.eq(true); + expect(hasVsDevEnvSignals({ name: 'test', generator: 'Visual Studio 15 2017' })).to.eq(true); + }); + + test('hasVsDevEnvSignals detects external toolset strategy', () => { + expect(hasVsDevEnvSignals({ name: 'test', generator: 'Ninja', toolset: { value: 'v143', strategy: 'external' } })).to.eq(true); + }); + + test('hasVsDevEnvSignals detects external architecture strategy', () => { + expect(hasVsDevEnvSignals({ name: 'test', generator: 'Ninja', architecture: { value: 'x64', strategy: 'external' } })).to.eq(true); + }); + + test('hasVsDevEnvSignals returns false for Ninja with no MSVC signals', () => { + expect(hasVsDevEnvSignals({ name: 'test', generator: 'Ninja' })).to.eq(false); + }); + + test('hasVsDevEnvSignals returns false for no generator and no strategy', () => { + expect(hasVsDevEnvSignals({ name: 'test' })).to.eq(false); + }); + + test('hasVsDevEnvSignals returns false for set strategy (non-external)', () => { + expect(hasVsDevEnvSignals({ name: 'test', generator: 'Ninja', toolset: { value: 'v143', strategy: 'set' } })).to.eq(false); + expect(hasVsDevEnvSignals({ name: 'test', generator: 'Ninja', architecture: { value: 'x64', strategy: 'set' } })).to.eq(false); + }); + + test('hasVsDevEnvSignals returns false for string toolset and architecture', () => { + expect(hasVsDevEnvSignals({ name: 'test', generator: 'Ninja', toolset: 'v143' })).to.eq(false); + expect(hasVsDevEnvSignals({ name: 'test', generator: 'Ninja', architecture: 'x64' })).to.eq(false); + }); + + test('hasVsDevEnvSignals detects combined external toolset and architecture', () => { + expect(hasVsDevEnvSignals({ + name: 'test', + generator: 'Ninja', + toolset: { value: 'v143', strategy: 'external' }, + architecture: { value: 'x64', strategy: 'external' } + })).to.eq(true); + }); }); From fb3ccf9e6c91ae9591033681b848d6444054b0f4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 2 Mar 2026 17:35:13 +0000 Subject: [PATCH 3/3] Update log.info hint to mention all auto-detection signals Co-authored-by: hanniavalera <90047725+hanniavalera@users.noreply.github.com> --- src/presets/preset.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/presets/preset.ts b/src/presets/preset.ts index 0a02d2e56e..ba00e84039 100644 --- a/src/presets/preset.ts +++ b/src/presets/preset.ts @@ -1072,7 +1072,7 @@ export async function tryApplyVsDevEnv(preset: ConfigurePreset, workspaceFolder: } else { log.info(localize( 'vs.dev.env.skipped.hint', - 'Configure preset "{0}": VS Developer Environment was not set up automatically. To enable it, set CMAKE_CXX_COMPILER to "cl" in cacheVariables, or set cmake.useVsDeveloperEnvironment to "always".', + 'Configure preset "{0}": VS Developer Environment was not set up automatically. To enable it, set CMAKE_CXX_COMPILER to "cl" in cacheVariables, use a Visual Studio generator, set toolset or architecture strategy to "external", or set cmake.useVsDeveloperEnvironment to "always".', preset.name )); }