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().
Составные условия вычисляются в следующем порядке приоритетов:
- Скобки.
- Унарные тесты, такие как COMMAND, POLICY, TARGET, TEST, EXISTS, IS_READABLE, IS_WRITABLE, IS_EXECUTABLE, IS_DIRECTORY, IS_SYMLINK, IS_ABSOLUTE и 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, IN_LIST, IS_NEWER_THAN и 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(IS_READABLE).if(EXISTS)может быть изменено в будущем, чтобы проверять только существование файла.
-
if(IS_READABLE <path-to-file-or-directory>) -
Добавлен в версии 3.29.
Истинно, если указанный файл или каталог доступен для чтения. Поведение определено только для явных полных путей (ведущий
~/не расширяется как домашний каталог и рассматривается как относительный путь). Разрешает символические ссылки; т.е. если указанный файл или каталог является символической ссылкой, возвращает истинно, если целевой объект символической ссылки доступен для чтения.Ложно, если указанный путь является пустой строкой.
-
if(IS_WRITABLE <path-to-file-or-directory>) -
Добавлен в версии 3.29.
Истинно, если указанный файл или каталог доступен для записи. Поведение определено только для полных путей (ведущий
~/не расширяется как домашний каталог и рассматривается как относительный путь). Разрешает символические ссылки, т.е. если указанный файл или каталог является символической ссылкой, возвращает true, если целевой объект символической ссылки доступен для записи.Ложно, если указанный путь является пустой строкой.
-
if(IS_EXECUTABLE <path-to-file-or-directory>) -
Добавлен в версии 3.29.
Истинно, если указанный файл или каталог доступен для выполнения. Поведение определено только для полных путей (ведущий
~/не расширяется как домашний каталог и рассматривается как относительный путь). Разрешает символические ссылки, т.е. если указанный файл или каталог является символической ссылкой, возвращает true, если целевой объект символической ссылки доступен для выполнения.Ложно, если указанный путь является пустой строкой.
-
if(<file1> IS_NEWER_THAN <file2>) -
Истинно, если
file1новее, чемfile2, или если один из двух файлов не существует. Поведение определено только для полных путей. Если временные метки файлов совпадают, сравнениеIS_NEWER_THANвозвращает true, чтобы любые зависимые операции сборки выполнялись в случае ничьей. Это включает случай, когда для 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 нет, возвращается false без ошибки.
- Оба левого и правого аргумента для 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 независимо проверяются на то, являются ли они определёнными переменными. Если да, используются их определённые значения, в противном случае используется исходное значение.
- Левый аргумент для IN_LIST проверяется на то, является ли он определённой переменной. Если да, используется значение переменной, в противном случае используется исходное значение.
- Правый аргумент для 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/latest/command/if.html