CMake - Как команда if() обрабатывает символ? Как строка или как переменная?
Я не уверен, что CMake if()
Команда будет обрабатывать символ в условии условия как переменную или строковый литерал. Поэтому я провел несколько экспериментов.
Script1.cmake
cmake_minimum_required(VERSION 3.15)
set(XXX "YYY") #<========== HERE!!
if(XXX STREQUAL "XXX")
message("condition 1 is true") # If reach here, XXX is treated as string
elseif(XXX STREQUAL "YYY")
message("condition 2 is true") # If reach here, XXX is treated as variable
endif()
Выход:
condition 2 is true
Итак, я прихожу к заключению ниже1.
Для символа в условии условия:
- Если символопределен как переменная ранее, CMake будет обрабатывать его как переменную и использовать его значение для оценки.
- Если символне был определен как переменная ранее, CMake будет обрабатывать его буквально как строку.
Затем я сделал еще один эксперимент.
set(ON "OFF")
if(ON)
message("condition 3 is true") # If reach here, ON is treated as a constant.
else()
message("condition 4 is true") # If reach here. ON is treated as a variable.
endif()
Выход:
condition 3 is true
Итак, хотяON
явно определяется как переменная,if
Команда все еще рассматривает это как константу ИСТИННОГО значения. Это прямо противоречит моему предыдущемувыводу 1.
Так как я могу точно знать, что команда CMake if() будет обрабатывать символ как строку или переменную??
ДОБАВИТЬ 1 - 11:04 7/11/2019
Кажетсяif(constant)
форма предшествует другим формамif()
заявление. (источник)
if(<constant>)
Истинно, если константа равна 1, ВКЛ, ДА, ИСТИНА, Y или ненулевое число. False, если константа равна 0, OFF, NO, FALSE, N, IGNORE, NOTFOUND, пустой строке или заканчивается суффиксом -NOTFOUND. Именованные логические константы не чувствительны к регистру. Если аргумент не является одной из этих конкретных констант, он обрабатывается как переменная или строка, и используется следующая подпись.
Итак, сейчас я должен обратиться к вышеупомянутому правилу, прежде чем применять мой вывод 1. (Это может быть ответом, но я еще не уверен.)
1 ответ
Добро пожаловать в пустыню интерпретации символов CMake.
Если символ существует как переменная, то выражение оценивается по значению переменной. В противном случае вместо этого оценивается имя переменной (или литерала, как вы сказали).
Поведение становится немного более последовательным, если вы добавите ${
а также }
последовательности. Затем значение переменной используется в оценке каждый раз. Если переменная не существует или ей не присвоено значение, то CMake использует несколько значений заполнителей, которые оцениваются как "ложные". Это значения, которые вы упомянули в последней части своего поста.
Я полагаю, что это сделано для обратной совместимости, что очень хорошо для CMake. Для большинства изворотливых вещей, которые делает CMake, это обычно происходит во имя обратной совместимости.
Что касается противоречивого поведения, которое вы упомянули в переменной "ON", это, вероятно, связано с приоритетом, в котором CMake обрабатывает аргументы команды. Я должен был бы понять, что константы анализируются до того, как произойдет поиск символа.
Так что, когда дело доходит до знания / предсказания, как if
Заявление оценит, мой лучший ответ - опыт. Исходное дерево и логика CMake - это один великолепный, противный зверь.
Были дискуссии о добавлении альтернативного языка (язык с, возможно, функциональной парадигмой), но это довольно большое дело.