Spec-Zone.ru › CMake

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. Унарные проверки, например:
  • Проверки существования COMMAND, DEFINED, DIAGNOSTIC, EXISTS, POLICY, TARGET и TEST.
  • Файловые операции IS_READABLE, IS_WRITABLE, IS_EXECUTABLE, IS_DIRECTORY, IS_SYMLINK и IS_ABSOLUTE.
  1. Бинарные проверки, описанные в разделах Сравнения, Сравнение версий и Сравнение путей, а также IN_LIST и IS_NEWER_THAN.
  2. Унарный логический оператор NOT.
  3. Бинарные логические операторы 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>)

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

  • значение строки является одной из истинных констант либо
  • в версиях CMake до 4.0 политика CMP0054 не установлена в значение NEW, а значение строки случайно совпадает с именем переменной, на которую влияет поведение CMP0054.
if()

Ложь, если аргументы не указаны.

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

if(NOT <condition>)

Истина, если условие не является истинным.

if(<cond1> AND <cond2>)

Истина, если оба условия по отдельности считались бы истинными.

if(<cond1> OR <cond2>)

Истина, если любое из условий по отдельности считалось бы истинным.

if((condition) AND (condition OR (condition)))

Сначала вычисляются условия в скобках, затем — оставшееся условие, как и в других примерах. Если скобки вложены, внутренние скобки вычисляются в рамках вычисления содержащего их условия.

Проверки существования

if(COMMAND <command-name>)

Истина, если указанное имя является вызываемой командой, макросом или функцией.

if(DIAGNOSTIC <category>)

Добавлено в версии 4.4.

Истина, если указанное имя является существующей категорией диагностики.

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

Истина, если указанная строка или значение переменной соответствует заданному регулярному выражению. Формат регулярных выражений см. в разделе Спецификация регулярных выражений. Группы () сохраняются в переменных CMAKE_MATCH_<n>.

if(<variable|string> LESS <variable|string>)

Истина, если указанная строка или значение переменной интерпретируется как вещественное число (например, число типа double в C) и меньше значения справа.

if(<variable|string> GREATER <variable|string>)

Истина, если указанная строка или значение переменной интерпретируется как вещественное число (например, число типа double в C) и больше значения справа.

if(<variable|string> EQUAL <variable|string>)

Истина, если указанная строка или значение переменной интерпретируется как вещественное число (например, число типа double в C) и равно значению справа.

if(<variable|string> LESS_EQUAL <variable|string>)

Добавлено в версии 3.7.

Истина, если указанная строка или значение переменной интерпретируется как вещественное число (например, число типа double в C) и меньше или равно значению справа.

if(<variable|string> GREATER_EQUAL <variable|string>)

Добавлено в версии 3.7.

Истина, если указанная строка или значение переменной интерпретируется как вещественное число (например, число типа double в C) и больше или равно значению справа.

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.

Лексикографически сравнивает два пути CMake покомпонентно, не обращаясь к файловой системе. Пути считаются равными, только если совпадают все их компоненты. Несколько разделителей пути фактически сводятся к одному, однако обратные косые черты не преобразуются в прямые. Другая нормализация пути не выполняется. Завершающие косые черты сохраняются, поэтому /a/b и /a/b/ не равны.

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

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

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

См. также

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

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

Spec-Zone.ru

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