Spec-Zone.ru › CMake 3.25

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 таким образом см. в обсуждении этой проблемы в 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.25.1 предупреждает при обнаружении неизвестных зависимостей в деревьях сборки вне исходного кода, если политика не установлена, и затем использует поведение OLD . Используйте команду cmake_policy() для явного задания политики на OLD или NEW. Настройка политики должна находиться в рамках действия верхнего уровня CMakeLists.txt файла проекта и имеет глобальное действие.

Примечание

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

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

Spec-Zone.ru

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