language - ¿Cuándo debo citar variables?
contains liquid (1)
Debes tener en cuenta dos principios de CMake:
- CMake es un lenguaje de script y los argumentos se evalúan después de expandir las variables
- CMake diferencia entre cadenas normales y variables de lista (cadenas con delimitadores de punto y coma)
Ejemplos
-
set(_my_text "ABC")
con elmessage("${_my_text}")
daríaABC
-
set(_my_list ABC)
conmessage("${_my_list}")
daríaA;B;C
-
set(_my_list "A" "B" "C")
conmessage("${_my_list}")
daríaA;B;C
-
set(_my_list "A" "B" "C")
conmessage(${_my_list})
le daríaABC
Algunas reglas generales
Hay algunas reglas generales que debes considerar:
-
a) Cuando su variable contiene texto, especialmente uno que podría contener punto y coma, debe agregar comillas.
Razonamiento : un punto y coma es un delimitador para elementos de lista en CMake. Ponga comillas alrededor de un texto que se supone que es uno (funciona en todas partes y para mí personalmente se ve mejor con el resaltado de sintaxis CMake)
EDITAR: Gracias por la pista de @schieferstapel
b) Para ser más precisos: un contenido variable con espacios que ya tenían comillas sí mantiene esas comillas (imagínense como parte del contenido de la variable). Esto funciona en todas partes también sin comillas (parámetros de función normales o definidos por el usuario) con la excepción destacada de las llamadas
if()
, donde CMake reinterpreta el contenido de las variables sin comillas después de la expansión de variables (ver también la regla general # 3 y la política CMP0054: solo interprete los argumentosif()
como variables o palabras clave cuando no están entre comillas )Ejemplos:
-
set(_my_text "ABC")
conmessage(${_my_text})
también daríaABC
-
set(_my_text "A;B;C")
conif (${_my_text} STREQUAL "A;B;C")
daríaif given arguments: "A" "B" "C" "STREQUAL" "A;B;C" Unknown arguments specified
-
-
Si su variable contiene una lista, normalmente no agrega comillas.
Razonamiento : si le da algo como una lista de archivos a un comando CMake, normalmente espera una lista de cadenas y no una cadena que contenga una lista. La diferencia se puede ver, por ejemplo, en el comando
foreach()
aceptaITEMS
oLISTS
. -
if()
declaracionesif()
son un caso especial en el que normalmente ni siquiera pone llaves.Razonamiento : una cadena podría, después de la expansión, evaluar nuevamente a un nombre de variable. Para evitar esto, se recomienda simplemente nombrar la variable cuyo contenido desea comparar (por ejemplo,
if (_my_text STREQUAL "ABC")
).
COMMAND
Ejemplos
-
set(_my_text "ABC")
conCOMMAND "${CMAKE_COMMAND}" -E echo "${_my_text}"
haría-
llame a
cmake.exe -E echo "ABC"
en VS / Windows -
llame a
cmake -E echo A/ B/ C
en GCC / Ubuntu -
dar
ABC
-
llame a
-
set(_my_text "ABC")
conCOMMAND "${CMAKE_COMMAND}" -E echo "${_my_text}" VERBATIM
haría-
llame a
cmake.exe -E echo "ABC"
en VS / Windows -
llame a
cmake -E echo "ABC"
en GCC / Ubuntu -
dar
ABC
-
llame a
-
set(_my_list ABC)
conCOMMAND "${CMAKE_COMMAND}" -E echo "${_my_list}"
haría-
llame a
cmake.exe -E echo A;B;C
-
dar
A
,B: command not found
,C: command not found
-
llame a
-
set(_my_list ABC)
conCOMMAND "${CMAKE_COMMAND}" -E echo "${_my_list}" VERBATIM
haría-
llame a
cmake.exe -E echo "A;B;C"
-
dar
A;B;C
-
llame a
-
set(_my_list "A" "B" "C")
conCOMMAND "${CMAKE_COMMAND}" -E echo "${_my_list}" VERBATIM
haría-
llame a
cmake.exe -E echo "A;B;C"
-
dar
A;B;C
-
llame a
-
set(_my_list "A" "B" "C")
conCOMMAND "${CMAKE_COMMAND}" -E echo ${_my_list} VERBATIM
haría-
llame a
cmake.exe -E echo ABC
-
dar
ABC
-
llame a
-
set(_my_list "A + B" "=" "C")
conCOMMAND "${CMAKE_COMMAND}" -E echo ${_my_list} VERBATIM
haría-
llame a
cmake.exe -E echo "A + B" = C
-
dar
A + B = C
-
llame a
Algunas reglas
add_custom_target()
con
add_custom_target()
/
add_custom_command()
/
execute_process()
Hay algunas reglas generales que debe tener en cuenta al usar variables en las llamadas de
COMMAND
:
-
a) Use comillas para los argumentos que contienen rutas de archivo (como el primer argumento que contiene el ejecutable).
Razonamiento : podría contener espacios y podría reinterpretarse como argumentos separados para la llamada de
COMMAND
b) Ver arriba, funciona también si la variable
set()
incluía comillas. -
Use comillas solo si desea concatenar algo en un solo parámetro para pasarlo al ejecutable que se llama.
Razonamiento : una variable podría contener una lista de parámetros que, al usar comillas, no se extraerán correctamente (punto y coma en lugar de espacios)
-
Agregue siempre la opción
VERBATIM
conadd_custom_target()
/add_custom_command()
Razonamiento : de lo contrario, el comportamiento multiplataforma no está definido y podría obtener sorpresas con sus cadenas citadas.
Referencias
Estoy escribiendo macros CMake por primera vez, y me cuesta entender cómo funcionan las variables.
Más específicamente,
${a}
parece tener un significado diferente que
"${a}"
.
Por ejemplo aquí: pasar una lista a una macro CMake
No entiendo cuándo se supone que debo agregar citas y cuáles son los principios subyacentes más importantes.