Проблема зависимости cmake / make (OBJECT) - не перестраивается при изменении заголовка - PullRequest
0 голосов
/ 15 мая 2019

Мне удалось воспроизвести проблему, возникшую у меня с гораздо большим проектом. Я думаю, что это настолько минимально, насколько я могу это сделать

При наличии ключа явно добавил заголовок в список источников, и его редактирование все равно не вызывает перекомпиляции чего-либо.

~/src/test2/_build£ cat ../CMakeLists.txt
cmake_minimum_required (VERSION 3.14)
set (CMAKE_CXX_STANDARD 11)
# various explicit CXX sets are necessary for this tiny project and don't exist in larger original
project(moduletest CXX)
set (HEADER_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
add_subdirectory(submod)
add_library(moduletest_static STATIC "$<TARGET_OBJECTS:submod>")
set_target_properties(moduletest_static PROPERTIES LINKER_LANGUAGE CXX)

~/src/test2/_build£ cat ../submod/CMakeLists.txt
include_directories (${HEADER_DIR})
add_library(submod OBJECT compileme.cpp ../includeme.h)

~/src/test2/_build£ cat ../submod/compileme.cpp
#include "includeme.h"
int function()
{
  return 5;
}

Сделать вывод следующим образом:

~/src/test2/_build£ touch ../submod/compileme.cpp
~/src/test2/_build£ make
[ 50%] Building CXX object submod/CMakeFiles/submod.dir/compileme.cpp.o
[ 50%] Built target submod
[100%] Linking CXX static library libmoduletest_static.a
[100%] Built target moduletest_static
~/src/test2/_build£ touch ../includeme.h
~/src/test2/_build£ make
[ 50%] Built target submod
[100%] Built target moduletest_static

Если я уберу использование include_directories и просто #include "../includeme.h" в моем файле cpp, все будет работать правильно, независимо от моего вызова add_library. (Но это точно не вариант в моем реальном проекте)

Следует также отметить, что «Сканирование зависимостей целевого подмодуля» - это что-то вроде красной сельди. В моем более крупном проекте я попытался прикоснуться к одному файлу cpp, чтобы это произошло. Другие cpp-файлы, которые должны были скомпилироваться, по-прежнему не выполнялись.

Использование target_include_directories ничего не исправило, независимо от абсолютных / относительных путей.

Проблема исчезает с cmake -GNinja ..

Ответы [ 3 ]

2 голосов
/ 15 мая 2019

Я просто вспоминаю, как в последний раз смотрел, как CMake генерирует файловые зависимости для «исходных файлов» при использовании генератора Makefile.

Шаг «Сканирование зависимостей» - это когдаCMake сканирует «исходные файлы» и создает правила построения зависимостей для этого «исходного файла».Это делается с использованием REGEX и нескольких других правил (пропускаются некоторые правила предварительной обработки).Как правило, он пропускает то, что считает системным заголовочным файлом, который может включать файл, найденный при использовании абсолютного пути включения.Думайте об этом как о ложном срабатывании.

Обычные обходные пути - не использовать include_directories() и избегать абсолютных путей при использовании target_include_directories().Поэтому попробуйте вместо этого использовать target_include_directories( submod PRIVATE .. ).

2 голосов
/ 15 мая 2019

Мой первоначальный ответ:

Скорее всего, вы лаете не на то дерево. Источник к заголовку зависимостями управляет не CMake, а генератор, как Заголовки не принимают участия в компиляции библиотек напрямую. В вашем В этом случае необходимо обнаружить грязный заголовок и восстановить файл .cpp. Заголовки могут быть перечислены в источниках, но это только делает их видимыми в несколько IDE и добавляет проверку работоспособности, когда они существуют.

Но для случая GNU make это не совсем правда. Более новые инструменты, такие как ninja, могут генерировать зависимости от исходного к заголовку при компиляции кода. Поэтому CMake отслеживает только зависимости библиотеки от источника, а базовый инструмент отслеживает источник-заголовка.

Для make, CMake использует свой внутренний механизм для создания файлов depen.make для файлов объектов .cpp.o. Алгоритм не идеален и может не работать для абсолютных путей, переданных include_directories.

Для справки: изначально (после шага генерации) он создает depend.make файлы с комментариями:

# Empty dependencies file for submod.
# This may be replaced when dependencies are built.

Когда вызывается make и объекты создаются впервые, файл заполняется:

# CMAKE generated file: DO NOT EDIT!
# Generated by "Unix Makefiles" Generator, CMake Version 3.14

submod/CMakeFiles/submod.dir/compileme.cpp.o: ../includeme.h
submod/CMakeFiles/submod.dir/compileme.cpp.o: ../submod/compileme.cpp

Спасибо @Fred, что заставили меня прочитать все об этом.

Также эта проблема уже обсуждалась в SO: Обработка зависимостей заголовочных файлов с помощью cmake

И историческое прочтение: http://www.aosabook.org/en/cmake.html

0 голосов
/ 16 мая 2019

Фред и R2RT оба привели меня к правильному ответу на мою проблему. Моя сборка cmake (вытащенная из основного репозитория github) была проблемой. Я переключился на сборку дистрибутива, и эта проблема исчезла. Я не совсем уверен, почему моя сборка была проблемой, но .... у вас есть. (cmake v. перешел с 3.14 на 3.10, но я считаю, что моя сборка - это проблема, а не 3.14)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...