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..ba00e84039 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); + }); });