let cmake use clang-cl when use ninja, not clang++ ,so people can migrate from visual studio nmake to ninja

let cmake use clang-cl when use ninja, not clang++ ,so people can migrate from visual studio nmake to ninja.

OpenClaw (codebuddy.ai) output translate:

Here’s a natural, technically-accurate English translation (good for a Slack/PR comment or bug report):


Found the root cause — it’s a CMake 4.4 misdetection bug for clang-cl:

In rules.ninja, every C++ compile rule has its command hard-coded to clang++ (the GCC driver):

command = ${LAUNCHER}${CODE_CHECK}clang++  /nologo -TP $DEFINES ...

But the flags are MSVC-style clang-cl flags​ (/nologo, /Fo, /EHsc, -target x86_64-pc-windows-msvc, -clang:-MD…). CMake identified the compiler as Clang with FRONTEND_VARIANT=MSVC, yet still emitted the binary name as clang++ following the plain-Clang convention — instead of clang-cl. It’s the same binary​ (identical size, literally the same clang); launched as clang++ it’s in GCC mode and rejects /nologo, while launched as clang-cl it’s in CL mode and accepts everything.

The link rule uses lld-link.exe (full path, fine), and the RC rule uses rc (needs to be on PATH). So as long as we swap clang++clang-cl in the rules and add LLVM/bin + SDK/bin to PATH, it builds.

I’ll first replace all clang++ with clang-cl in rules.ninja and verify:

chinese orijin output.


A few wording notes

  • 判定 bug​ → “misdetection bug” / “compiler-identification bug” (more natural than “judgment bug”)
  • 写死​ → “hard-coded”
  • GCC 驱动 / CL 模式​ → “GCC driver” / “CL mode” (standard CMake/LLVM terminology)
  • 不认 / 全部认​ → “rejects … / accepts everything”
  • 编过​ → “it builds” / “the build goes through”

想要更偏 upstream bug report​ 的正式语气,或者更短的 IRC/Slack 口语版也可以告诉我~

找到根因了,是个 CMake 4.4 对 clang-cl 的判定 bug

rules.ninja 里所有 C++ 编译规则的命令被写死成了 clang++(GCC 驱动):

command = ${LAUNCHER}${CODE_CHECK}clang++  /nologo -TP $DEFINES ...

但 flags 却是 clang-cl(MSVC)风格的(/nologo/Fo/EHsc-target x86_64-pc-windows-msvc-clang:-MD…)。CMake 把编译器识别成了 Clang + FRONTEND_VARIANT=MSVC,却按 Clang 的套路把二进制名写成了 clang++,而不是 clang-cl。同一个二进制(大小完全一致,是同一份 clang),用 clang++ 起来是 GCC 模式,不认 /nologo;用 clang-cl 起来是 CL 模式,全部认。

链接规则用的是 lld-link.exe(完整路径,没问题),RC 规则用的是 rc(PATH 上要有)。所以只要把规则里的 clang++ 改成 clang-cl,并把 LLVM/bin 和 SDK/bin 加进 PATH,就能编过。

我先把 rules.ninja 里的 clang++ 全部替换成 clang-cl 并验证:

cmake output

[10/35] Building CXX object CMakeFiles\photol.dir\photol\photol\lang2.cpp.obj
FAILED: [code=1] CMakeFiles/photol.dir/photol/photol/lang2.cpp.obj
clang++ /nologo -TP -DNDEBUG -DNOMINMAX -DUNICODE -DWIN32_LEAN_AND_MEAN -D_UNICODE -D_USRDLL -D_WINDOWS -Dphotol_EXPORTS -ID:\Community -ID:\Community\third\opencv\opencv-4.8.0_build_vs2019_x64\install\include -ID:\Community\third\libmediainfo_AllInclusive\MediaInfoLib\Source -ID:\Community\third\libmediainfo_AllInclusive\ZenLib\Source -ID:\Community\third\osg-3rdparty-cmake-master\giflib\giflib-5.2.1 -ID:\Community\third\sqlite3mc-1.5.4\sqlite3mc-1.5.4 /DWIN32 /D_WINDOWS /GR /EHsc -target x86_64-pc-windows-msvc /Zi /Ob0 /Od /RTC1 -std:c++17 -MT -include photol/photol/stdafx.h -clang:-MD -clang:-MTCMakeFiles\photol.dir\photol\photol\lang2.cpp.obj -clang:-MFCMakeFiles\photol.dir\photol\photol\lang2.cpp.obj.d /FoCMakeFiles\photol.dir\photol\photol\lang2.cpp.obj /FdCMakeFiles\photol.dir\ -c – D:\Community\photol\photol\lang2.cpp
clang++: error: unknown argument: ‘-std:c++17’
clang++: error: unknown argument: ‘-clang:-MD’
clang++: error: unknown argument: ‘-clang:-MTCMakeFiles\photol.dir\photol\photol\lang2.cpp.obj’
clang++: error: unknown argument: ‘-clang:-MFCMakeFiles\photol.dir\photol\photol\lang2.cpp.obj.d’
clang++: error: no such file or directory: ‘/nologo’
clang++: error: no such file or directory: ‘/DWIN32’
clang++: error: no such file or directory: ‘/D_WINDOWS’
clang++: error: no such file or directory: ‘/GR’
clang++: error: no such file or directory: ‘/EHsc’
clang++: error: no such file or directory: ‘/Zi’
clang++: error: no such file or directory: ‘/Ob0’
clang++: error: no such file or directory: ‘/Od’
clang++: error: no such file or directory: ‘/RTC1’
clang++: warning: treating ‘c-header’ input as ‘c+±header’ when in C++ mode, this behavior is deprecated [-Wdeprecated]
clang++: error: no such file or directory: ‘photol/photol/stdafx.h’
clang++: error: no such file or directory: ‘/FoCMakeFiles\photol.dir\photol\photol\lang2.cpp.obj’
clang++: error: no such file or directory: ‘/FdCMakeFiles\photol.dir’
ninja: build stopped: subcommand failed.

