Spec-Zone.ru › CMake 3.31

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 будет существовать до того, как его потребители потребуют его. Подробности о проблеме см. в вопросе 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_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.31/policy/CMP0058.html

Spec-Zone.ru

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