在 Windows 上生成 CMake 编译命令

Generate CMake compile commands on Windows

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

我正在使用 Windows 构建的 CMake (3.20) 和 ninja 以及 MSYS2 版本的 gcc。所有工具都可以通过 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

并且build目录下没有生成compile_commands.json

我知道在尝试为不受支持的生成器导出编译命令时,这通常是一个问题,例如Visual Studio。但由于我使用的是忍者,我希望能成功生成 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)

不幸的是我不能post我的整个CMakeLists.txt因为它属于我们公司的一个项目。顶级 CMakeLists.txt 没有定义任何目标,但添加了几个 ExternalProjects 来支持交叉编译。

我能够通过以下 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

之所以这样,是因为,如你所说,

The top-level CMakeLists.txt does not define any targets, but adds a couple of ExternalProjects to support cross-compilation.

自定义目标的命令不包含在 compile_commands.json 中,并且变量仅在处理第一个编译目标(add_executableadd_library)时由 CMake 检查。

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

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

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