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, PATH_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>) -
Истина, если
pathявляется каталогом. Поведение определено только для полных путей.Ложь, если заданный путь — пустая строка.
-
if(IS_SYMLINK <path>) -
Истина, если указанный путь является символической ссылкой. Поведение определено только для полных путей.
-
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>) -
Истина, если значение заданной строки или переменной можно интерпретировать как вещественное число (как в C
double) и оно меньше, чем значение справа.
-
if(<variable|string> GREATER <variable|string>) -
Истина, если значение заданной строки или переменной можно интерпретировать как вещественное число (как в C
double) и оно больше, чем значение справа.
-
if(<variable|string> EQUAL <variable|string>) -
Истина, если значение заданной строки или переменной можно интерпретировать как вещественное число (как в C
double) и оно равно значению справа.
-
if(<variable|string> LESS_EQUAL <variable|string>) -
Новое в версии 3.7.
Истина, если значение заданной строки или переменной можно интерпретировать как вещественное число (как в C
double) и оно меньше или равно значению справа.
-
if(<variable|string> GREATER_EQUAL <variable|string>) -
Новое в версии 3.7.
Истина, если значение заданной строки или переменной можно интерпретировать как вещественное число (как в C
double) и оно больше или равно значению справа.
-
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(<variable|string> PATH_EQUAL <variable|string>) -
Новое в версии 3.24.
Сравнивает два пути покомпонентно. Два пути равны только в том случае, если все компоненты обоих путей совпадают. Несколько разделителей путей фактически сводятся к одному разделителю, но обратите внимание, что обратные слэши не преобразуются в косые. Другое нормализация путей не выполняется.
Покомпонентное сравнение лучше, чем сравнение по строкам, из-за обработки нескольких разделителей путей. В следующем примере выражение оценивается как истинное с помощью
PATH_EQUAL, но ложное сSTREQUAL:# comparison is TRUE if ("/a//b/c" PATH_EQUAL "/a/b/c") ... endif() # comparison is FALSE if ("/a//b/c" STREQUAL "/a/b/c") ... endif()Дополнительные сведения см. в cmake_path(COMPARE).
Расширение переменных
Команда 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–2024 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.28/command/if.html