Spec-Zone.ru › CMake 3.19

CMP0058

Новая версия с 3.3.

Ninja требует, чтобы побочные продукты пользовательских команд были явными.

Когда промежуточный файл, сгенерированный во время сборки, используется в дорогостоящей операции или большой деревом зависимостей, можно уменьшить объём работы для инкрементальной пересборки, обновив только метку времени файла, когда его содержимое изменится. С этим подходом правило генерации должно иметь отдельный выходной файл, который всегда обновляется с новой меткой времени, которая новее, чем любые зависимости правила, чтобы инструмент сборки повторно запускал правило только при изменении входных данных. Мы называем отдельный выходной файл свидетелем правила, а сгенерированный файл — побочным продуктом правила.

Побочные продукты не могут быть перечислены в качестве выходных данных, потому что их метки времени могут быть старше входных данных. Ни один инструмент сборки (например, make) существовавший во время разработки CMake, не имеет способа выразить побочные продукты. Поэтому версии CMake до 3.2 не имели возможности указать их. Проекты обычно оставляли побочные продукты не объявленными в правилах, которые их генерируют. Например:

add_custom_command(
  OUTPUT witness.txt
  COMMAND ${CMAKE_COMMAND} -E copy_if_different
          ${CMAKE_CURRENT_SOURCE_DIR}/input.txt
          byproduct.txt # timestamp may not change
  COMMAND ${CMAKE_COMMAND} -E touch witness.txt
  DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/input.txt
  )
add_custom_target(Provider DEPENDS witness.txt)
add_custom_command(
  OUTPUT generated.c
  COMMAND expensive-task -i byproduct.txt -o generated.c
  DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/byproduct.txt
  )
add_library(Consumer generated.c)
add_dependencies(Consumer Provider)

Это хорошо работает для всех генераторов, кроме Ninja. Инструмент сборки Ninja видит правило, перечисляющее byproduct.txt в качестве зависимости и не видит правила, перечисляющее его как выходное. Тогда Ninja жалуется, что нет способа удовлетворить зависимость и прекращает сборку, даже если есть зависимости только по порядку, которые гарантируют, что byproduct.txt будет существовать до того, как ему потребуются потребители. Подробнее об этой проблеме см. в Ninja Issue 760.

Вместо того, чтобы оставлять побочные продукты не объявленными в правилах, которые их генерируют, Ninja ожидает, что побочные продукты будут перечислены вместе с другими выходными данными. Такие правила могут быть помечены опцией restat, которая сообщает Ninja проверить метки времени выходных данных после выполнения правил. Это предотвращает ненужную пересборку зависимостей, вызванную побочными продуктами, метки времени которых не меняются.

Поскольку вышеуказанный подход не сообщает CMake, какая пользовательская команда генерирует byproduct.txt, генератор Ninja не имеет достаточной информации, чтобы добавить побочный продукт как выходное значение любого правила. CMake 2.8.12 и выше обходят эту проблему и позволяют проектам, использующим вышеуказанный подход, собираться, генерируя phony правила сборки, чтобы сообщить Ninja, что он может игнорировать такие отсутствующие файлы. Однако это решение обходит проблему, предотвращая диагностику отсутствующей зависимости. Оно также плохо работает в сборках из исходного кода, где каждая зависимость пользовательской команды, даже от исходных файлов, должна обрабатываться таким образом, потому что CMake не имеет достаточной информации, чтобы узнать, какие файлы генерируются как побочные продукты пользовательских команд.

CMake 3.2 представил опцию BYPRODUCTS для команд add_custom_command() и add_custom_target(). Эта опция позволяет явно указать побочные продукты:

add_custom_command(
  OUTPUT witness.txt
  BYPRODUCTS byproduct.txt # explicit byproduct specification
  COMMAND ${CMAKE_COMMAND} -E copy_if_different
          ${CMAKE_CURRENT_SOURCE_DIR}/input.txt
          byproduct.txt # timestamp may not change
...

Опция BYPRODUCTS используется генератором Ninja для перечисления побочных продуктов среди выходных данных пользовательских команд, которые их генерируют, и игнорируется другими генераторами.

CMake 3.3 и выше предпочитают требовать от проектов явного указания побочных продуктов пользовательских команд, чтобы избежать использования обходного пути правила phony. Политика CMP0058 была введена для обеспечения совместимости с существующими проектами, которым всё ещё нужен обходной путь.

Эта политика не оказывает влияния на генераторы, кроме Ninja. Поведение OLD для этой политики заключается в генерации правил Ninja phony для неизвестных зависимостей в дереве сборки. Поведение NEW для этой политики — не генерировать их и вместо этого потребовать от проектов явно указать пользовательские команды BYPRODUCTS.

Эта политика была введена в версии CMake 3.3. Версия CMake 3.19.0-rc3 предупреждает о неизвестных зависимостях в сборках вне исходного дерева, если политика не установлена, а затем использует поведение OLD. Используйте команду cmake_policy() для явного задания политики в OLD или NEW. Установка политики должна быть в области действия в конце файла верхнего уровня CMakeLists.txt проекта и имеет глобальное действие.

Примечание

Поведение OLD политики deprecated by definition и может быть удалено в будущей версии CMake.

© 2000–2020 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.19/policy/CMP0058.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API