Ответ 1
Источником вашей путаницы, вероятно, является интерпретация цитируемых строк в CMake.
Например, следующее: все перебирают по списку строк правильно:
(1) foreach(LETTER a b c) [...]
(2) foreach(LETTER a;b;c) [...]
(3) set(MYLIST "a;b;c")
foreach(LETTER ${MYLIST}) [...]
Единственный случай, когда это не работает, -
(4) foreach(LETTER "a;b;c") [...]
Причина, по которой работа (1)
и (2)
находится в руководстве к языку CMake для некотируемых аргументов:
Содержимое без кавычек состоит из всего текста в смежном блоке разрешенных или экранированных символов. Обе последовательности и переменные Escape Ссылки оцениваются. Результирующее значение делится на одно и то же way Lists делятся на элементы. Каждому непустому элементу присваивается значение вызов команды в качестве аргумента. Поэтому неопределенный аргумент может присваивается вызову команды как ноль или более аргументов.
Обратите внимание, что это отличается от приведенных аргументов, которые также оценивают последовательности Escape и ссылки на переменные, но не делают расширение списка. Это объясняет, почему (4)
терпит неудачу.
Интересный вопрос теперь в том, почему (3)
все еще преуспевает. set
будет принимать как одно значение, так и аргумент значения списка. На самом деле все до закрытия )
или одного из ключевых слов CACHE
или PARENT_SCOPE
считается частью значения. Таким образом, следующие две команды эквивалентны:
set(MYLIST "a;b;c")
set(MYLIST a;b;c)
В обоих случаях значение MYLIST
будет a;b;c
(без кавычек).
Когда мы теперь разворачиваем ${MYLIST}
в другую команду, вы можете думать о том, что она выполняет простую замену строки со значением MYLIST
, который равен a;b;c
. Полученная команда затем будет расширяться с помощью правил цитируемых или некотируемых аргументов. То есть будет работать следующее:
foreach(LETTER ${MYLIST}) [...]
пока это не будет:
foreach(LETTER "${MYLIST}") [...]