list - description - name keywords
Bucle sobre una lista de cadenas (1)
La fuente de su confusión es probablemente la peculiar interpretación de CMake de cadenas citadas.
Por ejemplo, todo lo siguiente itera sobre la lista de cadenas correctamente:
(1) foreach(LETTER a b c) [...]
(2) foreach(LETTER a;b;c) [...]
(3) set(MYLIST "a;b;c")
foreach(LETTER ${MYLIST}) [...]
El único caso en que esto no funciona es
(4) foreach(LETTER "a;b;c") [...]
La razón por la que (1)
y (2)
funcionan se encuentra en el manual de lenguaje de CMake para los argumentos sin comillas :
El contenido del argumento no citado consta de todo el texto en un bloque contiguo de caracteres permitidos o escapados. Se evalúan las secuencias de escape y las referencias variables. El valor resultante se divide de la misma manera Las listas se dividen en elementos . Cada elemento no vacío se asigna a la invocación del comando como un argumento. Por lo tanto, se puede dar un argumento sin comillas a una invocación de comando como cero o más argumentos.
Tenga en cuenta que esto es diferente de los argumentos citados , que también evalúan las secuencias de escape y las referencias de variables, pero no hacen la expansión de la lista. Esto explica por qué (4)
falla.
La pregunta interesante ahora es por qué (3)
todavía tiene éxito. set
aceptará los argumentos de valor único y valor de lista. De hecho, todo antes del cierre )
o una de las palabras clave CACHE
o PARENT_SCOPE
se consideran parte del valor. Como tal, los siguientes dos comandos son equivalentes:
set(MYLIST "a;b;c")
set(MYLIST a;b;c)
En ambos casos, el valor de MYLIST
será a;b;c
(sin las comillas).
Cuando ahora expandimos ${MYLIST}
en otro comando, puede pensar que realiza un reemplazo de cadena simple con el valor de MYLIST
, que es a;b;c
. El comando resultante se expandirá a través de las reglas de los argumentos entre comillas o sin comillas. Es decir, lo siguiente funcionará:
foreach(LETTER ${MYLIST}) [...]
mientras esto no lo hará:
foreach(LETTER "${MYLIST}") [...]
Me gustaría hacer un bucle sobre la lista de elementos, dada en una cadena. Como lo requiere CMake, los elementos están separados por punto y coma. El seguimiento
cmake_minimum_required(VERSION 2.8)
FOREACH(LETTER "a;b;c")
MESSAGE("<<${LETTER}>>")
ENDFOREACH()
interpreta la cadena "a;b;c"
como cadena literal. En contraste, al asignar "a;b;c"
a una variable primero, todo funciona como se espera.
cmake_minimum_required(VERSION 2.8)
SET(MYLIST "a;b;c")
FOREACH(LETTER ${MYLIST})
MESSAGE("<<${LETTER}>>")
ENDFOREACH()
¿Es esta la forma recomendada para recorrer una lista o hay una solución más elegante?