2011-05-30 15 views
8

Siento que toda la comunidad de cmake me está atrapando. Ninguno de los "tutoriales" o recursos tiene sentido para mí. Es como si me falta algo. Creo que lo que más me confunde es el lenguaje y ninguno de los tutoriales que he visto se acercan a ser decente al explicar cmake a alguien que tiene poco Unix y experiencia.¿Alguien puede explicarme este script cmake?

De todos modos, estoy trabajando con FireBreath y utiliza cmake extensamente, creo que es hora de que empiece a descubrir cómo usarlo en lugar de cambiar los archivos del proyecto directamente.

archivo CMakeLists.txt

La raíz contiene lo siguiente:

cmake_minimum_required (VERSION 2.6) 
set (CMAKE_BACKWARDS_COMPATIBILITY 2.6) 

Project(${PLUGIN_NAME}) 

file (GLOB GENERAL RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} 
    [^.]*.cpp 
    [^.]*.h 
    [^.]*.cmake 
    ) 

include_directories(${PLUGIN_INCLUDE_DIRS}) 

# Generated files are stored in ${GENERATED} by the project configuration 
SET_SOURCE_FILES_PROPERTIES(
    ${GENERATED} 
    PROPERTIES 
     GENERATED 1 
    ) 

SOURCE_GROUP(Generated FILES 
    ${GENERATED} 
    ) 

SET(SOURCES 
    ${GENERAL} 
    ${GENERATED} 
    ) 

Me realmente apreciaría si alguien podría explicar cada línea para mí. Especialmente lo que ${GENERAL} y ${GENERATED} son.

Respuesta

19

Antes que nada, la sintaxis de cmake es realmente simple. Consiste en "comandos" y "argumentos". Es tan simple que tarda un tiempo en asimilarse. Todo es "comando (argumentos)". Además, los nombres de los comandos no distinguen entre mayúsculas y minúsculas. Antes tenían que ser TODOS MAYÚSCULAS, pero desde la versión 2.6 (creo) no importa. Sin embargo, los argumentos son sensibles a mayúsculas y minúsculas.

cmake_minimum_required (VERSION 2.6) 

Este comando establece la versión mínima requerida de cmake para un proyecto. Si la versión actual de cmake es inferior a 2.6, dejará de procesarse e informará de un error. Esto evita tener que soportar versiones antiguas de la herramienta.

set (CMAKE_BACKWARDS_COMPATIBILITY 2.6) 

Establezca la variable CMAKE_BACKWARDS_COMPATIBILITY en el valor 2.6. En realidad, se trata de un error menor en el archivo CMakeLists.txt que ha presentado, ya que CMAKE_BACKWARDS_COMPATIBILITY no debe utilizarse para 2.6 y versiones posteriores. El script probablemente debería usar cmake_policy. Esto es para especificar cómo se comportarán las versiones más nuevas de cmake cuando se enfrenten con inconsistencias en versiones anteriores de cmake. Cualquier script que escriba desde cero hoy no debería preocuparse por esto.

Project(${PLUGIN_NAME}) 

Establece el nombre del proyecto con el valor de lo que está en la variable PLUGIN_NAME. Este valor se muestra como el nombre del proyecto en algunos IDEs. Para escribir un valor en una variable, puede usar set(PLUGIN_NAME myName) y leer el valor que usa la sintaxis ${}: "${PLUGIN_NAME}". Algunos comandos también escriben en variables, pero los usa de la misma manera que en el comando set.

file (GLOB GENERAL RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} 
    [^.]*.cpp 
    [^.]*.h 
    [^.]*.cmake 
    ) 

file es un comando. Su primer argumento GLOB significa "devolver archivos en el disco cuyos nombres coinciden con los patrones que daré como argumentos". El siguiente argumento GENERAL es la variable en la que se almacena el resultado, como con set, escribe el resultado en la variable y luego puede leerlo con ${GENERAL}. RELATIVE y la ruta significa devolver los nombres de archivo relativos a esa ruta, no la ruta completa. Entonces, en lugar de "C: \ some \ long \ path \ src \ foo.cpp" o "/home/me/some/path/src/foo.cpp" obtendría "src \ foo.cpp" o "src/foo.cpp ". La variable CMAKE_CURRENT_SOURCE_DIR es una "variable mágica" que CMake rellena para usted y se refiere a la ruta al directorio de origen que se está procesando actualmente, donde vive este archivo CMakeLists.txt. La última lista de argumentos son los patrones de archivos que se emparejarán. Básicamente, cualquier cosa que tenga la extensión de archivo cpp, h o cmake.

include_directories(${PLUGIN_INCLUDE_DIRS}) 

Añadir los directorios en los ${PLUGIN_INCLUDE_DIRS} a los buscados por el compilador para incluir archivos. Esto dará como resultado argumentos extra "-I" si compila con gcc, por ejemplo.

