CMake - Как команда if () обрабатывает символ? Как строка или как переменная? - PullRequest
2 голосов
/ 11 июля 2019

Я не уверен, что команда 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().( src )

if(<constant>)

Истина, если константа равна 1, ВКЛ, ДА, ИСТИНА, Y или ненулевое число.False, если константа равна 0, OFF, NO, FALSE, N, IGNORE, NOTFOUND, пустой строке или заканчивается суффиксом -NOTFOUND.Именованные логические константы не чувствительны к регистру. Если аргумент не является одной из этих конкретных констант, он обрабатывается как переменная или строка, и используется следующая подпись.

Итак, сейчас я должен обратиться квышеупомянутое правило сначала, прежде чем применять мой вывод 1 .(Это может быть ответом, но я еще не уверен.)

1 Ответ

2 голосов
/ 11 июля 2019

Добро пожаловать в пустыню интерпретации символов CMake.

Если символ существует как переменная, то выражение оценивается по значению переменной.В противном случае вместо этого оценивается имя переменной (или литерала, как вы сказали).

Поведение становится немного более последовательным, если вы добавляете последовательности ${ и }.Затем значение переменной используется в оценке каждый раз.Если переменная не существует или ей не присвоено значение, то CMake использует несколько значений заполнителей, которые оцениваются как «ложные».Это значения, которые вы упомянули в последней части своего поста.

Я полагаю, что это сделано для обратной совместимости, что очень хорошо для CMake.Для большинства изворотливых вещей, которые делает CMake, это обычно происходит во имя обратной совместимости.

Что касается противоречивого поведения, которое вы упомянули в переменной «ON», это, вероятно, связано с тем, что CMake обрабатываеткомандные аргументы.Я должен был бы понять, что константы анализируются до того, как происходит поиск символа.

Поэтому, когда дело доходит до знания / прогнозирования оценки оператора if, мой лучший ответ - опыт.Дерево исходных текстов и логика CMake - это один великолепный, неприятный зверь.

Были дискуссии о добавлении альтернативного языка (язык с, возможно, функциональной парадигмой), но это довольно большое дело.

...