当我使用CMake和Ninja构建时,clang ++忽略-MD标志

时间:2019-01-11 21:51:43

标签: c++ cmake clang++ ninja

我创建了一个非常简单的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标志?

2 个答案:

答案 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

但是,无论我是否指定-MDtarget_compile_options,该依存关系信息都是可用的。