Подтвердить что ты не робот

Пересечение списка строк

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

cmake_minimum_required(VERSION 2.8)

FOREACH(LETTER "a;b;c")
  MESSAGE("<<${LETTER}>>")
ENDFOREACH()

интерпретирует строку "a;b;c" как строковый литерал. Напротив, при первом присваивании переменной "a;b;c", все работает как ожидалось.

cmake_minimum_required(VERSION 2.8)

SET(MYLIST "a;b;c")
FOREACH(LETTER ${MYLIST})
  MESSAGE("<<${LETTER}>>")
ENDFOREACH()

Является ли это рекомендуемым способом для перебора списка или есть более элегантное решение?

4b9b3361

Ответ 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}") [...]