使用 CMake、Clang 和 Ninja 在 Windows 上构建 c++ 项目

Posted

技术标签:

【中文标题】使用 CMake、Clang 和 Ninja 在 Windows 上构建 c++ 项目【英文标题】:Building c++ project on Windows with CMake, Clang and Ninja 【发布时间】:2014-04-30 10:06:05 【问题描述】:

我目前在 Windows 上安装了 cmake、clang 和 ninja。我正在尝试使用 CMake 生成一个 ninja 构建文件来编译一个非常简单的 hello world 程序。

我的 CMakeLists.txt 如下所示:

cmake_minimum_required(VERSION 2.8)
project(test_project)
add_executable(main main.cpp)

main.cpp 是一个简单的 hello world 程序。

在命令行上我运行这个:cmake -G Ninja ..,我得到以下错误:

-- The C compiler identification is Clang 3.5.0
clang.exe: error: no such file or directory: '/nologo'
clang.exe: error: no such file or directory: '/showIncludes'
-- The CXX compiler identification is Clang 3.5.0
clang.exe: error: no such file or directory: '/nologo'
clang.exe: error: no such file or directory: '/showIncludes'
-- Check for working C compiler using: Ninja
-- Check for working C compiler using: Ninja -- broken
CMake Error at C:/Program Files (x86)/CMake 2.8/share/cmake-2.8/Modules/CMakeTestCCompiler.cmake:61 (message):
  The C compiler "C:/llvm_build/RelWithDebInfo/bin/clang.exe" is
  not able to compile a simple test program.

  It fails with the following output:

   Change Dir: C:/test_proj/build/CMakeFiles/CMakeTmp



  Run Build Command:C:/ninja/ninja.exe cmTryCompileExec375034429

  [1/2] Building C object
  CMakeFiles\cmTryCompileExec375034429.dir\testCCompiler.c.obj


  [2/2] Linking C executable cmTryCompileExec375034429.exe


  FAILED: cmd.exe /c cd .  &&
  C:\llvm_build\RelWithDebInfo\bin\clang.exe
  CMakeFiles\cmTryCompileExec375034429.dir\testCCompiler.c.obj -o
  cmTryCompileExec375034429.exe && cd .


  clang.exe: error: unable to execute command: program not executable



  clang.exe: error: linker command failed with exit code 1 (use -v to see
  invocation)



  ninja: build stopped: subcommand failed.






  CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
  CMakeLists.txt:2 (project)


-- Configuring incomplete, errors occurred!
See also "C:/test_proj/build/CMakeFiles/CMakeOutput.log".
See also "C:/test_proj/build/CMakeFiles/CMakeError.log".

CMakeError.log 文件如下所示:

Compiling the C compiler identification source file "CMakeCCompilerId.c" failed.
Compiler: C:/llvm_build/RelWithDebInfo/bin/clang.exe 
Build flags: 
Id flags: 

The output was:
1
clang.exe: error: unable to execute command: program not executable
clang.exe: error: linker command failed with exit code 1 (use -v to see invocation)


Compiling the CXX compiler identification source file "CMakeCXXCompilerId.cpp" failed.
Compiler: C:/llvm_build/RelWithDebInfo/bin/clang++.exe 
Build flags: 
Id flags: 

The output was:
1
clang++.exe: error: unable to execute command: program not executable
clang++.exe: error: linker command failed with exit code 1 (use -v to see invocation)


Determining if the C compiler works failed with the following output:
Change Dir: C:/test_proj/build/CMakeFiles/CMakeTmp

Run Build Command:C:/ninja/ninja.exe cmTryCompileExec2120850158
[1/2] Building C object CMakeFiles\cmTryCompileExec2120850158.dir\testCCompiler.c.obj

[2/2] Linking C executable cmTryCompileExec2120850158.exe

FAILED: cmd.exe /c cd . && C:\llvm_build\RelWithDebInfo\bin\clang.exe     CMakeFiles\cmTryCompileExec2120850158.dir\testCCompiler.c.obj  -o cmTryCompileExec2120850158.exe   && cd .

clang.exe: error: unable to execute command: program not executable


clang.exe: error: linker command failed with exit code 1 (use -v to see invocation)


ninja: build stopped: subcommand failed.

似乎 cmake 正在尝试使用 Windows 选项 /nologo/showIncludes 测试 clang。我不知道如何告诉 cmake 传递正确的参数。

FWIW 我正在运行 64 位 Windows 7

编辑:

所以我查看了内置的 cmake 文件,发现 CMakeClDeps.cmake 文件是添加 /nologo /showIncludes 选项的罪魁祸首。看来,如果我将 Clang 设置为编译器,则 cmake 认为 Visual Studio 是编译器(它将 MSVC_C_ARCHITECTURE_ID 设置为 x86)。

我删除了CMakeDetermineCompilerId.cmake 中设置MSVC_C_ARCHITECTURE_ID 的行,重试后出现以下错误:

