Spec-Zone.ru › CMake

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, что такие отсутствующие файлы допустимы. Однако это обходное решение не позволяет 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/latest/policy/CMP0058.html

Spec-Zone.ru

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