Spec-Zone.ru › CMake 3.23

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 "Canceled 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–2022 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.23/command/cmake_language.html

Spec-Zone.ru

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