# Generated files are stored in ${GENERATED} by the project configuration 

Las líneas que comienzan con # son comentarios.

SET_SOURCE_FILES_PROPERTIES(
     ${GENERATED} 
     PROPERTIES 
      GENERATED 1 
     ) 

Los archivos pueden tener pares clave/valor asociados a ellos, y esto afecta la forma en que se crean. Aquí los archivos enumerados en la variable ${GENERATED} tienen la propiedad "GENERADO" establecido en el valor 1. ¿Qué significa eso? Bueno, CMake ahora sabe que no debe buscar los archivos "$ {GENERATED}" en el disco, ya que se crearán en otro paso de compilación. En el fragmento publicado, nadie establece la variable ${GENERATED}. Me imagino que se establece en otra parte de los archivos del proyecto. ¡No mezcle la variable ${GENERATED} con la propiedad GENERADA! Este es un punto sutil, y tal vez la variable debería haber sido GENERATED_FILES para evitar confusiones, es decir, SET_SOURCE_FILES_PROPERTIES(${GENERATED_FILES} PROPERTIES GENERATED 1).

SOURCE_GROUP(Generated FILES ${GENERATED}) 

Esto crea un grupo, que en Visual Studio se traduce en una ficha de archivo, llamado "generada" que contiene los archivos en la variable ${GENERATED}.

SET(SOURCES ${GENERAL} ${GENERATED}) 

Esta línea establece las fuentes variables a lo que está en las variables ${GENERAL} y ${GENERATED}. Anteriormente configuramos ${GENERAL} como la lista de archivos cpp, h y cmake que se encontraban en el directorio de origen actual. En un pseudocódigo tipo C, esto es como "FUENTES = GENERAL + GENERADO". Como detalle de la implementación, el valor FUENTES es en realidad una lista y sus contenidos están separados por ";" caracteres. Por lo general, esto se hace para que luego pueda crear una biblioteca o ejecutable simplemente usando la variable ${SOURCES} en lugar de repetir las otras 2 variables en todas partes.

+0

¡Gracias! Desearía poder darte más de un voto positivo. Esta es una gran ayuda. –

6

A veces, puedo entender sus sentimientos acerca de los tutoriales de cmake. Recomiendo mirar los documentos en línea y en algunos proyectos de cmake: P. ej. Ogre, Vtk, Kde.

Por lo que usted parece CMakeLists.txt, parece que se supone que este debe ser llamado por un proyecto CMake externo (con add_subdirectory), porque se refiere a las variables PLUGIN_NAME, PLUGIN_INCLUDE_DIRS y GENERATED.

para responder a sus preguntas:

cmake_minimum_required (VERSION 2.6) 
set (CMAKE_BACKWARDS_COMPATIBILITY 2.6) 
Project(${PLUGIN_NAME}) 

Esto prepara su cmakefile, dice cmake que debe ser la versión 2.6 o superior y que va a iniciar un proyecto con un nombre como se especifica en la variable PLUGIN_NAME.

file (GLOB GENERAL RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} 
    [^.]*.cpp 
    [^.]*.h 
    [^.]*.cmake 
    ) 

Esta parte globos a través del directorio de fuente de corriente (aquel en el que CMakeLists.txt es) y recoge todos * .cpp, * .h y archivos * .cmake. El resultado es un conjunto/lista de rutas de archivos, relativo con resectivo al directorio fuente actual y se almacena en una variable GENERAL.

# Generated files are stored in ${GENERATED} by the project configuration 
SET_SOURCE_FILES_PROPERTIES(
    ${GENERATED} 
    PROPERTIES 
     GENERATED 1 
    ) 

SOURCE_GROUP(Generated FILES 
    ${GENERATED} 
    ) 

Al parecer, habrá un conjunto de fuente-archivos almacenados en la variable generada (por lo tanto no GENERAL). En el caso de los archivos fuente generados por compilación, estos archivos no están necesariamente allí en la primera compilación de CMake y CMake tendrá que saber que estos se generan.Con el comando set_source_files_properties, obtienen la propiedad "generado", que es necesaria para que CMake haga la verificación de dependencia correcta.

SET(SOURCES 
    ${GENERAL} 
    ${GENERATED} 
    ) 

Así que ahora tenemos un conjunto de archivos de origen de la (GLOB ...) de llamadas, archivo almacenado en la variable GENERAL. Y tenemos un conjunto de archivos soruce almacenados en la variable GENERATED que se crea en otro lugar. Estos dos conjuntos se combinan en una sola lista de archivos de origen y se almacenan en la variable FUENTES.

En circunstancias normales yo esperaría una llamada add_library: add_library ($ {PLUGIN_NAME} {SOURCES})

Esto especifica a Cmake que una nueva biblioteca se va a crear y construido a partir de la fuente de los archivos de las fuentes .

Cuestiones relacionadas