txt library how create cmakelists cmake

library - create cmakelists txt



¿Cuál es la sintaxis de CMake para establecer y usar variables? (3)

Al escribir scripts de CMake, hay mucho que necesita saber sobre la sintaxis y cómo usar variables en CMake.

La sintaxis

Cadenas usando set() :

  • set(MyString "Some Text")
  • set(MyStringWithVar "Some other Text: ${MyString}")
  • set(MyStringWithQuot "Some quote: /"${MyStringWithVar}/"")

O con una string() :

  • string(APPEND MyStringWithContent " ${MyString}")

Listas que usan set() :

  • set(MyList "a" "b" "c")
  • set(MyList ${MyList} "d")

O mejor con list() :

  • list(APPEND MyList "a" "b" "c")
  • list(APPEND MyList "d")

Listas de nombres de archivo:

  • set(MySourcesList "File.name" "File with Space.name")
  • list(APPEND MySourcesList "File.name" "File with Space.name")
  • add_excutable(MyExeTarget ${MySourcesList})

La documentación

El alcance o "¿Qué valor tiene mi variable?"

Primero están las "Variables normales" y las cosas que necesita saber sobre su alcance:

  • Las variables normales son visibles para el CMakeLists.txt que se establecen y todo lo que se llama desde allí ( add_subdirectory() , include() , macro() y function() ).
  • Los add_subdirectory() y function() son especiales, porque abren su propio ámbito.
    • Las variables de significado set(...) solo son visibles allí y hacen una copia de todas las variables normales del nivel de alcance desde el que se llaman (llamado alcance primario).
    • Entonces, si está en un subdirectorio o una función, puede modificar una variable ya existente en el ámbito primario con set(... PARENT_SCOPE)
    • Puede utilizar esto, por ejemplo, en funciones pasando el nombre de la variable como un parámetro de función. Un ejemplo sería la function(xyz _resultVar) es set set(${_resultVar} 1 PARENT_SCOPE)
  • Por otro lado, todo lo que establezca en los scripts include() o macro() modificará las variables directamente en el ámbito de donde se llaman.

En segundo lugar está el "Caché de variables globales". Cosas que debes saber sobre el caché:

  • Si no se define una variable normal con el nombre dado en el ámbito actual, CMake buscará una entrada de caché coincidente.
  • Los valores de caché se almacenan en el archivo CMakeCache.txt en su directorio de salida binario.
  • Los valores en la caché se pueden modificar en la aplicación GUI de CMake antes de que se generen. Por lo tanto, en comparación con las variables normales, tienen un type y una docstring . Normalmente no uso la GUI, así que uso set(... CACHE INTERNAL "") para establecer mis valores globales y persistentes.

    Tenga en cuenta que el tipo de variable de caché INTERNAL implica FORCE

  • En un script CMake, solo puede cambiar las entradas de caché existentes si utiliza la sintaxis set(... CACHE ... FORCE) . Este comportamiento es utilizado, por ejemplo, por CMake mismo, porque normalmente no fuerza las entradas de caché y, por lo tanto, puede predefinirlo con otro valor.

  • Puede usar la línea de comando para establecer entradas en la caché con la sintaxis cmake -D var:type=value , solo cmake -D var=value o con cmake -C CMakeInitialCache.cmake .
  • Puede unset entradas en la caché con unset(... CACHE) .

La memoria caché es global y puede configurarlos prácticamente en cualquier lugar en sus scripts CMake. Pero le recomendaría que lo piense dos veces antes de utilizar las variables de caché (son globales y persistentes). Normalmente prefiero la set_property(GLOBAL PROPERTY ...) y set_property(GLOBAL APPEND PROPERTY ...) para definir mis propias variables globales no persistentes.

Errores variables y "¿Cómo depurar cambios variables?"

Para evitar dificultades, debe saber lo siguiente acerca de las variables:

  • Las variables locales ocultan las variables en caché si ambas tienen el mismo nombre
  • Los comandos find_... , si tienen éxito, escriben sus resultados como variables en caché "para que ninguna llamada vuelva a buscar"
  • Las listas en CMake son solo cadenas con delimitadores de punto y coma y, por lo tanto, las comillas son importantes
    • set(MyVar abc) es "a;b;c" y set(MyVar "abc") es "abc"
    • La recomendación es que siempre use comillas con la única excepción cuando desee dar una lista como lista
    • Generalmente prefiero el comando list() para manejar listas
  • Todo el problema de alcance descrito anteriormente. Se recomienda especialmente utilizar functions() lugar de macros() porque no desea que sus variables locales se muestren en el ámbito primario.
  • Muchas variables utilizadas por CMake se configuran con las llamadas project() y enable_language() . Por lo tanto, podría ser importante establecer algunas variables antes de usar esos comandos.
  • Las variables de entorno pueden diferir de dónde CMake generó el entorno de creación y cuándo se utilizan los archivos de creación.
    • Un cambio en una variable de entorno no reactiva el proceso de generación.
    • Especialmente un entorno IDE generado puede diferir de su línea de comando, por lo que se recomienda transferir sus variables de entorno a algo que está en caché.

