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 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 3.20.0-rc3 предупреждает, когда обнаруживает неизвестные зависимости в сборке вне исходного дерева, если политика не задана, а затем использует поведение OLD . Используйте команду cmake_policy() для явного задания политики в OLD или NEW. Параметр политики должен быть в области действия в конце верхнего уровня CMakeLists.txt файла проекта и имеет глобальное влияние.
Примечание
Поведение OLD политики — deprecated by definition и может быть удалено в будущих версиях CMake.
© 2000–2021 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.20/policy/CMP0058.html