Interesting issue trying to compile windows RC files using Ninja & MSVC

Recently while trying to build QT6 with CMake, Ninja and MSVC, I encountered an issue around MSVC RC files.
The specific error message is as such:

[1/3] Building RC object CMakeFiles\main.dir\Test.rc.res
FAILED: CMakeFiles/main.dir/Test.rc.res
"C:/Program Files/CMake/bin/cmcldeps.exe" RC C:\Users\Yaram\projects\cmake-test\Test.rc CMakeFiles\main.dir\Test.rc.res.d CMakeFiles\main.dir\Test.rc.res "Note: including file: " "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.29.30133/bin/Hostx64/x64/cl.exe" C:\PROGRA~2\WI3CF2~1\10\bin\100183~1.0\x64\rc.exe   -DWIN32 -D_DEBUG /fo CMakeFiles\main.dir\Test.rc.res C:\Users\Yaram\projects\cmake-test\Test.rc
'C:/Program' is not recognized as an internal or external command,
operable program or batch file.
[2/3] Building CXX object CMakeFiles\main.dir\main.cpp.obj
ninja: build stopped: subcommand failed.

And the 'C:/Program' is not recognized as an internal or external command, operable program or batch file. message changes to The filename, directory name, or volume label syntax is incorrect. if CMake is installed in a path with no spaces.

After a bit of troubleshooting I narrowed the problem down to the cmcldeps.exe path in rules.ninja having quotes around it, which Ninja seemingly doesn’t like. Removing the quotes results in a successful build when the cmcldeps.exe contains no spaces.

This issue is present atleast in CMake versions 3.18.6, 3.21.2, and the latest master (256785749e152c4d587df4bd6805b87fe70572a7)

I’ve noticed that the other executable paths in rules.ninja are specified in short form (eg. C:\PROGRA~2\MICROS~1\2019\COMMUN~1\VC\Tools\MSVC\1429~1.301\bin\Hostx64\x64\cl.exe), perhaps the path to cmcldeps.exe should be as well?

I’m running CMake and Ninja within a Visual Studio 2019 x64 native command prompt (AKA with vcvarsall x64 ran) to make CMake/Ninja use cl and the other MSVC tools rather than gcc-flavor clang.

Please let me know if this is an actual bug and if I should create a issue in the bug tracker, or if I’ve just done something stupid!

I’ve create a very simple repo for reproducing the bug here.

The steps to reproduce are as such:

  1. Clone the test repo above
  2. Open a Visual Studio 2019 x64 Native Tools Command Prompt (or just run vcvarsall x64)
  3. cd to the test repo source directory, run mkdir build, then cd build
  4. Run cmake -G Ninja .. to generate the Ninja build files
  5. Run cmake --build . or ninja to run the build and trigger the issue

Your minimal example doesn’t have a cmake_minimum_required() command at the beginning. Does adding that change the behavior for you? The minimal nature of that project looks like something I’d expect our test suite would already cover, but I haven’t checked specifically.

I added a cmake_minimum_required command, no change to behaviour. This is consistent with results from the QT6 CMake scripts which contain the command.

I’ve submited a PR here containing a fix I implemented, though I’m unsure if the fix is the best suited for the CMake codebase, since I’m unfamiliar with it.

I’ll look into the tests myself and try to determine if there’s one that covers this specific situation.

I found the VSResource test which appears to test the specific functionality in question. I ran the test locally under an MSVC & Ninja environment and got the test to fail and reproduce the issue, but the test appears to succeed in the test:windows-vs2019-x64-ninja CI job.