Spec-Zone.ru › CMake 3.20

cmake_language

Новое в версии 3.18.

Вызов мета-операций над командами CMake.

Синопсис

cmake_language(CALL <command> [<arg>...])
cmake_language(EVAL CODE <code>...)
cmake_language(DEFER <options>... CALL <command> [<arg>...])

Введение

Эта команда вызовет мета-операции над встроенными командами CMake или теми, которые созданы с помощью команд macro() или function().

cmake_language не вводит новую переменную или область политики.

Вызов команд

cmake_language(CALL <command> [<arg>...])

Вызывает именованную <command> с заданными аргументами (если таковые имеются). Например, код:

set(message_command "message")
cmake_language(CALL ${message_command} STATUS "Hello World!")

эквивалентен

message(STATUS "Hello World!")

Примечание

Для обеспечения согласованности кода следующие команды запрещены:

  • if / elseif / else / endif
  • while / endwhile
  • foreach / endforeach
  • function / endfunction
  • macro / endmacro

Вычисление кода

cmake_language(EVAL CODE <code>...)

Вычисляет <code>... как код CMake.

Например, код:

set(A TRUE)
set(B TRUE)
set(C TRUE)
set(condition "(A AND B) OR C")

cmake_language(EVAL CODE "
  if (${condition})
    message(STATUS TRUE)
  else()
    message(STATUS FALSE)
  endif()"
)

эквивалентен

set(A TRUE)
set(B TRUE)
set(C TRUE)
set(condition "(A AND B) OR C")

file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/eval.cmake "
  if (${condition})
    message(STATUS TRUE)
  else()
    message(STATUS FALSE)
  endif()"
)

include(${CMAKE_CURRENT_BINARY_DIR}/eval.cmake)

Отложенные вызовы

Новое в версии 3.19.

cmake_language(DEFER <options>... CALL <command> [<arg>...])

Планирует вызов именованной <command> с заданными аргументами (если таковые имеются) для выполнения в более позднее время. По умолчанию отложенные вызовы выполняются так, как будто они были написаны в конце файла CMakeLists.txt текущего каталога, за исключением того, что они выполняются даже после вызова return(). Ссылки на переменные в аргументах вычисляются в момент выполнения отложенного вызова.

Варианты:

DIRECTORY <dir>

Планирует вызов для конца заданного каталога вместо текущего каталога. <dir> может ссылаться на каталог исходного кода или соответствующий двоичный каталог. Относительные пути рассматриваются как относительные к текущему каталогу исходного кода.

Заданный каталог должен быть известен CMake, являясь либо корневым каталогом, либо добавленным с помощью add_subdirectory(). Кроме того, заданный каталог не должен быть завершён обработкой. Это означает, что он может быть текущим каталогом или одним из его предков.

ID <id>

Указывает идентификатор для отложенного вызова. <id> не может быть пустым и не может начинаться с заглавной буквы A-Z. <id> может начинаться с нижнего подчеркивания (_) только в том случае, если он был сгенерирован автоматически предыдущим вызовом, который использовал ID_VAR для получения идентификатора.

ID_VAR <var>

Указывает переменную, в которой будет храниться идентификатор отложенного вызова. Если ID <id> не указан, будет сгенерирован новый идентификатор, и сгенерированный идентификатор будет начинаться с нижнего подчеркивания (_).

Текущий запланированный список отложенных вызовов можно получить:

cmake_language(DEFER [DIRECTORY <dir>] GET_CALL_IDS <var>)

Это сохранит в <var> список, разделённый точкой с запятой идентификаторов отложенных вызовов. Идентификаторы относятся к области каталога, в которую отложены вызовы (т. е. где они будут выполнены), которая может отличаться от области, в которой они были созданы. Опция DIRECTORY может быть использована для указания области, для которой необходимо получить идентификаторы вызовов. Если эта опция не указана, будут возвращены идентификаторы вызовов для текущей области каталога.

Подробности конкретного вызова можно получить по его идентификатору:

cmake_language(DEFER [DIRECTORY <dir>] GET_CALL <id> <var>)

Это сохранит в <var> список, разделённый точкой с запятой, в котором первый элемент — имя вызываемой команды, а оставшиеся элементы — её невычисленные аргументы (любые содержащиеся ; символы включаются буквально и не могут быть отличимы от нескольких аргументов). Если несколько вызовов запланированы с одинаковым идентификатором, это извлекает первый из них. Если в указанной области DIRECTORY (или текущей области каталога, если опция DIRECTORY не указана) не запланирован ни один вызов с заданным идентификатором, в переменную сохранится пустая строка.

Отложенные вызовы можно отменить по их идентификатору:

cmake_language(DEFER [DIRECTORY <dir>] CANCEL_CALL <id>...)

Это отменяет все отложенные вызовы, соответствующие любому из указанных идентификаторов в указанной области DIRECTORY (или текущей области каталога, если опция DIRECTORY не указана). Неизвестные идентификаторы игнорируются без ошибок.

Примеры отложенных вызовов

Например, код:

cmake_language(DEFER CALL message "${deferred_message}")
cmake_language(DEFER ID_VAR id CALL message "Cancelled Message")
cmake_language(DEFER CANCEL_CALL ${id})
message("Immediate Message")
set(deferred_message "Deferred Message")

выводит:

Immediate Message
Deferred Message

Cancelled Message никогда не выводится, потому что его команда отменена. Ссылка на переменную deferred_message вычисляется не до места вызова, а при вызове, поэтому её можно установить после планирования отложенного вызова.

Для немедленного вычисления ссылок на переменные при планировании отложенного вызова, оберните его с помощью cmake_language(EVAL). Однако обратите внимание, что аргументы будут повторно вычислены в отложенном вызове, хотя этого можно избежать, используя аргументы в квадратных скобках. Например:

set(deferred_message "Deferred Message 1")
set(re_evaluated [[${deferred_message}]])
cmake_language(EVAL CODE "
  cmake_language(DEFER CALL message [[${deferred_message}]])
  cmake_language(DEFER CALL message \"${re_evaluated}\")
")
message("Immediate Message")
set(deferred_message "Deferred Message 2")

также выводит:

Immediate Message
Deferred Message 1
Deferred Message 2

© 2000–2021 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.20/command/cmake_language.html

Spec-Zone.ru

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