if
Условно выполнить группу команд.
Синтаксис
if(<condition>) <commands> elseif(<condition>) # optional block, can be repeated <commands> else() # optional block <commands> endif()
Оценивает аргумент condition оператора if в соответствии с Синтаксисом условия, описанным ниже. Если результат равен true, то commands в блоке if выполняются. В противном случае обрабатываются необязательные блоки elseif. Наконец, если ни одно condition не равно true, commands в необязательном блоке else выполняются.
Согласно старой версии, команды else() и endif() допускают необязательный аргумент <condition>. Если используется, он должен быть точным повторением аргумента открывающей команды if.
Синтаксис условия
Следующий синтаксис применяется к аргументу condition операторов if, elseif и while().
Сложные условия оцениваются в следующем порядке приоритетов:
- Скобки.
- Унарные тесты, такие как КОМАНДА, ПОЛИТИКА, ЦЕЛЬ, ТЕСТ, СУЩЕСТВУЕТ, ЧИТАЕМ, ЗАПИСЫВАЕМ, ИСПОЛНЯЕМ, ДИРЕКТОРИЯ, СИМВОЛИЧЕСКАЯ_ССЫЛЬКА, АБСОЛЮТНЫЙ и ОПРЕДЕЛЁН.
- Бинарные тесты, такие как РАВНО, МЕНЬШЕ, МЕНЬШЕ_ИЛИ_РАВНО, БОЛЬШЕ, БОЛЬШЕ_ИЛИ_РАВНО, СТР_РАВНО, СТР_МЕНЬШЕ, СТР_МЕНЬШЕ_ИЛИ_РАВНО, СТР_БОЛЬШЕ, СТР_БОЛЬШЕ_ИЛИ_РАВНО, VERSION_РАВНО, VERSION_МЕНЬШЕ, VERSION_МЕНЬШЕ_ИЛИ_РАВНО, VERSION_БОЛЬШЕ, VERSION_БОЛЬШЕ_ИЛИ_РАВНО, ПУТЬ_РАВНО, В_СПИСКЕ, НОВЕЕ и СООТВЕТСТВУЕТ.
- Унарный логический оператор НЕ.
- Бинарные логические операторы И и ИЛИ, слева направо, без короткого замыкания.
Основные выражения
-
if(<constant>) -
True, если константа равна
1,ON,YES,TRUE,Y, или ненулевому числу (включая числа с плавающей точкой). False, если константа равна0,OFF,NO,FALSE,N,IGNORE,NOTFOUND, пустой строке или заканчивается суффиксом-NOTFOUND. Названные булевы константы нечувствительны к регистру. Если аргумент не является одной из этих конкретных констант, он обрабатывается как переменная или строка (см. Расширение переменных ниже).
-
if(<variable>) -
True, если задана переменная, значение которой не является ложной константой. False в противном случае, включая случай, когда переменная не определена. Обратите внимание, что аргументы макросов не являются переменными. Переменные окружения также не могут быть проверены таким образом, например,
if(ENV{some_var})всегда будет оцениваться как false.
-
if(<string>) -
Строка в кавычках всегда оценивается как false, за исключением случаев:
Логические операторы
-
if(NOT <condition>) -
True, если условие не истинно.
-
if(<cond1> AND <cond2>) -
True, если оба условия считаются истинными.
-
if(<cond1> OR <cond2>) -
True, если хотя бы одно из условий считается истинным.
-
if((condition) AND (condition OR (condition))) -
Условия в скобках оцениваются в первую очередь, а затем оставшееся условие оценивается так же, как и в других примерах. При наличии вложенных скобок, самые внутренние оцениваются как часть условия, которое их содержит.
Проверки существования
-
if(COMMAND <command-name>) -
True, если заданное имя является командой, макросом или функцией, которые можно вызвать.
-
if(POLICY <policy-id>) -
True, если заданное имя является существующей политикой (в форме
CMP<NNNN>).
-
if(TARGET <target-name>) -
True, если заданное имя является существующим именем логической цели, созданной вызовом команды
add_executable(),add_library()илиadd_custom_target()(в любой директории).
-
if(TEST <test-name>) -
Добавлена в версии 3.3.
True, если заданное имя является существующим именем теста, созданным командой
add_test().
-
if(DEFINED <name>|CACHE{<name>}|ENV{<name>}) -
True, если переменная, переменная кеша или переменная окружения с заданным
<name>определена. Значение переменной не имеет значения. Обратите внимание на следующие замечания:- Аргументы макросов не являются переменными.
- Невозможно напрямую проверить, является ли
<name>переменной, отличной от переменной кеша. Выражениеif(DEFINED someName)будет оцениваться как true, если существует либо переменная кеша, либо переменная, отличная от переменной кеша,someName. В сравнении, выражениеif(DEFINED CACHE{someName})будет оцениваться как true только если существует переменная кешаsomeName. Оба выражения необходимо проверить, если вам нужно узнать, существует ли переменная, отличная от переменной кеша:if(DEFINED someName AND NOT DEFINED CACHE{someName}).
Добавлена в версии 3.14: Добавлена поддержка переменных
CACHE{<name>}.
-
if(<variable|string> IN_LIST <variable>) -
Добавлена в версии 3.3.
True, если заданный элемент содержится в переменной списка с указанным именем.
Операции с файлами
-
if(EXISTS <path-to-file-or-directory>) -
True, если указанный файл или директория существуют и читаемы. Поведение определено только для явных полных путей (ведущий
~/не обрабатывается как домашний каталог и считается относительным путем). Разрешает символические ссылки, т.е. если указанный файл или директория является символической ссылкой, возвращает true, если целевой объект символической ссылки существует.False, если заданный путь является пустой строкой.
Примечание
Предпочтительнее использовать
if(IS_READABLE), чтобы проверить читаемость файла.if(EXISTS)может быть изменено в будущем, чтобы проверять только существование файла.
-
if(IS_READABLE <path-to-file-or-directory>) -
Добавлена в версии 3.29.
True, если указанный файл или директория читаемы. Поведение определено только для явных полных путей (ведущий
~/не обрабатывается как домашний каталог и считается относительным путем). Разрешает символические ссылки, т.е. если указанный файл или директория является символической ссылкой, возвращает true, если целевой объект символической ссылки читаем.False, если заданный путь является пустой строкой.
-
if(IS_WRITABLE <path-to-file-or-directory>) -
Добавлена в версии 3.29.
True, если указанный файл или директория записываемы. Поведение определено только для явных полных путей (ведущий
~/не обрабатывается как домашний каталог и считается относительным путем). Разрешает символические ссылки, т.е. если указанный файл или директория является символической ссылкой, возвращает true, если целевой объект символической ссылки записываем.False, если заданный путь является пустой строкой.
-
if(IS_EXECUTABLE <path-to-file-or-directory>) -
Добавлен в версии 3.29.
Истинно, если указанный файл или директория исполняемый. Поведение определено только для явных полных путей (начальный символ
~/не обрабатывается как домашняя директория и рассматривается как относительный путь). Разрешает символические ссылки, т.е. если указанный файл или директория является символической ссылкой, возвращает истинно, если целевой объект символической ссылки исполняемый.Ложно, если заданный путь является пустой строкой.
-
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 нет, возвращается 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/v3.31/command/if.html