Spec-Zone.ru › CMake 3.29

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_policy() или cmake_minimum_required(). Если она не установлена, CMake выводит предупреждение при обнаружении неизвестных зависимостей в сборке вне исходного дерева и использует поведение OLD.

Настройка политики должна быть в области действия в конце верхнего уровня 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.29/policy/CMP0058.html

Spec-Zone.ru

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