我创建了一个非常简单的C ++ / CMake项目:
CMakeLists.txt(注意-MD
标志):
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
add_executable(moop main.cc)
target_compile_options(moop PRIVATE -MD)
main.cc:
#include "moop.hh"
int main( int, char** ) { return 0; }
moop.hh:
#pragma once
从项目根目录运行以下命令:
mkdir build && cd build
cmake -G Ninja -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ..
cat compile_commands.json
cat compile_commands.json
输出(请注意-MD
标志):
{
"directory": "/home/zbardoo/moop/build",
"command": "/usr/bin/clang++ -MD -o CMakeFiles/moop.dir/main.cc.o -c /home/zbardoo/moop/main.cc",
"file": "/home/zbardoo/moop/main.cc"
}
如果我随后运行ninja
,则可执行文件moop
已成功构建。但是,moop.cc.d
找不到。但是,如果我然后从command
复制并粘贴compile_commands.json
值并运行它:
/usr/bin/clang++ -MD -o CMakeFiles/moop.dir/main.cc.o -c /home/zbardoo/moop/main.cc
出现文件/home/zbardoo/moop/build/CMakeFiles/moop.dir/main.cc.d
:
zbardoo@localhost:~/moop/build$ cat CMakeFiles/moop.dir/main.cc.d
CMakeFiles/moop.dir/main.cc.o: /home/zbardoo/moop/main.cc \
/home/zbardoo/moop/moop.hh
为什么ninja
不遵守-MD
文件中的compile_commands.json
标志?
答案 0 :(得分:1)
C不是罪魁祸首,而是宁加
找不到CMakeFiles/moop.dir/main.cc.d
的说明
如果您查看生成的build/rules.ninja
并找到:
rule CXX_COMPILER__moop
depfile = $DEP_FILE
deps = gcc
command = /usr/bin/clang++ $DEFINES $INCLUDES $FLAGS -MD -MT $out -MF $DEP_FILE -o $out -c $in
description = Building CXX object $out
注意:
deps = gcc
然后参见the Ninja manual: C/C++ header dependencies -> deps
:
单位 (自Ninja 1.3起可用。)
事实证明,对于大型项目(尤其是在文件系统较慢的Windows上),在启动时加载这些依赖文件的速度很慢。
Ninja 1.3可以在生成依赖项后立即对其进行处理,并将相同信息的压缩形式保存在Ninja内部数据库中。
Ninja支持两种处理方式。
deps = gcc指定该工具以Makefiles的形式输出gcc样式的依赖项。 将其添加到上面的示例中将使Ninja在编译完成后立即处理depfile, 然后删除.d文件(仅用作临时文件)。
(我的重点)。
答案 1 :(得分:-1)
似乎可以通过ninja -t deps
获得等效的标头依赖项信息:
zbardoo@localhost:~/moop/build$ ninja -t deps
CMakeFiles/moop.dir/main.cc.o: #deps 2, deps mtime 1547243911 (VALID)
../main.cc
../moop.hh
但是,无论我是否指定-MD
至target_compile_options
,该依存关系信息都是可用的。