Es una herramienta para multiplataforma para generar Makefiles a partir de scripts y poder compilar proyectos escritos en C, C++, Objective-C o Fortran usando un lenguaje más elevado que el propio Makefile o proyectos de IDEs comunes.
¿Para que sirve y porque usarlo?
Tiene capacidad para generar proyectos de Eclipse, Visual Studio, o plain Makefiles a partir de dichos scripts (CMakeLists.txt) para facilitar el desarrollo de un proyecto. Además, al estar orientado a cualquier plataforma y enfocado a facilitar la crosscompilación mediante toolchains, facilita la compilación en cualquier plataforma GNU/Linux, MAC y Windows con cualquier target (x86, ARM).
Hay que tener en cuenta que no hace magia, el propio código siempre tiene que estar adaptado a cada plataforma, tener precondiciones para que funcione en todas, etc. No obstante, usar CMake facilita mucho la adaptación si tienes en cuenta ciertos detalles que se adquieren con la experiencia.
Organización
A la hora de organizar un proyecto, lo primero que se tiene que tener claro es como lo vamos a organizar. Recomiendo usar control de versiones git, ya sea administrado por nosotros mismos o usando uno de los servicios populares: Github o Bitbucket. Sugiero utilizar diversas carpetas para separar conceptualmente las distintas partes del código, por ejemplo:
Proyecto general:
Constará con la configuración del proyecto en lineas generales, y la organización del código. Se recomienda tener unos ficheros básicos en la carpeta raiz del proyecto:
- CMakeLists.txt principal que configure el proyecto usado por CMake.
- README.md que explique que hace el proyecto, autores, datos de interés...
- Contributing.md, fichero opcional para informar al que quiera contribuir en el proyecto.
- License, fichero con la licencia del código, aunque este en las cabeceras de el source code, es importante dejarlo claro.
- Modules: Carpeta con las distintas librerias, bien sean estáticas o dinámicas que componen nuestro proyecto. Contendrán todo el código de la librería separado conceptualmente en distintas sublibrerías si procede. No debe contener ejecutables.
- 3rdParty: Carpeta con todo el código de terceros, ya sea en submodulos de git
- Samples: Carpeta con minimo código para crear ejecutables de ejemplo de funciones básicas de la libreria, o ejemplos complejos ilustrativos.
- Test: Carpeta con todos los test unitarios para probar los módulos si son necesarios. Esta carpeta es opcional. Por ejemplo usando GTests
- cmake, carpeta con los módulos y otros scripts de cmake utiles para compilar el proyecto.
Será todo aquel en un subdirectorio del proyecto general. Puede ser un ejecutable o una librería de nuestro proyecto general. Se sugiere que conste con:
- CMakeLists.txt: Fichero con la configuración de ese subproyecto concreto.
- src: Carpeta con todos los ficheros *.cpp, *.c, *.m del subproyecto.
- include: Carpeta con todos los ficheros *.h, *.hpp del subproyecto
Por ejemplo, yo suelo tener una carpeta con el proyecto que contiene:
- git, carpeta con todos los repositorios relacionados con el proyecto.
- doc, carpeta con toda la documentación o referencias relacionadas.
- build, carpeta con todas las plataformas compiladas, pruebas, Doxygen documentation output, etc.
CMake dispone de muchos comandos y variables importantes, que pueden ser consultadas en su referencia, y que nos ayudarán a configurar nuestro proyecto. Por supuesto, puedes crearte tus propios comandos, o macros si lo prefieres, llamar a ejecutables como hacen los Makefiles, y muchas cosas más.
CMAKE_CONFIGURATION_TYPES, configura Release, debug... en proyectos como VS
PROJECT_BINARY_DIR, variable que apunta a la base de la carpeta build
CMAKE_VERBOSE, información extra al generar el proyecto-
CMAKE_DEBUG_POSTFIX, sufijo en el caso de target debug
CMAKE_CURRENT_SOURCE_DIR, el proyecto donde se ejecuta el actual CMakeLists.txt
cmake_minimum_required(VERSION 2.8.8), versión minima probada de los scripts
PROJECT(${PROJ_MAIN_NAME}), Crea un proyecto con el nombre de la variable PROJ_MAIN_NAME.
ADD_SUBDIRECTORY, añade una subcarpeta al script actual, para revisar su CMakeLists.txt
ADD_EXECUTABLE, A partir del código proporcionado después del comando PROJECT, crea un ejecutable.
ADD_LIBRARY, lo mismo que ADD_EXECUTABLE pero creando una librería estática o dinámica según la opción proporcionada.
LINK_DIRECTORIES, provee paths que contentan librerías que necesita el proyecto
TARGET_LIBRARY, provee el nombre de las librerías necesitadas.
MESSAGE, comando para printear información, datos o variables.
Tengo un pequeño repositorio en Github de código abierto llamado CMake-supporter. Utilizado como submodulo en un repositorio o simplemente copiando el código en la carpeta cmake, puede ser usado para manejar toolchains que compilan código en C++ para iOS y Android, también tiene templates de los proyectos principales y está perfectamente documentado como usarlos. Si no tienes mucha idea de CMake, pueden serte de utilidad tanto para no pensar en organizar un proyecto, como para aprender n poco sobre este sistema.
Un ejemplo:
Puedes ver el funcionamiento de un proyecto de prueba más avanzado que lo usa como submodulo en este repositorio. Simplemente haz:git clone --recursive https://github.com/vgonisanz/cmake-supporter-sampleConfigura y ejecuta el proyecto, y trata de compilarlo.
Trabajo futuro:
A parte de que mejoraré CMake-supporter, y el ejemplo, estoy pensando como generar automáticamente con unos pocos datos la estructura del proyecto, ya adaptada para no tener que copiar los templates y renombrar a mano, crear las carpetas, etc. Os mantendré informados.
Otros enlaces utiles:
- http://www.cmake.org/cmake-tutorial/
- http://outcoldman.com/en/archive/2014/05/02/xcode-and-cmake/
- http://voices.canonical.com/jussi.pakkanen/2013/03/26/a-list-of-common-cmake-antipatterns/
No hay comentarios:
Publicar un comentario