tutorial make descarga cmake

descarga - cmake vs make



CMake comparar con una cadena vacĂ­a con STREQUAL fallido (1)

Siempre pienso que si quieres comparar dos cadenas (pero no variables) todo lo que necesitas hacer es citarlo así:

if("${A}" STREQUAL "some string")

pero ahora descubro que este código a veces se imprime, ¡ oops !

cmake_minimum_required(VERSION 2.8) if("d" STREQUAL "") message("oops...") endif()

¿Puede ser que sea un error (porque se imprime con Xcode , pero no con make )? ¿O hay algunas variables especiales?

  • cmake: 2.8.12, 2.8.11.2
  • xcode: 4.6.2, 5.0.1

Actualizar

Hay una string comandos sin problemas descritos:

string(COMPARE EQUAL "${A}" "" result) if(result) message("...") endif()

Actualización 2

El comportamiento que esperaba implementado desde CMake 3.1.0 (ver CMP0054 ).

Salida de la test 3.0.2:

CMake version: 3.0.2 Quoted test Surprise! Unquoted test Surprise!

Salida de la test 3.1.0:

CMake version: 3.1.0 Quoted test OK Unquoted test Surprise!


Se encontró con un comportamiento bastante molesto de "no es un error, es una característica" de CMake. Como se explica en la documentación del comando if :

The if command was written very early in CMake''s history, predating the ${} variable evaluation syntax, and for convenience evaluates variables named by its arguments as shown in the above signatures.

Bueno, la conveniencia resultó ser un inconveniente. En su ejemplo, la cadena "d" se trata como una variable llamada d por el comando if . Si la variable d pasa a estar definida en la cadena vacía, la declaración del mensaje imprimirá "oops ...", por ejemplo:

set (d "") if("d" STREQUAL "") # this branch will be taken message("oops...") else() message("fine") endif()

Esto puede dar resultados sorprendentes para afirmaciones como

if("${A}" STREQUAL "some string")

porque puede haber una expansión doble no intencionada del primer argumento si la variable A pasa a definirse en una cadena que también es el nombre de una variable CMake, por ejemplo:

set (A "d") set (d "some string") if("${A}" STREQUAL "some string") # this branch will be taken message("oops...") else() message("fine") endif()

Posibles soluciones:

Puede agregar un carácter de sufijo a la cadena después de la expansión ${} que evita que la sentencia if realice la evaluación automática:

set (A "d") set (d "some string") if("${A} " STREQUAL "some string ") message("oops...") else() # this branch will be taken message("fine") endif()

No utilice la expansión ${} :

set (A "d") set (d "some string") if(A STREQUAL "some string") message("oops...") else() # this branch will be taken message("fine") endif()

Para evitar la evaluación involuntaria en el lado derecho de STREQUAL use STREQUAL con una expresión regular CMake :

if(A MATCHES "^value$") ... endif()

Addendum: CMake 3.1 ya no hace expansiones dobles para los argumentos entre comillas. Ver la nueva política .