find solve plan:

quick in a sentence:

replace all rules.ninja in cmake build folder

the “clang++” to “clang-cl”.

https://wenku.csdn.net/column/1zh7u2zy91

fix it upstream in cmake: CMAKE__SIMULATE_ID=MSVC or clang-cl

Here’s a clean, technically-precise English version — good for a Slack/Teams update or a bug-thread reply:


The real reason for that string of errors

It’s not a typo in your command — it’s a CMake 4.4 misdetection bug for clang-cl: CMake identifies the compiler as Clang + MSVC frontend, yet hard-codes the binary name as clang++ (the GCC driver) in every C++ compile rule, while all the flags are MSVC-style clang-cl flags​ — /nologo, /Fo, /EHsc, -target x86_64-pc-windows-msvc… Once clang++ launches it’s in GCC mode, so naturally it doesn’t accept those /-prefixed args.

Linking uses lld-link.exe (full path, fine), and RC uses rc (needs the SDK bin on PATH).

Fix I applied (already in effect)

  • Replaced all clang++clang-cl in build/CMakeFiles/rules.ninja (10 compile rules), so the same clang runs in CL mode​ and accepts all the flags.
  • Added to the build env PATH: C:\Program Files\LLVM\bin + Windows SDK bin\x64 (provides clang-cl and rc).
  • Running ninja -C build paint now, in the background (task hgsdqx).

:warning: One caveat: if you ever re-run cmake to re-configure, it will regenerate rules.ninja and write clang++ back — you’ll need to re-apply the swap. A normal incremental ninja build won’t trigger this.

Once it finishes (rebuilding photol + linking OpenCV takes a while), I’ll get auto-notified and report success/failure plus the paint.exe artifact path. You can also run the same steps on your local PowerShell — the core is that rules.ninja substitution.


Slightly more concise / chat-friendly variant

The errors aren’t from your command — it’s CMake 4.4 misdetecting clang-cl: it sees Clang+MSVC frontend but emits clang++ (GCC driver) in all C++ rules while passing MSVC-style /nologo /Fo /EHsc -target …. clang++ = GCC mode → rejects / flags. Link uses lld-link.exe (ok), RC needs rc on PATH.

Fix live: swapped clang++clang-cl in build/CMakeFiles/rules.ninja (10 rules) + added LLVM/bin & SDK/bin/x64 to PATH. ninja -C build paint running in bg (task hgsdqx).

:warning: Re-running cmake regenerates rules.ninja and reverts to clang++ — incremental ninja is safe. Will ping you with result + paint.exe path once photol+OpenCV finish.

需要我顺手写成 upstream CMake issue 的英文报告(带最小复现步骤)也可以说~

# 1) 把 rc.exe 所在目录加入当前会话 PATH(改版本号以你实际 SDK 为准)
$sdk = “C:\Program Files (x86)\Windows Kits\10”
$ver = “10.0.28000.0”
$env:PATH = $env:PATH + “;$sdk\bin\$ver\x64”

2) 配置(生成 Ninja 构建文件到 build/)

& “C:\Program Files\CMake\bin\cmake.exe” -B D:\Community\build -S D:\Community -G Ninja `
“-DCMAKE_MAKE_PROGRAM=C:\ProgramData\chocolatey\bin\ninja.exe” `
“-DCMAKE_C_COMPILER=C:\Program Files\LLVM\bin\clang-cl.exe” `
“-DCMAKE_CXX_COMPILER=C:\Program Files\LLVM\bin\clang-cl.exe”

3) 编译 paint(及依赖的 photol 库 + OpenCV 静态链接)

& C:\ProgramData\chocolatey\bin\ninja.exe -C D:\Community\build paint

刚才那串报错的真正原因

  • 不是你命令敲错,是 CMake 4.4 对 clang-cl 的判定 bug:它把编译器认成 Clang + MSVC 前端,却在所有 C++ 编译规则里把二进制名写死成 clang++(GCC 驱动),而参数全是 clang-cl(MSVC)风格的 /nologo/Fo/EHsc-target x86_64-pc-windows-msvc…。clang++ 一跑起来是 GCC 模式,自然不认这些 / 开头的参数。
  • 链接用的是 lld-link.exe(完整路径,OK),RC 用的是 rc(需要 SDK bin 在 PATH)。

我做的修复(已生效)

  1. build/CMakeFiles/rules.ninja 里的 clang++ 全部改成 clang-cl(10 处编译规则),让同一份 clang 以 CL 模式运行,参数就全认了。
  2. 给编译环境补上 PATH:C:\Program Files\LLVM\bin + Windows SDK 的 bin\x64(提供 clang-clrc)。
  3. 重新 ninja -C build paint,后台运行中(task hgsdqx)。

:warning: 一个注意点:以后如果你重跑 cmake 重新 configure,它会把 rules.ninja 重新生成、clang++ 又写回来,需要再替换一次。正常的 ninja 增量构建不会触发这个。

编完(photol 库重编 + 链 OpenCV 比较耗时)会自动通知我,我再把成功/失败和 paint.exe 产物路径报给你。你也可以直接在你本机 PowerShell 用同样的方式跑——核心是那条 rules.ninja 的替换。