Spec-Zone.ru › CMake 3.26

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(file1 IS_NEWER_THAN file2)

Истина, если file1 новее file2 или если один из двух файлов не существует. Поведение определено только для полных путей. Если метки времени файлов точно совпадают, сравнение IS_NEWER_THAN возвращает истину, так что любые зависимые операции построения будут выполняться в случае ничьей. Это включает случай передачи одного и того же имени файла для file1 и file2.

if(IS_DIRECTORY path)

Истина, если path является каталогом. Поведение определено только для полных путей.

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

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

См. также

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

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

Spec-Zone.ru

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