En el desarrollo de software , CMake es un software multiplataforma , gratuito y de código abierto para la automatización de la compilación , las pruebas , el empaquetado y la instalación de software mediante el uso de 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 , Apple's Xcode y Microsoft Visual Studio . [5] Tiene dependencias mínimas y solo requiere 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 permisiva de cláusula BSD-3 . [6]
El desarrollo de CMake comenzó en 1999, en respuesta a la necesidad de un entorno de compilación multiplataforma para 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 Humano Visible . [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 sus homólogos 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 se concibió teniendo en cuenta las siguientes características principales: [5]
Debido a estas limitaciones, CMake no eligió utilizar el lenguaje de secuencias de comandos Tcl (popular en ese momento) como predeterminado y, en su lugar, los desarrolladores decidieron crear un lenguaje de secuencias de comandos más simple. [5]
El desarrollo y las mejoras continuos fueron impulsados por la incorporación de CMake en los propios sistemas de los desarrolladores, incluido el Proyecto VXL , [ se necesita aclaración ] las características de CABLE [8] agregadas por Brad King, [ se necesita aclaración ] y GE Corporate R&D para respaldar a DART. [ se necesita aclaración ] Se crearon funciones adicionales cuando VTK hizo la transición a CMake para su entorno de compilación y para admitir ParaView .
La versión 3.0 se lanzó en junio de 2014. [9] Se ha descrito como el comienzo del "CMake moderno". [10] Los expertos ahora aconsejan evitar variables a favor de objetivos y propiedades . [11] Los comandos add_compile_options
,,, que eran el núcleo de CMake 2 ahora deberían reemplazarse por comandos específicos del objetivo include_directories
.link_directories
link_libraries
El desarrollador Brad King ha declarado que "la 'C' en CMake significa 'multiplataforma ' ". [12]
Una de sus características principales es la capacidad de colocar las salidas del compilador (como archivos objeto) en un árbol de compilación que se encuentra fuera del árbol fuente. [5] Esto permite múltiples compilaciones desde el mismo árbol fuente y compilación cruzada . Los archivos fuente y de compilación separados garantizan que la eliminación de un directorio de compilación no afecte a los archivos fuente y evite 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 cambian sus fuentes. [5] [un]
CMake puede localizar bibliotecas, archivos y ejecutables especificados por el usuario y en todo el sistema. Estas ubicaciones se almacenan en una memoria caché , que luego se puede personalizar antes de generar los archivos de compilación de destino. El caché se puede editar con un editor gráfico, que se incluye con CMake.
CMake admite jerarquías de directorios complicadas y aplicaciones que dependen de varias bibliotecas. Por ejemplo, CMake puede acomodar un proyecto que tiene múltiples kits de herramientas o bibliotecas, cada una de las cuales tiene múltiples directorios. Además, CMake puede trabajar con proyectos que requieren 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 Unix.
CMake permite especificar las características que el compilador debe admitir para poder compilar el programa o biblioteca de destino. [14]
CMake admite una lista extensa de compiladores, que incluyen: Apple Clang, Clang , GNU GCC , MSVC , Oracle Developer Studio e Intel C++ Compiler . [15]
Aunque CMake no es un administrador de paquetes , proporciona funciones de módulos básicos (consulte CPack) para instalar archivos binarios e información de paquetes declarada por el CMakeList.txt
script para ser utilizada por proyectos de consumidores de CMake. El paquete también se puede empaquetar en un archivo para el administrador 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 mediante un programa ncursesccmake
como ese que se puede utilizar para configurar proyectos a través de una interfaz de línea de comandos.
La construcción de un programa o biblioteca con CMake es un proceso de dos etapas. [5] Primero, los archivos de compilación (generalmente scripts) se crean (generan) a partir de archivos de configuración (scripts CMakeLists.txt) escritos en lenguaje CMake. Luego, las herramientas de compilación nativas de la plataforma que pueden leer estos archivos de compilación (cadena de herramientas nativa) se invocan manualmente de forma externa o mediante cmake --build
la compilación real de programas (objetivos de compilación). [13] [19] El generador especificado por el usuario en la línea de comando determina qué cadena de herramientas de compilación usar. [5]
Los archivos de compilación se configuran según el generador utilizado (por ejemplo, Unix Makefiles para make ) y los archivos de cadena de herramientas asociados. Los usuarios avanzados también pueden crear e incorporar generadores de archivos MAKE adicionales para satisfacer sus necesidades específicas de compilador y sistema operativo. Los archivos generados normalmente se colocan (usando cmake
el indicador ') en una carpeta fuera de la fuente (fuera de la compilación 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 las propiedades de destino. Anteriormente, se hacía mediante CMAKE_...
variables globales con prefijo que también se utilizan para configurar CMake y establecer los valores predeterminados iniciales. [11] [20] Actualmente se desaconseja el enfoque anterior.
Dependiendo de 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 pseudoobjetivos (incluidos los alias). CMake puede producir archivos objeto que se pueden vincular mediante binarios/bibliotecas ejecutables, evitando vínculos dinámicos (en tiempo de ejecución) y utilizando en su lugar vínculos estáticos (en tiempo de compilación). Esto permite flexibilidad en la configuración de varias optimizaciones. [21]
Las dependencias de compilación pueden determinarse automáticamente.
Es posible generar encabezados precompilados usando 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 cmake
desde un archivo llamado CMakeLists.txt
. Este archivo especifica los archivos fuente 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 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 tomar 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 ofrece CMake 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 idioma elegido) que se construiráadd_library(...)
— lo mismo pero para una bibliotecatarget_link_libraries(...)
- agrega dependencias, etc.CMake admite la extracción de valores en variables de cadenas de datos JSON (desde la versión 3.19). [28]
El lenguaje de programación 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 son generadas por el generador de documentación Sphinx .
CMake se entrega con numerosos .cmake
módulos y herramientas. Estos facilitan trabajos como encontrar dependencias (tanto integradas como externas, por ejemplo, FindXYZ
módulos), probar el entorno de la cadena de herramientas y los ejecutables, empaquetar versiones ( CPack
módulo y cpack
comando) y gestionar 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 Segunda vida . [36]
Los siguientes archivos de código fuente demuestran cómo crear un programa simple de Hola Mundo escrito en C++ mediante CMake.
// hola.cpp #include <iostream> int main () { std :: cout << "¡Hola mundo!" << std :: endl ; devolver 0 ; }
# CMakeLists.txt cmake_minimum_required ( VERSIÓN 3.5 ) proyecto ( HelloWorld CXX ) add_executable ( hola hola.cpp )
// hola.cpp #include <iostream> #incluye "hola_heading.h" int main () { for ( int i = 0 ; i < Times ; i ++ ) { std :: cout << "¡Hola mundo!" << std :: endl ; } devolver 0 ; }
// hola_heading.h #ifndef HOLA_HEADING_H_ #define HOLA_HEADING_H_ const int Veces = 10 ; #terminara si
# CMakeLists.txt cmake_minimum_required ( VERSIÓN 3.5 ) proyecto ( HelloWorld CXX ) include_directories ( ${ PROJECT_SOURCE_DIR } ) add_executable ( hola hola.cpp )
Comandos de Shell para ejecutar CMake en un sistema Linux (que se ingresarán en el directorio que contiene los dos archivos anteriores):
cmake -B construir . # Configurar el directorio de compilación. cmake --build build # Construye el programa en el directorio de compilación. ./build/hello # Ejecuta el programa (muestra "¡Hola, mundo!")