vscode-cmake-tools icon indicating copy to clipboard operation
vscode-cmake-tools copied to clipboard

[Bug] Impossible to use CMake Tools with custom Ninja install on Windows

Open Rawalanche opened this issue 6 months ago • 6 comments

Brief Issue Summary

It does not seem to be possible to use CMake tools with custom Ninja executable.

Setup:

  1. I have acquired Ninja using winget, I have added ninja to PATH environment variable, and I have verified it works:
PS C:\Users\rawal> Get-Command ninja
>>

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Application     ninja.exe                                          0.0.0.0    C:\Users\rawal\AppData\Local\Microsoft\WinGet\Packages\Ninja-build.Ninja_Microsoft.Winget.Source_8wekyb3d8bbwe\ninja.exe
  1. I have Visual Studio Community 2022 with MSVC compiler.
  2. I have VSCode on Windows with latest CMake and CMake extension.

VSCode Project: I have generated CMake project using CMake: Quick Start wizard. It generated simple CMakeLists.txt:

cmake_minimum_required(VERSION 3.10.0)
project(Terraform VERSION 0.1.0 LANGUAGES C CXX)

add_executable(Terraform main.cpp)

as well as CMakePresets.json:

{
    "version": 8,
    "configurePresets": [
        {
            "name": "Ninja",
            "displayName": "Custom configure preset",
            "description": "Sets Ninja generator, build and install directory",
            "generator": "Ninja",
            "binaryDir": "${sourceDir}/out/build/${presetName}",
            "cacheVariables": {
                "CMAKE_BUILD_TYPE": "Debug",
                "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}"
            }
        }
    ]
}

The CMake configuration does not work:

[cmake] -- The C compiler identification is unknown
[cmake] -- The CXX compiler identification is unknown
[cmake] CMake Error at CMakeLists.txt:2 (project):
[cmake]   No CMAKE_C_COMPILER could be found.
[cmake] 
[cmake]   Tell CMake where to find the compiler by setting either the environment
[cmake]   variable "CC" or the CMake cache entry CMAKE_C_COMPILER to the full path to
[cmake]   the compiler, or to the compiler name if it is in the PATH.

This can be easily solved by setting "cmake.useVsDeveloperEnvironment" to "always", however it just kicks the problem down the road, as now, VS Developer Environment will kill all global environment variables including PATH which defines path to Ninja:

[preset] Ninja is not set on PATH, trying to use C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja\ninja.exe

So I end up in this circular problem, where Ninja build needs to know path to cl.exe which VS Developer Environment provides but doing so, it deletes the PATH variable leading to Ninja.exe. This causes the CMake Tools to fall back to some stale, internal Ninja.exe executable.

I do not want to be relying on a failure fallback. I want to be using my own up to date Ninja executable. How do I do that?

Curiously, it also appears that automatic detection of VS Developer Environment setup does not seem to work as described: Image When Ninja is defined in PATH environment variable and set as Cmake Generator, "cmake.useVsDeveloperEnvironment" set to "auto" will still not trigger.

CMake Tools Diagnostics

{
  "os": "win32",
  "vscodeVersion": "1.103.0",
  "cmtVersion": "1.22.5",
  "configurations": [
    {
      "folder": "d:\\Projects\\Software\\Terraform",
      "cmakeVersion": "3.31.6",
      "configured": true,
      "generator": "Ninja",
      "usesPresets": true,
      "compilers": {}
    }
  ],
  "cpptoolsIntegration": {
    "isReady": false,
    "hasCodeModel": false,
    "activeBuildType": "",
    "buildTypesSeen": [],
    "requests": [],
    "responses": [],
    "partialMatches": [],
    "targetCount": 0,
    "executablesCount": 0,
    "librariesCount": 0,
    "targets": []
  },
  "settings": [
    {
      "communicationMode": "automatic",
      "useCMakePresets": "auto",
      "configureOnOpen": true
    }
  ]
}

Debug Log

[proc] Executing command: "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" --version
[proc] Executing command: "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" -E capabilities
[kit] Successfully loaded 4 kits from C:\Users\rawal\AppData\Local\CMakeTools\cmake-tools-kits.json
[presetController] Reading and validating the presets file "D:\Projects\Software\Terraform\CMakePresets.json"
[presetController] Successfully validated D:\Projects\Software\Terraform\CMakePresets.json against presets schema
[presetController] Expanding presets file D:\Projects\Software\Terraform\CMakePresets.json
[presetController] Successfully expanded presets file D:\Projects\Software\Terraform\CMakePresets.json
[main] Configuring project: Terraform 
[proc] Executing command: "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=D:/Projects/Software/Terraform/out/install/Ninja -S D:/Projects/Software/Terraform -B D:/Projects/Software/Terraform/out/build/Ninja -G Ninja
[cmake] -- The C compiler identification is unknown
[cmake] -- The CXX compiler identification is unknown
[cmake] CMake Error at CMakeLists.txt:2 (project):
[cmake]   No CMAKE_C_COMPILER could be found.
[cmake] 
[cmake]   Tell CMake where to find the compiler by setting either the environment
[cmake]   variable "CC" or the CMake cache entry CMAKE_C_COMPILER to the full path to
[cmake]   the compiler, or to the compiler name if it is in the PATH.
[cmake] 
[cmake] 
[cmake] CMake Error at CMakeLists.txt:2 (project):
[cmake]   No CMAKE_CXX_COMPILER could be found.
[cmake] 
[cmake]   Tell CMake where to find the compiler by setting either the environment
[cmake]   variable "CXX" or the CMake cache entry CMAKE_CXX_COMPILER to the full path
[cmake]   to the compiler, or to the compiler name if it is in the PATH.
[cmake] 
[cmake] 
[cmake] -- Configuring incomplete, errors occurred!
[proc] The command: "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=D:/Projects/Software/Terraform/out/install/Ninja -S D:/Projects/Software/Terraform -B D:/Projects/Software/Terraform/out/build/Ninja -G Ninja exited with code: 1

