Spec-Zone.ru › CMake 3.24

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 работает таким образом.

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

Поскольку вышеуказанный подход не сообщает CMake, какая пользовательская команда генерирует byproduct.txt, генератор Ninja не имеет достаточной информации, чтобы добавить побочный продукт в качестве выходного файла любого правила. CMake 2.8.12 и выше обходят эту проблему, разрешая проектам, использующим вышеуказанный подход, выполнять сборку, генерируя phony правила сборки, чтобы сообщить Ninja о том, что такие отсутствующие файлы могут быть проигнорированы. Однако это обходное решение не позволяет 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.24.2 выводит предупреждение при обнаружении неизвестных зависимостей в деревьях сборки вне исходного каталога, если политика не установлена, а затем использует поведение 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.24/policy/CMP0058.html

Spec-Zone.ru

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