¿Cómo funciona exactamente CMake? ¿Por qué se generan tantos archivos?
¿Qué estaba pasando exactamente detrás de escena cuando, para un archivo CMakeLists.txt tan pequeño,
cmake_minimum_required (VERSION 2.6)
project(Tutorial)
add_executable(Tutorial tutorial.cpp)
y tan pequeñotutorial.cpp
int main() { return 0; }
hay tantos archivos generados:
CMakeCache.txt cmake_install.cmake Makefile
CMakeLists.txt tutorial.cpp
Y una carpeta CMakeFiles con tantos archivos y carpetas:
CMakeCCompiler.cmake CMakeOutput.log Makefile.cmake
cmake.check_cache CMakeSystem.cmake progress.marks
CMakeCXXCompiler.cmake CMakeTmp TargetDirectories.txt
CMakeDetermineCompilerABI_C.bin CompilerIdC Tutorial.dir
CMakeDetermineCompilerABI_CXX.bin CompilerIdCXX
CMakeDirectoryInformation.cmake Makefile2
No comprender lo que sucedía detrás de escena (es decir, por qué era necesario generar tantos archivos y cuál era su propósito) fue el mayor obstáculo para poder aprender CMake.
¿Cuál es el propósito de estos archivos y, cuando escribo cmake .
, qué configura y genera exactamente CMake antes de construir el proyecto?
El secreto es que no es necesario comprender qué hacen los archivos generados.
CMake introduce mucha complejidad en el sistema de compilación, la mayor parte de la cual solo vale la pena si se usa para crear proyectos de software complejos.
La buena noticia es que CMake hace un buen trabajo al mantener lejos de usted gran parte de este desorden: use compilaciones fuera de fuente y ni siquiera tendrá que mirar los archivos generados. Si no hizo esto hasta ahora (que supongo que es el caso, ya que escribió cmake .
), revíselos antes de continuar . Mezclar el directorio de compilación y de origen es realmente complicado con CMake y no es la forma en que se supone que debe usarse el sistema.
En pocas palabras: en lugar de
cd <source_dir>
cmake .
siempre usa
cd <build_dir_different_from_source_dir>
cmake <source_dir>
Normalmente uso una subcarpeta vacía build
dentro de mi directorio fuente como directorio de compilación.
Para aliviar su dolor, permítame brindarle una descripción general rápida de los archivos relevantes que genera CMake:
- Archivos de proyecto/Makefiles : lo que realmente le interesa: Los archivos necesarios para construir su proyecto con el generador seleccionado. Puede ser cualquier cosa, desde un Makefile de Unix hasta una solución de Visual Studio.
- CMakeCache.txt : este es un almacenamiento de cadena de clave/valor persistente que se utiliza para almacenar en caché el valor entre ejecuciones. Los valores almacenados aquí pueden ser rutas a las dependencias de la biblioteca o si se va a crear un componente opcional. La lista de variables es prácticamente idéntica a la que ve cuando ejecuta
ccmake
ocmake-gui
. Puede ser útil revisar esto de vez en cuando, pero recomendaría usar las herramientas antes mencionadas para cambiar cualquiera de los valores si es posible. - Archivos generados : pueden ser cualquier cosa, desde archivos fuente generados automáticamente hasta macros de exportación que le ayudan a reintegrar su proyecto creado con otros proyectos de CMake. La mayoría de estos solo se generan bajo demanda y no aparecerán en un proyecto simple como el de su pregunta.
- Cualquier otra cosa es bastante ruido para mantener contento al sistema de construcción. En particular, nunca tuve que preocuparme por nada de lo que sucede dentro del
CMakeFiles
subdirectorio.
En general, no deberías meterte con ninguno de los archivos que CMake genera para ti. Todos los problemas pueden resolverse desde dentro CMakeLists.txt
de una forma u otra. Siempre que el resultado construya su proyecto como se esperaba, probablemente esté bien. No se preocupe demasiado por los detalles sangrientos, ya que esto es lo que CMake intentaba evitarle en primer lugar.
Como se indica en su sitio web:
CMake es un sistema de compilación de código abierto y multiplataforma para gestionar el proceso de compilación de software utilizando un método independiente del compilador.
En la mayoría de los casos, se utiliza para generar archivos de proyecto/creación. En su ejemplo, ha producido Makefile que se utilizan para crear su software (principalmente en la plataforma Linux/Unix).
CMake permite proporcionar archivos de compilación multiplataforma que generarían archivos de creación/proyecto específicos de la plataforma para una compilación/plataforma en particular.
Por ejemplo, puede intentar compilar su software en Windows con Visual Studio y luego, con la sintaxis adecuada en su archivo CMakeLists.txt , puede iniciar
cmake .
dentro del directorio de su proyecto en la plataforma Windows. CMake generará todos los archivos necesarios del proyecto/solución ( .sln
, etc.).
Si desea crear su software en la plataforma Linux/Unix, simplemente vaya al directorio de origen donde tiene su archivo CMakeLists.txt , active el mismo cmake .
y generará todos los archivos necesarios para que pueda crear software mediante un proceso simple make
o make all
.
Aquí tenéis una muy buena presentación sobre las funcionalidades clave de CMake: Aprendiendo CMake (Pau García i Quiles)
Si desea que la biblioteca dependiente de la plataforma incluya/definiciones de variables, etc., puede usar esta sintaxis en el archivo CMakeLists.txt :
IF(WIN32)
...do something...
ELSE(WIN32)
...do something else...
ENDIF(WIN32)
También hay muchos comandos con los que puede evitar que la compilación falle y, en su lugar, CMake le notificará que, por ejemplo, no tiene bibliotecas Boostfilesystem
instaladas regex
en su sistema. Para hacer eso puedes usar la siguiente sintaxis:
find_package(Boost 1.45.0 COMPONENTS filesystem regex)
Habiendo verificado que generará los archivos MAKE para el sistema/IDE/compilador apropiado.
Cómo funciona exactamente CMake es una pregunta para los desarrolladores, por lo que esta pregunta no se puede responder aquí.
Sin embargo, podemos brindarle una guía útil sobre cuándo debe usar CMake y cuándo, por lo tanto, debe preocuparse por cómo funciona. Tampoco soy partidario de las respuestas de "oh, simplemente funciona", porque, especialmente en el software, nada "simplemente funciona" y siempre hay que entrar en los detalles esenciales en algún momento.
CMake es una herramienta de potencia industrial. Automatiza varios procesos muy complejos y tiene en cuenta muchas variables que quizás no conozcas, especialmente como desarrollador relativamente nuevo, que probablemente trabaja con un conocimiento limitado de todos los sistemas operativos y herramientas de compilación que CMake puede manejar. La razón por la que se generan tantos archivos y por la que las cosas parecen tan complejas es porque todos esos otros sistemas son complejos y deben contabilizarse y automatizarse.
Además, existen problemas de "almacenamiento en caché" y otras funciones de la herramienta que ahorran tiempo. Comprender todo en CMake significaría comprender todo en estas herramientas de compilación y sistemas operativos y todas las combinaciones posibles de estas variables, lo cual, como puede imaginar, es imposible.
Es importante tener en cuenta que si no está a cargo de administrar un gran sistema de compilación multiplataforma y su código base es de unos pocos KLOC, tal vez hasta 100 KLOG, usar CMake se parece un poco a usar un árbol forestal de 100.000 dólares. Máquina quitamalezas para quitar las malas hierbas de su jardín de flores de 2 pies por 2 pies (60 x 60 cm). (Por cierto, si nunca has visto una máquina así, deberías buscar una en YouTube; son increíbles).
Si su sistema de compilación es pequeño y simple, probablemente sea mejor escribir sus propios archivos MAKE a mano o escribirlos usted mismo. Cuando sus archivos MAKE se vuelven difíciles de manejar o necesita crear una versión de su sistema en otra plataforma, puede cambiar a CMake. En ese punto, tendrás muchos problemas que resolver y podrás hacer preguntas más específicas al respecto. Mientras tanto, consulte algunos de los fantásticos libros que se han escrito sobre CMake o, mejor aún, ¡escriba uno usted mismo! 8)