Additional Information

No response

Rawalanche avatar Aug 13 '25 11:08 Rawalanche

Hi @Rawalanche , thank you for reporting this issue. We tried to check this issue in Visual Studio Code v1.103.1 + CMake Tools v1.21.36. We can use the custom Ninja and generate cache. Please refer to this video. Could you please recheck this issue? If this does not work for you, please let us know. Thanks.

Image

yanghhhhhhh avatar Aug 14 '25 07:08 yanghhhhhhh

Hi @Rawalanche , thank you for reporting this issue. We tried to check this issue in Visual Studio Code v1.103.1 + CMake Tools v1.21.36. We can use the custom Ninja and generate cache. Please refer to this video. Could you please recheck this issue? If this does not work for you, please let us know. Thanks.

Hello,

thank you very much for taking the time to show me the steps. I am however still a bit confused:

  1. What is the point of "cmake.generator" user setting if it is unable to find ninja executable defined in PATH?
  2. What is needed to make the "cmake.useVsDeveloperEnvironment" set to "auto" work correctly when using ninja?

Currently, the only way to avoid having to start vscode through developer command prompt is to force it to "always" which kind of defeats the point of build system autodetection and automatic environment setup. And the autodetection can not work if the "cmake.generator" setting does not work, and it is not clear what its needed to make "cmake.generator" setting find custom Ninja install location on Windows.

Specifying CMAKE_MAKE_PROGRAM feels more like a workaround. AFAIK the whole point of CMake Tools extension is to abstract these internal variables from user by more user-friendly VSCode-integrated setup. It's clear that the systems for that are in place (such as the two configuration settings mentioned above), but it is not clear what's needed to make them work reliably.

Rawalanche avatar Aug 14 '25 07:08 Rawalanche

Hi @Rawalanche , thanks for your reply. For the first issue, the "cmake.generator" is the name of the generator that is being used to generate the build files. (e.g. Unix Makefiles, Ninja, etc.), please refer to https://cmake.org/cmake/help/latest/variable/CMAKE_GENERATOR.html. For the second, when using the cl.exe compiler or Ninja, if cmake.useVsDeveloperEnvironment is set to auto, CMake Tools will attempt to detect and apply the appropriate version of Visual Studio environment variables. When set to always, it will force the use of Visual Studio environment variables. Thanks.

yanghhhhhhh avatar Aug 15 '25 07:08 yanghhhhhhh

Hi @Rawalanche , thanks for your reply. For the first issue, the "cmake.generator" is the name of the generator that is being used to generate the build files. (e.g. Unix Makefiles, Ninja, etc.), please refer to https://cmake.org/cmake/help/latest/variable/CMAKE_GENERATOR.html. For the second, when using the cl.exe compiler or Ninja, if cmake.useVsDeveloperEnvironment is set to auto, CMake Tools will attempt to detect and apply the appropriate version of Visual Studio environment variables. When set to always, it will force the use of Visual Studio environment variables. Thanks.

Thanks, although I am not sure you actually answered my question. You've linked me to https://cmake.org/cmake/help/latest/variable/CMAKE_GENERATOR.html which states:

The value of this variable should never be modified by project code. A generator may be selected via the cmake -G option, interactively in cmake-gui(1), or via the CMAKE_GENERATOR environment variable.

If that is truly the case then why does CMake Tools extension expose it as user facing setting?: Image

For the second, when using the cl.exe compiler or Ninja, if cmake.useVsDeveloperEnvironment is set to auto, CMake Tools will attempt to detect and apply the appropriate version of Visual Studio environment variables. When set to always, it will force the use of Visual Studio environment variables.

That's the issue - it seems broken. The description clearly says:

Selecting auto will only apply the Visual Studio environment when we detect a supported compiler (cl, clang, clang-cl, clang-cpp, clang++), or the Ninja generator is being used.

That does not seem to be the case. Using Ninja generator will not set up the required VS environment variables.

In other words, the constellation of settings on the screenshot below should result in project that builds with Ninja and is able to find the cl.exe due to the VS environment variables being set (without the need to launch VSCode from developer command promt): Image Currently, that is not the case. Either these settings are broken, or their description is wrong. Either way, something is not the way it should be.

Rawalanche avatar Aug 15 '25 17:08 Rawalanche

@Rawalanche Thanks for the detailed information.

@gcampbell-msft Could you please take a look at this issue? Thanks.

yanghhhhhhh avatar Aug 19 '25 07:08 yanghhhhhhh

@Rawalanche Thanks for letting us know about this issue. I've taken a look, and it sounds like the core issues are the following:

  1. Our behavior for invoking the VS Developer Environment is not matching our description. You have Ninja on the PATH, but it then doesn't invoke the developer environment in order to find the compilers. Is this correct? Have you tried manually putting your compilers on PATH?
  2. The Use Vs Developer Environment setting has an issue where it clobbers the environment variables such that it overtakes what you may have set in your environment. When developing, it was a goal to avoid this, but it seems there is a bug in this.

Assuming (unless you respond differently) that these are the correct core issues, we will do our best to prioritize this amongst our other work and get to it when we can.

In the meantime, have you tried similar updates to your PATH that you made for ninja, for your compilers?

gcampbell-msft avatar Aug 25 '25 10:08 gcampbell-msft