【问题标题】:Generate CMake compile commands on Windows在 Windows 上生成 CMake 编译命令
【发布时间】:2021-09-06 18:58:27
【问题描述】:

我正在使用 Eclipse CDT、CMake 和 cmake4eclipse 插件在 Windows 上设置 C/C++ 构建环境。除了生成 compile_commands.json 之外,一切正常。 cmake4eclipse 插件需要此​​文件,以便使用两个 CMAKE_EXPORT_COMPILE_COMMANDS 提供程序进行自动包含检测等(据我理解正确)。

我正在使用 CMake (3.20) 和 ninja 的 Windows 版本以及 gcc 的 MSYS2 版本。所有工具都可以通过 PATH 变量访问(正如我已经提到的,编译工作正常)。

我的 cmake 命令大致如下:

cmake -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=ON -G Ninja "C:\\path\\to\\source" 

在配置过程中我总是收到警告

CMake Warning:
  Manually-specified variables were not used by the project:

    CMAKE_EXPORT_COMPILE_COMMANDS

并且构建目录中没有生成compile_commands.json。

我知道,当尝试为不受支持的生成器导出编译命令时,这通常是一个问题,例如视觉工作室。但由于我使用的是 ninja,我希望 JSON 文件能够成功生成。

有没有人遇到过类似的问题或有什么想法?

谢谢!

编辑: 这是message(STATUS "gen = ${CMAKE_GENERATOR}") 的输出:

cmake -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=ON  -G Ninja "C:\\path\\to\\source" 
-- The C compiler identification is GNU 10.2.0
-- The CXX compiler identification is GNU 10.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/msys64/usr/bin/cc.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/msys64/usr/bin/c++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- gen = Ninja
-- Configuring done
-- Generating done
CMake Warning:
  Manually-specified variables were not used by the project:

    CMAKE_EXPORT_COMPILE_COMMANDS


-- Build files have been written to: C:/path/to/build
10:52:57 Buildscript generation finished (took 9351 ms)

很遗憾,我无法发布我的整个 CMakeLists.txt,因为它属于我们公司的一个项目。顶层 CMakeLists.txt 没有定义任何目标,而是添加了几个 ExternalProjects 来支持交叉编译。

【问题讨论】:

  • 我尝试使用最小的 CMakeLists.txt 重现此问题,但未能成功。您能否使用基本的 CMakeLists.txt 尝试相同的工作流程,看看问题是否仍然存在?
  • 最小的意思是“cmake_minimum_required + project + add_executable”在源文件中带有int main() {return 0;}
  • 尝试message(STATUS "gen = ${CMAKE_GENERATOR}") 以确保生成器设置正确。
  • 你能发布完整的输出和你的 CMakeLists.txt 吗?
  • 感谢您的 cmets。在我的原始帖子中发布了完整的输出,包括message(STATUS "gen = ${CMAKE_GENERATOR}")

标签: eclipse cmake eclipse-cdt


【解决方案1】:

我能够使用以下 CMakeLists.txt 重现您的错误消息。这不是错误:

cmake_minimum_required(VERSION 3.20)
project(test)

然后我跑了

> cmake -G Ninja -S . -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
-- The C compiler identification is MSVC 19.28.29915.0
-- The CXX compiler identification is MSVC 19.28.29915.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.28.29910/bin/Hostx64/x64/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.28.29910/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
CMake Warning:
  Manually-specified variables were not used by the project:

    CMAKE_EXPORT_COMPILE_COMMANDS


-- Build files have been written to: D:/test/build

这样做的原因是,正如你所说,

顶层 CMakeLists.txt 没有定义任何目标,而是添加了几个 ExternalProjects 来支持交叉编译。

compile_commands.json 中不包含自定义目标的命令,只有在处理第一个编译目标(add_executableadd_library)时,CMake 才会检查该变量。

没有简单的解决办法;在您的每个子项目中设置CMAKE_EXPORT_COMPILE_COMMANDS 将为每个子项目生成一个compile_commands.json 文件。合并它们以便 Eclipse 能够理解结果超出了这个问题的范围。

这是ExternalProject 的一个更大问题的一部分——它分开了。它归结为自动创建一些相对复杂的自定义目标和命令,因此父项目不知道其子项目中发生了什么。

使用宿主工具进行交叉编译的更好方法是允许用户调用您的构建两次:第一次在一个目录中使用宿主工具链,第二次在不同目录中使用目标工具链并设置变量,以便第一次构建将扫描主机工具,而不是在目标构建中重新创建目标。 export()find_package() 命令对此很有用。

【讨论】:

  • 感谢您的帮助,亚历克斯!我已经认为这个警告是由我的顶级 CMakeLists.txt 中的 ExternalProject_Add() 引起的,但我也无法排除任何与工具兼容性相关的问题(因为构建过程在 Windows 上运行)。
  • 我不太喜欢 ExternalProject 方法(有时会导致不必要的重建问题)。我想我将来会尝试摆脱这种方法......
  • 还有一个问题:您能否提供一些关于在没有外部项目的情况下使用 CMake 进行交叉编译的资源?我真的不明白你所说的建造两次是什么意思。这种方法是否会涉及两个单独的“顶级”CMakeLists.txt?
  • 我实际上正在写一篇博客文章来更好地解释这项技术......但现在这是我为测试使用它的卤化物而编写的一个构建:github.com/halide/Halide/tree/master/test/integration/xc
  • 这个想法是将您的主机工具分离到不同的目录中,并根据您是否进行交叉编译而选择 add_subdirectory 或 find_package
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-29
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
  • 2011-03-23
  • 2010-10-12
  • 1970-01-01
相关资源
最近更新 更多