if
Условно выполнить группу команд.
Аннотация
if(<condition>) <commands> elseif(<condition>) # optional block, can be repeated <commands> else() # optional block <commands> endif()
Оценивает аргумент condition в блоке if в соответствии с синтаксисом условий, описанным ниже. Если результат истинный, то commands в блоке if выполняются. В противном случае обрабатываются необязательные блоки elseif. Наконец, если ни один condition не является истинным, commands в необязательном блоке else выполняются.
По унаследованным причинам команды else() и endif() допускают необязательный аргумент <condition>. Если он используется, он должен быть точной копией аргумента открывающей команды if.
Синтаксис условий
Следующий синтаксис применяется к аргументу condition в блоках if, elseif и while().
Составные условия вычисляются в следующем порядке приоритетов:
- Скобки.
- Унарные тесты, такие как EXISTS, COMMAND и DEFINED.
- Бинарные тесты, такие как EQUAL, LESS, LESS_EQUAL, GREATER, GREATER_EQUAL, STREQUAL, STRLESS, STRLESS_EQUAL, STRGREATER, STRGREATER_EQUAL, VERSION_EQUAL, VERSION_LESS, VERSION_LESS_EQUAL, VERSION_GREATER, VERSION_GREATER_EQUAL и MATCHES.
- Унарный логический оператор NOT.
- Бинарные логические операторы AND и OR, слева направо, без короткого замыкания.
Основные выражения
-
if(<constant>) -
Истина, если константа равна
1,ON,YES,TRUE,Y, или ненулевому числу (включая числа с плавающей точкой). Ложь, если константа равна0,OFF,NO,FALSE,N,IGNORE,NOTFOUND, пустой строке или заканчивается суффиксом-NOTFOUND. Имена булевых констант нечувствительны к регистру. Если аргумент не является одной из этих констант, он рассматривается как переменная или строка (см. Расширение переменных ниже) и применяется одна из следующих двух форм. -
if(<variable>) -
Истина, если переменная определена значением, которое не является ложной константой. Ложь в противном случае, включая случай, когда переменная не определена. Обратите внимание, что аргументы макросов не являются переменными. Переменные среды также не могут быть проверены таким образом, например,
if(ENV{some_var})всегда будет оцениваться как ложь. -
if(<string>) -
Строка в кавычках всегда оценивается как ложь, если только:
Логические операторы
-
if(NOT <condition>) -
Истина, если условие не истинно.
-
if(<cond1> AND <cond2>) -
Истина, если оба условия были бы истинными по отдельности.
-
if(<cond1> OR <cond2>) -
Истина, если хотя бы одно условие было бы истинным по отдельности.
-
if((condition) AND (condition OR (condition))) -
Условия внутри скобок вычисляются сначала, а затем оставшееся условие вычисляется так же, как и в других примерах. При наличии вложенных скобок вложенные скобки вычисляются как часть вычисления условия, которое их содержит.
Проверки существования
-
if(COMMAND command-name) -
Истина, если заданное имя является командой, макросом или функцией, которые можно вызвать.
-
if(POLICY policy-id) -
Истина, если заданное имя является существующей политикой (формата
CMP<NNNN>). -
if(TARGET target-name) -
Истина, если заданное имя является существующим логическим именем цели, созданным вызовом команды
add_executable(),add_library()илиadd_custom_target(), которая уже была вызвана (в любом каталоге). -
if(TEST test-name) -
Новое в версии 3.3: Истина, если заданное имя является существующим именем теста, созданным командой
add_test().
-
if(DEFINED <name>|CACHE{<name>}|ENV{<name>}) -
Истина, если переменная, переменная кэша или переменная среды с заданным
<name>определена. Значение переменной не имеет значения. Обратите внимание на следующие замечания:- Аргументы макросов не являются переменными.
- Невозможно напрямую проверить, является ли
<name>переменной без кэша. Выражениеif(DEFINED someName)будет истинным, если существует либо переменная кэша, либо переменная без кэшаsomeName. В сравнении выражениеif(DEFINED CACHE{someName})будет истинным только если существует переменная кэшаsomeName. Оба выражения нужно проверить, если нужно узнать, существует ли переменная без кэша:if(DEFINED someName AND NOT DEFINED CACHE{someName}).
Новое в версии 3.14: Добавлена поддержка
CACHE{<name>}переменных. -
if(<variable|string> IN_LIST <variable>) -
Новое в версии 3.3: Истина, если заданный элемент содержится в именованной списковой переменной.
Операции с файлами
-
if(EXISTS path-to-file-or-directory) -
Истина, если указанный файл или каталог существует. Поведение определено только для явных полных путей (начальный
~/не расширяется как домашний каталог и рассматривается как относительный путь). Разрешает символические ссылки, т.е. если указанный файл или каталог является символической ссылкой, возвращает истину, если целевой объект символической ссылки существует. -
if(file1 IS_NEWER_THAN file2) -
Истина, если
file1новее, чемfile2, или если один из двух файлов не существует. Поведение определено только для полных путей. Если отметки времени файлов совпадают, сравнениеIS_NEWER_THANвозвращает истину, чтобы любые зависимые операции сборки произошли в случае ничьи. Это включает случай передачи одного и того же имени файла для file1 и file2. -
if(IS_DIRECTORY path-to-directory) -
Истина, если заданное имя является каталогом. Поведение определено только для полных путей.
-
if(IS_SYMLINK file-name) -
Истина, если заданное имя является символической ссылкой. Поведение определено только для полных путей.
-
if(IS_ABSOLUTE path) -
Истина, если заданный путь является абсолютным. Обратите внимание на следующие специальные случаи:
- Пустой
pathоценивается как ложь. - На хостах Windows любой
path, начинающийся с буквы диска и двоеточия (например,C:), прямой слеш или обратный слеш, будет оцениваться как истина. Это означает, что путь, подобныйC:no\base\dirбудет оцениваться как истина, даже если часть пути, не относящаяся к диску, относительна. - На хостах, отличных от Windows, любой
path, начинающийся с тильды (~), оценивается как истина.
- Пустой
Сравнения
-
if(<variable|string> MATCHES regex) -
Истина, если заданная строка или значение переменной соответствует заданному регулярному выражению. См. Спецификацию регулярных выражений для формата регулярных выражений.
Новое в версии 3.9:
()группы попадают в переменныеCMAKE_MATCH_<n>.
-
if(<variable|string> LESS <variable|string>) -
Истина, если заданная строка или значение переменной является допустимым числом и меньше правого.
-
if(<variable|string> GREATER <variable|string>) -
Истина, если заданная строка или значение переменной является допустимым числом и больше правого.
-
if(<variable|string> EQUAL <variable|string>) -
Истина, если заданная строка или значение переменной является допустимым числом и равно правому.
-
if(<variable|string> LESS_EQUAL <variable|string>) -
Новое в версии 3.7: Истина, если заданная строка или значение переменной является допустимым числом и меньше или равно правому.
-
if(<variable|string> GREATER_EQUAL <variable|string>) -
Добавлена в версии 3.7: Истина, если значение заданной строки или переменной является допустимым числом и больше или равно значению справа.
-
if(<variable|string> STRLESS <variable|string>) -
Истина, если значение заданной строки или переменной лексикографически меньше строки или переменной справа.
-
if(<variable|string> STRGREATER <variable|string>) -
Истина, если значение заданной строки или переменной лексикографически больше строки или переменной справа.
-
if(<variable|string> STREQUAL <variable|string>) -
Истина, если значение заданной строки или переменной лексикографически равно строке или переменной справа.
-
if(<variable|string> STRLESS_EQUAL <variable|string>) -
Добавлена в версии 3.7: Истина, если значение заданной строки или переменной лексикографически меньше или равно строке или переменной справа.
-
if(<variable|string> STRGREATER_EQUAL <variable|string>) -
Добавлена в версии 3.7: Истина, если значение заданной строки или переменной лексикографически больше или равно строке или переменной справа.
Сравнения версий
-
if(<variable|string> VERSION_LESS <variable|string>) -
Сравнение целочисленных номеров версий покомпонентно (формат версии —
major[.minor[.patch[.tweak]]], пропущенные компоненты обрабатываются как ноль). Любой нецелочисленный компонент версии или нецелочисленная хвостовая часть компонента версии фактически обрезает строку в этом месте.
-
if(<variable|string> VERSION_GREATER <variable|string>) -
Сравнение целочисленных номеров версий покомпонентно (формат версии —
major[.minor[.patch[.tweak]]], пропущенные компоненты обрабатываются как ноль). Любой нецелочисленный компонент версии или нецелочисленная хвостовая часть компонента версии фактически обрезает строку в этом месте.
-
if(<variable|string> VERSION_EQUAL <variable|string>) -
Сравнение целочисленных номеров версий покомпонентно (формат версии —
major[.minor[.patch[.tweak]]], пропущенные компоненты обрабатываются как ноль). Любой нецелочисленный компонент версии или нецелочисленная хвостовая часть компонента версии фактически обрезает строку в этом месте.
-
if(<variable|string> VERSION_LESS_EQUAL <variable|string>) -
Добавлена в версии 3.7: Сравнение целочисленных номеров версий покомпонентно (формат версии —
major[.minor[.patch[.tweak]]], пропущенные компоненты обрабатываются как ноль). Любой нецелочисленный компонент версии или нецелочисленная хвостовая часть компонента версии фактически обрезает строку в этом месте.
-
if(<variable|string> VERSION_GREATER_EQUAL <variable|string>) -
Добавлена в версии 3.7: Сравнение целочисленных номеров версий покомпонентно (формат версии —
major[.minor[.patch[.tweak]]], пропущенные компоненты обрабатываются как ноль). Любой нецелочисленный компонент версии или нецелочисленная хвостовая часть компонента версии фактически обрезает строку в этом месте.
Расширение переменных
Команда if была написана очень рано в истории CMake, до синтаксиса оценки переменных ${}, и для удобства оценивает переменные, именованные её аргументами, как показано в вышеприведённых сигнатурах. Обратите внимание, что обычная оценка переменных с помощью ${} применяется до того, как команда if даже получит аргументы. Следовательно, код, подобный
set(var1 OFF)
set(var2 "var1")
if(${var2})
предстаёт перед командой if как
if(var1)
и оценивается в соответствии с документированным выше случаем if(<variable>). Результатом является OFF, что ложно. Однако, если мы удалим ${} из примера, то команда увидит
if(var2)
что истинно, потому что var2 определена как var1, что не является ложным константой.
Автоматическая оценка применяется в других случаях, когда приведенный выше синтаксис условий принимает <variable|string>:
- Сначала проверяется, является ли левый аргумент
MATCHESопределённой переменной, если да, то используется значение переменной, иначе используется исходное значение. - Если левый аргумент
MATCHESотсутствует, он возвращает ложь без ошибки - Оба левых и правых аргумента
LESS,GREATER,EQUAL,LESS_EQUAL, иGREATER_EQUAL, независимо проверяются на предмет того, являются ли они определёнными переменными, если да, используются их определённые значения, в противном случае используется исходное значение. - Оба левых и правых аргумента
STRLESS,STRGREATER,STREQUAL,STRLESS_EQUAL, иSTRGREATER_EQUALнезависимо проверяются на предмет того, являются ли они определёнными переменными, если да, используются их определённые значения, в противном случае используется исходное значение. - Оба левых и правых аргумента
VERSION_LESS,VERSION_GREATER,VERSION_EQUAL,VERSION_LESS_EQUAL, иVERSION_GREATER_EQUALнезависимо проверяются на предмет того, являются ли они определёнными переменными, если да, используются их определённые значения, в противном случае используется исходное значение. - Правый аргумент
NOTпроверяется на предмет того, является ли он булевой константой, если да, то используется значение, в противном случае предполагается, что это переменная, и она разыменовывается. - Левые и правые аргументы
ANDиORнезависимо проверяются на предмет того, являются ли они булевыми константами, если да, они используются как таковые, в противном случае предполагается, что это переменные, и они разыменовываются.
Изменено в версии 3.1: Для предотвращения неоднозначности, потенциальные имена переменных или ключевых слов могут быть указаны в Цитата аргумента или Скобочный аргумент. Цитата или скобочный аргумент переменной или ключевого слова будет интерпретироваться как строка, а не разыменовываться или интерпретироваться. См. политику CMP0054.
Автоматическое оценивание не применяется для переменных среды или кэша Ссылки на переменные. Их значения должны быть указаны как $ENV{<name>} или $CACHE{<name>} там, где синтаксис вышеуказанных условий принимает <variable|string>.
© 2000–2022 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.23/command/if.html