A veces solo ayuda la depuración de variables. Lo siguiente puede ayudarlo:

  • Simplemente use el viejo estilo de depuración printf usando el comando message() . También hay algunos módulos listos para usar que se envían con CMake: CMakePrintHelpers.cmake , CMakePrintSystemInformation.cmake
  • Busque en el archivo CMakeCache.txt en su directorio de salida binario. Este archivo incluso se genera si falla la generación real de su entorno de creación.
  • Use variable_watch() para ver dónde se leen / escriben / eliminan sus variables.
  • Mire las propiedades del directorio CACHE_VARIABLES y CACHE_VARIABLES
  • Llame a cmake --trace ... para ver el proceso completo de análisis de CMake. Esa es una especie de última reserva, ya que genera mucha salida.

Sintaxis Especial

  • Variables de entorno
    • Puede leer $ENV{...} y escribir variables de entorno del set(ENV{...} ...)
  • Expresiones de generador
    • Las expresiones de generador $<...> solo se evalúan cuando el generador de CMake escribe el entorno de creación (en comparación con las variables normales que se reemplazan "en el lugar" por el analizador)
    • Muy útil, por ejemplo, en las líneas de comando del compilador / enlazador y en entornos de configuración múltiple
  • Referencias
    • Con ${${...}} puede dar nombres de variables en una variable y hacer referencia a su contenido.
    • A menudo se usa al dar un nombre de variable como parámetro de función / macro.
  • Valores constantes (ver comando if() )
    • Con if(MyVariable) puede verificar directamente una variable para verdadero / falso (no es necesario aquí para el adjunto ${...} )
    • Verdadero si la constante es 1 , ON , YES , TRUE , Y o un número distinto de cero.
    • Falso si la constante es 0 , OFF , NO , FALSE , N , IGNORE , NOTFOUND , la cadena vacía o termina en el sufijo -NOTFOUND .
    • Esta sintaxis a menudo se usa para algo como if(MSVC) , pero puede ser confusa para alguien que no conoce este atajo de sintaxis.
  • Sustituciones recursivas
    • Puede construir nombres de variables usando variables. Después de que CMake haya sustituido las variables, verificará nuevamente si el resultado es una variable en sí misma. Esta es una característica muy poderosa utilizada en CMake, por ejemplo, como una especie de set(CMAKE_${lang}_COMPILER ...) plantillas set(CMAKE_${lang}_COMPILER ...)
    • Pero tenga en cuenta que esto puede causarle dolor de cabeza en los comandos if() . Aquí hay un ejemplo donde CMAKE_CXX_COMPILER_ID es "MSVC" y MSVC es "1" :
      • if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") es verdadero, porque se evalúa como if("1" STREQUAL "1")
      • if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") es falso, porque se evalúa como if("MSVC" STREQUAL "1")
      • Entonces, la mejor solución aquí sería, ver arriba, verificar directamente if(MSVC)
    • La buena noticia es que esto se solucionó en CMake 3.1 con la introducción de la política CMP0054 . Recomendaría siempre configurar cmake_policy(SET CMP0054 NEW) para "interpretar solo los argumentos if() como variables o palabras clave cuando no están entre comillas".
  • El comando option()
    • Principalmente solo cadenas en caché que solo pueden estar ON o OFF y permiten un manejo especial como, por ejemplo, dependencies
    • Pero tenga en cuenta , no confunda la option con el comando set . El valor dado a la option es realmente solo el "valor inicial" (transferido una vez al caché durante el primer paso de configuración) y luego debe ser modificado por el usuario a través de la GUI de CMake .

Referencias

Me lo pido como un recordatorio la próxima vez que use CMake. Nunca se pega, y los resultados de Google no son excelentes.

¿Cuál es la sintaxis para establecer y usar variables en CMake?


Aquí hay un par de ejemplos básicos para comenzar rápido y sucio.

Una variable de elemento

Establecer variable:

SET(INSTALL_ETC_DIR "etc")

Usar variable:

SET(INSTALL_ETC_CROND_DIR "${INSTALL_ETC_DIR}/cron.d")

Variable de elementos múltiples (es decir, lista)

Establecer variable:

SET(PROGRAM_SRCS program.c program_utils.c a_lib.c b_lib.c config.c )

Usar variable:

add_executable(program "${PROGRAM_SRCS}")

CMake documentos sobre variables


$ENV{FOO} para uso, donde FOO se está recogiendo de la variable de entorno. de lo contrario, use como ${FOO} , donde FOO es alguna otra variable. Para la configuración, SET(FOO "foo") se usaría en CMake.