Spec-Zone.ru › CMake 3.30

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().

Составные условия вычисляются в следующем порядке приоритетов:

  1. Скобки.
  2. Унарные тесты, такие как EXISTS, COMMAND и DEFINED.
  3. Бинарные тесты, такие как 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.
  4. Унарный логический оператор NOT.
  5. Бинарные логические операторы 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>)

Строка в кавычках всегда вычисляется как ложь, за исключением следующих случаев:

  • Значение строки — одна из истинных констант, или
  • Политика CMP0054 не установлена в NEW и значение строки — имя переменной, на которую влияет поведение CMP0054.

Логические операторы

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.

Истина, если указанный файл или каталог доступен для записи. Поведение определено только для полных явных путей (начальный ~/ не расширяется как домашний каталог и рассматривается как относительный путь). Разрешает символические ссылки, т.е. если указанный файл или каталог является символической ссылкой, возвращает истину, если целевой объект символической ссылки доступен для записи.

Ложь, если заданный путь — пустая строка.

END_OF_DOCUMENT_MARKER
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 проверяются на определение как переменных. Если переменные определены, используются их значения, иначе используются исходные значения.
  • Правый аргумент оператора NOT проверяется на то, является ли он булевым константой. Если это так, используется его значение; в противном случае предполагается, что это переменная, и она разыменовывается.
  • Левый и правый аргументы операторов AND и OR проверяются на то, являются ли они булевыми константами. Если это так, они используются как константы; в противном случае предполагается, что это переменные, и они разыменовываются.

Изменено в версии 3.1: Для предотвращения неоднозначности, потенциальные имена переменных или ключевых слов могут быть указаны в Цитата Аргумента или Аргумента в скобках. Цитата или скобки переменной или ключевого слова будут интерпретированы как строка и не будут разыменовываться или интерпретироваться. См. политику CMP0054.

Автоматической оценки для переменных среды или кэша Ссылок на переменные нет. Их значения должны быть указаны как $ENV{<name>} или $CACHE{<name>} всякий раз, когда синтаксис условия, описанный выше, принимает <variable|string>.

См. также

  • else()
  • elseif()
  • endif()

© 2000–2024 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.30/command/if.html

Spec-Zone.ru

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