Spec-Zone.ru › CMake 3.29

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.

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

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

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.29/command/if.html

Spec-Zone.ru

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