En el desarrollo de software , CMake es un software libre y de código abierto multiplataforma para la automatización de la compilación , prueba , empaquetado e instalación de software mediante un método independiente del compilador . [4] CMake no es un sistema de compilación en sí mismo; genera los archivos de compilación de otro sistema. [5] Admite jerarquías de directorios y aplicaciones que dependen de múltiples bibliotecas. Puede invocar entornos de compilación nativos como Make , Qt Creator , Ninja , Android Studio , Xcode de Apple y Microsoft Visual Studio . [5] Tiene dependencias mínimas, requiriendo solo un compilador de C++ en su propio sistema de compilación. [5]
CMake se distribuye como software gratuito y de código abierto bajo una licencia BSD-3-Clause permisiva . [6]
El desarrollo de CMake comenzó en 1999, en respuesta a la necesidad de un entorno de compilación multiplataforma para el Insight Segmentation and Registration Toolkit (ITK). [7] [5] El proyecto está financiado por la Biblioteca Nacional de Medicina de los Estados Unidos como parte del Proyecto Visible Human . [5] Se inspiró parcialmente en pcmaker
, un predecesor de CMake, que fue creado por Ken Martin y otros desarrolladores para respaldar la construcción del Visualization Toolkit (VTK) . pcmaker era un programa en C que convertía archivos Make en contrapartes NMake de MS Windows. [5] En Kitware , Bill Hoffman combinó componentes de pcmaker con sus propias ideas, esforzándose por imitar la funcionalidad de los scripts de configuración de Unix . CMake se implementó por primera vez en 2000 y se desarrolló aún más en 2001.
Históricamente, CMake fue concebido con las siguientes características principales en mente: [5]
Debido a estas restricciones, CMake no eligió utilizar el lenguaje de script Tcl (popular en ese momento) como su lenguaje predeterminado y, en su lugar, los desarrolladores decidieron crear un lenguaje de script más simple. [5]
El desarrollo y las mejoras continuas fueron impulsadas por la incorporación de CMake en los sistemas propios de los desarrolladores, incluido el Proyecto VXL , [ aclaración necesaria ] las características CABLE [8] agregadas por Brad King, [ aclaración necesaria ] y GE Corporate R&D para el soporte de DART. [ aclaración necesaria ] Se crearon características adicionales cuando VTK realizó la transición a CMake para su entorno de compilación y para soportar ParaView .
La versión 3.0 se lanzó en junio de 2014. [9] Se la ha descrito como el comienzo del "CMake moderno". [10] Los expertos ahora recomiendan evitar las variables en favor de los objetivos y las propiedades . [11] Los comandos add_compile_options
, include_directories
, link_directories
, link_libraries
que eran el núcleo de CMake 2 ahora deberían reemplazarse por comandos específicos del objetivo.
El desarrollador Brad King ha declarado que "la 'C' en CMake significa 'multiplataforma ' ". [12]
Una de sus principales características es la capacidad de colocar las salidas del compilador (como los archivos de objetos) en un árbol de compilación que se encuentra fuera del árbol de código fuente. [5] Esto permite múltiples compilaciones desde el mismo árbol de código fuente y la compilación cruzada . Los archivos de código fuente y de compilación separados garantizan que la eliminación de un directorio de compilación no afectará a los archivos de código fuente y evita el desorden que podría confundir a los sistemas de control de versiones. [5]
CMake realiza un seguimiento y vuelve a compilar todas las dependencias ascendentes de un submódulo determinado si se modifican sus fuentes. [5] [a]
CMake puede localizar ejecutables, archivos y bibliotecas de todo el sistema y especificados por el usuario. Estas ubicaciones se almacenan en una memoria caché , que luego se puede personalizar antes de generar los archivos de compilación de destino. La memoria caché se puede editar con un editor gráfico, que se incluye con CMake.
CMake es compatible con jerarquías de directorios complicadas y aplicaciones que dependen de varias bibliotecas. Por ejemplo, CMake puede adaptarse a un proyecto que tenga varios conjuntos de herramientas o bibliotecas que tengan varios directorios cada una. Además, CMake puede trabajar con proyectos que requieran la creación de ejecutables antes de generar el código que se compilará para la aplicación final. Su diseño extensible y de código abierto permite que CMake se adapte según sea necesario para proyectos específicos. [13]
CMake puede generar archivos de proyecto para varios IDE populares , como Microsoft Visual Studio , Xcode y Eclipse CDT . También puede producir scripts de compilación para MSBuild o NMake en Windows; Unix Make en plataformas similares a Unix como Linux , macOS y Cygwin ; y Ninja en plataformas Windows y similares a Unix.
CMake permite la especificación de características que el compilador debe soportar para compilar el programa o la biblioteca de destino. [14]
CMake admite una amplia lista de compiladores, incluidos: Apple Clang, Clang , GNU GCC , MSVC , Oracle Developer Studio y Intel C++ Compiler . [15]
Aunque CMake no es un gestor de paquetes , proporciona módulos básicos (consulte CPack), funciones para instalar binarios e información de paquetes declarada por el CMakeLists.txt
script que se utilizará en proyectos de CMake de consumo. El paquete también se puede empaquetar en un archivo de almacenamiento para el gestor de paquetes o el instalador compatible con una plataforma de destino. Los paquetes de terceros también se pueden importar a través de archivos CMake configurados que son proporcionados por el mismo tercero o creados manualmente. [16] : 132, 142 [17] [18]
Cmake se puede ejecutar utilizando un programa ncursesccmake
como el que se puede utilizar para configurar proyectos a través de la interfaz de línea de comandos.
La creación de un programa o una biblioteca con CMake es un proceso de dos etapas. [5] En primer lugar, se crean (generan) los archivos de creación (normalmente scripts) a partir de los archivos de configuración (scripts CMakeLists.txt) escritos en lenguaje CMake. A continuación, se invocan las herramientas de creación nativas de la plataforma que pueden leer estos archivos de creación (cadena de herramientas nativas) de forma manual o externa cmake --build
para la creación real de programas (objetivos de creación). [13] [19] El generador especificado por el usuario en la línea de comandos determina qué cadena de herramientas de creación se utilizará. [5]
Los archivos de compilación se configuran según el generador utilizado (por ejemplo, Makefiles de Unix para make ) y los archivos de la cadena de herramientas asociados. Los usuarios avanzados también pueden crear e incorporar generadores de makefiles adicionales para satisfacer sus necesidades específicas de compilador y sistema operativo. Los archivos generados generalmente se colocan (usando cmake
el indicador ' ) en una carpeta fuera de la de la fuente (compilación fuera de la fuente), por ejemplo, build/
.
Cada proyecto de compilación a su vez contiene su propio CMakeCache.txt
archivo y CMakeFiles
directorio en cada (sub)directorio de proyecto incluido por el add_subdirectory(...)
comando, lo que ayuda a evitar o acelerar la regeneración cuando se ejecuta repetidamente.
El proceso de generación y la salida se pueden ajustar mediante propiedades de destino. Anteriormente, esto se hacía mediante CMAKE_...
variables globales con prefijo - que también se utilizan para configurar CMake y para establecer valores predeterminados iniciales. [11] [20] Ahora se desaconseja el enfoque anterior.
Según la configuración de CMakeLists.txt, los archivos de compilación pueden ser ejecutables, bibliotecas (por ejemplo libxyz
, , xyz.dll
etc.), bibliotecas de archivos de objetos o pseudo-objetivos (incluidos alias). CMake puede producir archivos de objetos que se pueden vincular mediante bibliotecas/binarios ejecutables, evitando la vinculación dinámica (en tiempo de ejecución) y utilizando en su lugar la vinculación estática (en tiempo de compilación). Esto permite flexibilidad en la configuración de varias optimizaciones. [21]
Las dependencias de compilación se pueden determinar automáticamente.
Es posible generar encabezados precompilados utilizando CMake desde la versión 3.6. [22]
CMake tiene un lenguaje de programación imperativo e interpretado relativamente simple . Admite variables, métodos de manipulación de cadenas, matrices, declaraciones de funciones/macro e inclusión de módulos (importación). Los comandos (o directivas) del lenguaje CMake se leen desde cmake
un archivo llamado CMakeLists.txt
. Este archivo especifica los archivos de origen y los parámetros de compilación, que CMake colocará en la especificación de compilación del proyecto (como un Makefile). Además, .cmake
los archivos con el sufijo - pueden contener scripts utilizados por CMake. [23]
Para generar los archivos de compilación de un proyecto, se invoca cmake
en la terminal y se especifica el directorio que contiene CMakeLists.txt
. Este archivo contiene uno o más comandos en formato COMMAND(argument ...)
.
Los argumentos de los comandos están separados por espacios en blanco y pueden incluir palabras clave para separar grupos de argumentos. Los comandos pueden aceptar palabras clave. Por ejemplo, en el comando la palabra clave es . Sirve como delimitador entre la lista de archivos fuente y algunas otras opciones. [24]SET_SOURCE_FILE_PROPERTIES(source_file ... COMPILE_FLAGS compiler_option ...)
COMPILE_FLAGS
Ejemplos de comandos que CMake ofrece para especificar objetivos y sus dependencias y que sirven como punto de partida de CMakeLists.txt: [25] [26] [27]
add_executable(...)
— declara un objetivo binario ejecutable con fuentes (dependiendo del lenguaje elegido) para ser compiladoadd_library(...)
— lo mismo pero para una bibliotecatarget_link_libraries(...)
— agrega dependencias, etc.CMake admite la extracción de valores en variables desde cadenas de datos JSON (desde la versión 3.19). [28]
El lenguaje de scripting CMake se implementa mediante el uso de generadores Yacc y Lex . [b]
Los programas ejecutables CMake, CPack y CTest están escritos en el lenguaje de programación C++ . [b]
Gran parte de la funcionalidad de CMake se implementa en módulos escritos en el lenguaje CMake. [29]
Desde la versión 3.0, la documentación de CMake utiliza el marcado reStructuredText . Las páginas HTML y las páginas de manual se generan mediante el generador de documentación Sphinx .
CMake se entrega con numerosos .cmake
módulos y herramientas que facilitan tareas como la búsqueda de dependencias (tanto integradas como externas, por ejemplo, FindXYZ
módulos), la prueba del entorno de la cadena de herramientas y los ejecutables, la creación de paquetes de versiones ( CPack
módulo y cpack
comando) y la gestión de dependencias en proyectos externos ( ExternalProject
módulo): [30] [31]
CPack es un sistema de empaquetado para distribuciones de software. Está estrechamente integrado con CMake pero puede funcionar sin él. [32] [33]
Se puede utilizar para generar:
CMake ha sido ampliamente adoptado entre proyectos de software comerciales, de código abierto y académicos. Algunos usuarios notables incluyen Android NDK , Netflix , Inria , MySQL , Boost (bibliotecas C++) , KeePassXC , KDE , KiCAD , FreeCAD , Webkit , Blender , [34] Biicode, ReactOS , Apache Qpid , el experimento ATLAS , [35] y Second Life . [36]
Los siguientes archivos de código fuente demuestran cómo crear un programa simple de hola mundo escrito en C++ utilizando CMake.
// hola.cpp #include <iostream> int main () { std :: cout << "¡Hola, mundo!" << std :: endl ; devuelve 0 ; }
# CMakeLists.txt cmake_minimum_required ( VERSIÓN 3.5 ) proyecto ( HelloWorld CXX ) add_executable ( hola hola.cpp )
// hola.cpp #include "hola_encabezado.h" #include <iostream> int main () { for ( int i = 0 ; i < Times ; i ++ ) { std :: cout << "¡Hola, mundo!" << std :: endl ; } devuelve 0 ; }
// hola_encabezado.h #ifndef HOLA_ENCABEZADO_H_ #define HOLA_ENCABEZADO_H_ const int Times = 10 ; #endif
# CMakeLists.txt cmake_minimum_required ( VERSIÓN 3.5 ) proyecto ( HelloWorld CXX ) incluir_directorios ( ${ PROJECT_SOURCE_DIR } ) agregar_ejecutable ( hola hola.cpp )
Comandos de shell para ejecutar CMake en un sistema Linux (deben ingresarse en el directorio que contiene los dos archivos anteriores):
cmake -B build . # Configurar el directorio de compilación.
cmake --build build # Construir el programa en el directorio de compilación.
./build/hello # Ejecutar el programa (genera "¡Hola, mundo!")