clang ++ игнорирует флаг -MD при сборке с помощью CMake и ninja - PullRequest
0 голосов
/ 12 января 2019

Я создал очень простой проект 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 голосов
/ 12 января 2019

Кланг не виновник, это Нинга

Объяснение пропавшего 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

Затем см. руководство по Ninja: зависимости заголовка C / C ++ -> deps:

Deps (Доступно с ниндзя 1.3.)

Оказывается, что для больших проектов (и особенно в Windows, где файловая система работает медленно) загрузка этих файлов зависимостей при запуске происходит медленно.

Ninja 1.3 может вместо этого обрабатывать зависимости сразу после их создания и сохранять сжатую форму с той же информацией во внутренней базе данных Ninja.

Ниндзя поддерживает эту обработку в двух формах.

deps = gcc указывает, что инструмент выводит зависимости в стиле gcc в форме файлов Makefile. Добавление этого к приведенному выше примеру заставит Ninja обработать файл деплоя сразу после завершения компиляции, затем удалите файл .d (который используется только как временный) .

(мой акцент).

0 голосов
/ 12 января 2019

Похоже, что эквивалентная информация о зависимости заголовка доступна через 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.

...