Windows: Generate/config fail to capture all required properties for Ninja

This may be by design, but I had expected that if I configured a project on Windows from within the developer environment, I wouldn’t need to be in the developer environment later to build it.

Simple use case:

cmake_minimum_required (VERSION 3.24)
project (test LANGUAGES CXX)
add_executable(test test.cpp)
// test.cpp
#include <stdio.h>
int main() {}
PS> cmake
cmake: The term 'cmake' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

PS> powershell   # create new environment scope

# '>>' to denote this new sub-shell with its own env scope
PS>> enable-vsdevshell
**********************************************************************
** Visual Studio 2022 Developer PowerShell v17.4.4
** Copyright (c) 2022 Microsoft Corporation
**********************************************************************

PS>> cmake -G Ninja -B ./build -S .
-- The CXX compiler identification is MSVC 19.34.31937.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.34.31933/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/oliver.smith/Playground/cmake-winenv/build

PS>> get-command cmake
CommandType     Name          Version    Source
-----------     ----          -------    ------
Application     cmake.exe     3.24.2022… C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe

PS>> exit

# return to outer scope, original non-dev environment

PS> & "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" --build ./build --target test
[1/2] Building CXX object CMakeFiles\test.dir\test.cpp.obj
FAILED: CMakeFiles/test.dir/test.cpp.obj
C:\PROGRA~1\MICROS~3\2022\COMMUN~1\VC\Tools\MSVC\1434~1.319\bin\Hostx64\x64\cl.exe  /nologo /TP   /DWIN32 /D_WINDOWS /EHsc /Zi /Ob0 /Od /RTC1 -MDd /showIncludes /FoCMakeFiles\test.dir\test.cpp.obj /FdCMakeFiles\test.dir\ /FS -c C:\Users\oliver.smith\Playground\cmake-winenv\test.cpp
C:\Users\oliver.smith\Playground\cmake-winenv\test.cpp(1): fatal error C1034: stdio.h: no include path set
ninja: build stopped: subcommand failed.

PS> enable-vsdevshell
**********************************************************************
** Visual Studio 2022 Developer PowerShell v17.4.4
** Copyright (c) 2022 Microsoft Corporation
**********************************************************************

PS> & "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" --build ./build --target test
[2/2] Linking CXX executable test.exe

This problem affects GUI applications that can’t easily enter the developer environment before invoking commands, and I’d like to try encoding build-system specifics into my wrapper-that-uses-cmake-to-abstract-away-build-system-specifics.

Is there a way I can tell cmake to write all the absolute paths it needs at configure/generate time so that it won’t rely on environment parameters in --build?

It is. Non-IDE generators expect the compiler to work in the ambient environment as there are no mechanisms to load environment variables.

CMake also doesn’t know, in general, what variables matter for any given compiler and even if they were recorded, how to merge with an existing environment is an open question (e.g., not clobbering PATH and instead knowing how to add just the entries that matter).