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