Spec-Zone.ru › CMake 3.28

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

Примечание

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

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

Spec-Zone.ru

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