2012-03-12 21 views
11

Estoy empezando a jugar con CMake. Tengo algo como:CMakeLists.txt archivos para múltiples bibliotecas y ejecutables

/DEV 
|-- lib1 
     | CMakeLists.txt 

|-- lib2 
     | CMakeLists.txt 

|-- exe1 
     | CMakeLists.txt 

/BUILD 
|-- lib1 
|-- lib2 
|-- exe1 

/INSTALL 
|-- include 
|-- lib 
|-- bin 

me gustaría:

  • Construir cada lib y exe de forma independiente cuando sea necesario. (Así que supongo que debo agregar un archivo CMakeLists.txt para cada lib y exe);
  • Al compilar, los directorios include y lib deben hacer referencia al directorio INSTALL; (¿es una buena idea?)
  • Al construir, agregue dependencias a otras librerías y reconstruya las mismas si no están actualizadas.

No tengo ni idea de por dónde empezar. Por favor, ayuda ...

+0

Además de arrowdodgers respuesta excelente: compilar una sola lib, exe también se puede hacer de forma independiente mediante el comando cd'ing en el directorio de compilación generado para esa lib y llama a make/msbuild. P.ej. con Visual Studio, cmake generará un archivo de solución para cada lib/exe si lib/exe tiene su propio CMakeLists.txt con un comando project() –

Respuesta

11

No necesita CMakeLists.txt individual para compilar objetivos de forma independiente. Digamos que tiene una CMakeLists.txt nivel superior con:

ADD_LIBRARY(lib1 ${all_lib1_files}) 
ADD_LIBRARY(lib2 ${all_lib2_files}) 
ADD_EXECUTABLE(exe1 ${all_exe1_files}) 
TARGET_LINK_LIBRARIES(lib2 lib1) # lib2 now depends on lib1 
TARGET_LINK_LIBRARIES(exe1 lib2) # exe1 now depends on lib2 and lib1 

entonces usted puede construir solo LIB1 ejecutando make lib1 o msbuild lib1.vcxproj, etc. Se puede lograr el mismo por tener archivos individuales CMakeLists.txt por blanco - que depende de si crees que vale la pena.

Si su proyecto importa estos objetivos utilizando FIND_LIBRARY o FIND_PACKAGE, entonces ellos no se reconstruirán si no están al día. En última instancia, si desea que las dependencias desactualizadas se reconstruyan automáticamente, debe informar a CMake acerca de las fuentes y las reglas para el objetivo dependiente, es decir, que el archivo CMakeLists.txt debe haber agregado el destino utilizando ADD_LIBRARY o ADD_EXECUTABLE.

No debería necesitar hacer referencia al directorio INSTALL (excepto en los comandos INSTALL, imagino), ya que CMake utilizará libs/exes las ubicaciones de compilación en lugar de las ubicaciones instaladas al vincular los destinos.

+0

parece una mejor solución para mí. ¿Debo poner el archivo CMakeLists.txt en el nivel superior o podría poner ese archivo en cada carpeta ejecutable? ¿O hay alguna "magia recursiva" I debería tener en cuenta? ¡Gracias! – Korchkidu

+2

Es normal que tenga su CMakeLists.txt principal en la raíz de su proyecto. Si lo desea, puede agregar archivos CMakeLists.txt a cada carpeta exe y luego 'INCLUDE' cada uno de estos.' INCLUDE' ejecuta los comandos en línea, por lo que no es necesario que estos archivos subordinados CMakeLists.txt sean completamente independientes (es decir, no necesitan el comando 'PROJECT', etc.), simplemente serían una forma de lograr la separación de los diferentes partes del proyecto y mantener el archivo de nivel superior más limpio. Cada uno podría tener 'SET (all_exe1_files ...)', 'ADD_EXECUTABLE (exe1 $ {all_exe1_files})' y 'SET_TARGET_PROPERTIES (exe1 ...)'. – Fraser

+0

¡Excelente! ¡Muchas gracias! – Korchkidu

3

Para

Construir cada lib y exe de forma independiente cuando sea necesario.

sólo tiene que añadir EXCLUDE_FROM_ALL palabra clave en add_executable() o add_library() llamadas.

Cuando la construcción, y se incluyen directorios lib debe hacer referencia INSTALAR directorio

Si por referencing que significa añadir a include_directories() y link_directories() entonces no es agradable. Es mejor no afirmar en la ubicación de los archivos necesarios en el sistema del usuario. La forma correcta es ubicar los includes includes y las bibliotecas usando find_package(), find_library() o find_file(). Si desea utilizar la primera función, deberá escribir FindYourLib.cmake e instalarla junto con la biblioteca.

Cuando la construcción, agregar dependencias a otra lib y reconstruirlos si no al día

Esto se hace automáticamente por CMake. Las dependencias se pueden agregar con la función add_dependencies() o implícitamente con target_link_libraries().

+0

"entonces ahora es agradable". ¿es un error tipográfico o algo así? Además, las libs en el directorio INSTALL son nuestras y solo están disponibles para desarrolladores. No los vamos a distribuir. Están vinculados estáticamente a ejecutables que se vuelven a distribuir por paquetes. Por lo tanto, preferimos no "instalar" realmente nuestras bibliotecas en el sistema, sino mantenerlas separadas. ¿Tiene más sentido? ¡Gracias por tu respuesta! – Korchkidu

+1

Una dependencia importada no será reconstruida. De los documentos de CMake: "Las dependencias añadidas a un objetivo IMPORTADO se siguen transitivamente en su lugar, ya que el objetivo en sí no se genera". Además, 'EXCLUDE_FROM_ALL' no tiene nada que ver con la construcción del objetivo de forma independiente, simplemente evita que el objetivo se construya como parte del objetivo de ALL_BUILD' CMake. Finalmente, la forma correcta de incluir otro proyecto CMake en el suyo es usar el comando 'INSTALL (EXPORT ...' en la dependencia, y luego simplemente 'INCLUDE' el archivo exportado' .cmake' en el suyo. Ejecute 'cmake - -help-command INSTALAR' para más detalles. – Fraser

Cuestiones relacionadas