-- The C compiler identification is Clang 3.5.0
-- The CXX compiler identification is Clang 3.5.0
-- Check for working C compiler using: Ninja
-- Check for working C compiler using: Ninja -- broken
CMake Error at C:/Program Files (x86)/CMake 2.8/share/cmake-2.8/Modules/CMakeTestCCompiler.cmake:61 (message):
  The C compiler "C:/llvm_build/RelWithDebInfo/bin/clang.exe" is
  not able to compile a simple test program.

  It fails with the following output:

   Change Dir: C:/test_proj/build/CMakeFiles/CMakeTmp



  Run Build Command:C:/ninja/ninja.exe cmTryCompileExec2815594422

  [1/2] Building C object
  CMakeFiles\cmTryCompileExec2815594422.dir\testCCompiler.c.obj


  [2/2] Linking C executable cmTryCompileExec2815594422.exe


  FAILED: cmd.exe /c cd .  &&
  C:\llvm_build\RelWithDebInfo\bin\clang.exe
  CMakeFiles\cmTryCompileExec2815594422.dir\testCCompiler.c.obj -o
  cmTryCompileExec2815594422.exe && cd .


  clang.exe: error: unable to execute command: program not executable



  clang.exe: error: linker command failed with exit code 1 (use -v to see
  invocation)



  ninja: build stopped: subcommand failed.






  CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
  CMakeLists.txt:2 (project)


-- Configuring incomplete, errors occurred!
See also "C:/test_proj/build/CMakeFiles/CMakeOutput.log".
See also "C:/test_proj/build/CMakeFiles/CMakeError.log".

【问题讨论】:

你能试着在你的 cmake 文件的开头写上:remove_definitions( /nologo )remove_definitions( /showIncludes )吗?它可能有效,但如果有效,这是一个不错的小解决方法。 否则,你可以通过 CMakeCCompilerId.c 和 CMakeCXXCompilerId.cpp 看看是否有问题。 @Shingetsu 删除定义并没有改变任何东西,我通过查看这些文件也没有找到任何东西。但是,我确实找到了 /nologo /showIncludes 选项的来源并编辑了我的问题。 检查同一个文件是否设置了任何其他 MSVC 选项,并用 clang 替换它们。请注意,CMake 本身并不支持 clang(还)。您可以尝试手动覆盖 90% 的必需选项,如本文所示:***.com/questions/7031126/… 【参考方案1】:

不知道它是否有帮助,但我遇到了同样的错误。现在我可以在 Windows 上使用 clang(3.7.1)/ninja(1.6)/cmake(3.4.1) 在构建目录中执行以下操作进行编译:

    加载相关的vcvarsXX.bat文件(如"<Your Visual Studio location>\VC\vcvarsall.bat" x86) 将 CC 和 CXX 都设置为 clang-cl(而不是 clangclang++) 运行cmake -G Ninja <project> 运行cmake --build .

【讨论】:

您知道使用此设置生成的 compile_commands.json 文件是否可以提供给 clang-tidy 工具,或者 clan-tidy 工具是否需要 clang.exe 的命令行参数? 抱歉耽搁了,我不知道。【参考方案2】:

原来我收到的第二组错误是因为 clang 找不到链接器。我使用 Visual Studio 构建了 clang,但当时它找不到 Visual Studio 链接器。我所要做的就是在 Visual Studio 开发控制台中运行它。

CMake 仍然认为 clang 是一个 Visual Studio 编译器,因此在 CMakeDetermineCompilerId.cmake 文件中有一行如下所示:

set(MSVC_$lang_ARCHITECTURE_ID "$ARCHITECTURE_ID")

我把它改成这样

if (COMPILER_ID MATCHES "MSVC")
  set(MSVC_$lang_ARCHITECTURE_ID "$ARCHITECTURE_ID")
endif()

希望这不会破坏任何其他 CMake 功能。

【讨论】:

我仍然遇到问题 - 我没有遇到将其检测为 MSVC 的问题。我设置了 CMAKE_CXX_COMPILER_ID=Clang 但不知何故它以与您上次错误类似的方式失败。 这在 CMake 3.6.1 上对我不起作用。我仍然得到 /nologo 等导致编译测试程序失败的标志。我看到 CMAKE_DETERMINE_COMPILER_ID (在 CMakeDetermineCompilerId.cmake 中)始终设置父范围 MSVC_$lang_ARCHITECTURE_ID 并尝试仅设置它是否设置在本地范围内,但随后我得到 CMAKE_RC_COMPILER 未设置。

以上是关于使用 CMake、Clang 和 Ninja 在 Windows 上构建 c++ 项目的主要内容,如果未能解决你的问题,请参考以下文章

使用 ninja 和 clang++ 时 vim 中的快速修复列表

使用 CCMAKE 将 Clang 设置为自己的编译器后 ninja 出错

尝试在 Ubuntu 上配置 CMake 工具链

CMake / Ninja:当内容未知时递归“清理”输出目录......?

在 macOS 上使用 Ninja 进行 CMake GUI

CMake/Ninja 试图编译已删除的“.cpp”文件