Codifico en C/C++ y uso un Makefile (GNU) para compilar el código. Puedo hacer lo mismo con CMake y obtener un Makefile. Sin embargo, ¿cuál es la diferencia entre usar Makefile y CMake para compilar el código?
¿Cuál es la diferencia entre usar un Makefile y CMake para compilar el código?
rico
Angew ya no está orgulloso de SO
Make (o más bien un Makefile) es un sistema de compilación: impulsa el compilador y otras herramientas de compilación para compilar su código.
CMake es un generador de sistemas de compilación. Puede producir Makefiles, puede producir archivos de construcción Ninja, puede producir proyectos KDEvelop o Xcode, puede producir soluciones de Visual Studio. Desde el mismo punto de partida, el mismo archivo CMakeLists.txt. Entonces, si tiene un proyecto independiente de la plataforma, CMake es una forma de hacerlo también independiente del sistema de compilación.
Si tiene desarrolladores de Windows acostumbrados a Visual Studio y desarrolladores de Unix que juran por GNU Make, CMake es (uno de) el camino a seguir.
Siempre recomendaría usar CMake (u otro generador de sistemas de compilación, pero CMake es mi preferencia personal) si pretende que su proyecto sea multiplataforma o ampliamente utilizable. CMake en sí mismo también proporciona algunas características interesantes como la detección de dependencias, la gestión de la interfaz de la biblioteca o la integración con CTest, CDash y CPack.
El uso de un generador de sistemas de compilación hace que su proyecto esté más preparado para el futuro. Incluso si ahora es GNU-Make-only, ¿qué sucede si luego decide expandirse a otras plataformas (ya sea Windows o algo incrustado), o simplemente quiere usar un IDE?
-
¡gracias! Solo para confirmar, que si solo programo en un entorno Linux, solo el archivo MAKE es adecuado, pero si quiero que el programa de Linux se ejecute en Mac, cmake es una mejor opción, ya que entiendo que no necesitamos hacer un nuevo archivo MAKE en la Mac, sino simplemente ejecutar el cmake. ¿Es ese el punto?
– rico
12 de septiembre de 2014 a las 10:17
-
@rish Sí, esa es la esencia. Sin embargo, tenga en cuenta que hay más formas de programar en Linux que Makefiles; consulte, por ejemplo, QtCreator, KDEvelop, Ninja. Para cada uno de estos, es “crear un proyecto y mantenerlo sincronizado con el Makefile” o “volver a ejecutar CMake”. Y, como menciona la respuesta, CMake también tiene otra funcionalidad, como el descubrimiento de dependencias (por ejemplo,
find_package()
) o soporte de pruebas/empaquetado.– Angew ya no está orgulloso de SO
12/09/2014 a las 10:22
-
Leí que CMake no puede crear archivos MAKE no recursivos. ¿Sigue siendo cierto?
– Máximo Egorushkin
12/09/2014 a las 15:17
-
@Angew no recursivo es cuando make se invoca una vez con el árbol de dependencia del proyecto completo. Opuesto a recursivo cuando un archivo MAKE de nivel superior invoca archivos MAKE de subproyectos en cierto orden.
– Máximo Egorushkin
12/09/2014 a las 15:24
-
Esta es una debilidad importante de CMake: GNU make tiene sus defectos, pero si se toma el tiempo de aprenderlo, es extremadamente poderoso y versátil, y funciona en una enorme cantidad de plataformas. No tener un árbol de dependencias completo para analizar es una falla importante, solo busque en Google ‘marca recursiva considerada dañina’.
– Erik Alapää
23 de diciembre de 2015 a las 7:39
Víctor Sergio
La afirmación de que CMake es un “generador de compilación” es un error común.
No es técnicamente incorrecto; simplemente describe CÓMO funciona, pero no QUÉ hace.
En el contexto de la pregunta, hacen lo mismo: toman un montón de archivos C/C++ y los convierten en binarios.
Entonces, ¿cuál es la verdadera diferencia?
-
CMake es mucho más de alto nivel. Está diseñado para compilar C ++, para lo cual escribe mucho menos código de compilación, pero también se puede usar para compilaciones de propósito general.
make
también tiene algunas reglas integradas de C/C++, pero en el mejor de los casos son inútiles. -
CMake
hace una compilación de dos pasos: genera un script de compilación de bajo nivel enninja
omake
o muchos otros generadores, y luego lo haces funcionar. Todas las piezas de script de shell que normalmente se apilan enMakefile
sólo se ejecutan en la etapa de generación. Por lo tanto,CMake
la construcción puede ser órdenes de magnitud más rápida. -
la gramática de
CMake
es mucho más fácil admitir herramientas externas que make’s. -
Una vez
make
construye un artefacto, olvida cómo fue construido. ¿De qué fuentes se construyó, qué indicadores del compilador?CMake
lo rastrea,make
te lo deja a ti. Si se eliminó una de las fuentes de la biblioteca desde la versión anterior deMakefile
,make
no lo reconstruirá. -
Moderno
CMake
(a partir de la versión 3.algo) funciona en términos de dependencias entre “objetivos”. Un objetivo sigue siendo un único archivo de salida, pero puede tener dependencias transitivas (“públicas”/”interfaz” en términos de CMake). Estas dependencias transitivas se pueden exponer u ocultar de los paquetes dependientes.CMake
administrará los directorios por usted. Conmake
está atascado en un nivel de archivo por archivo y administración de directorios a mano.
Podrías codificar algo en make
usando archivos intermedios para cubrir los dos últimos espacios, pero estás solo. make
contiene un Idioma completo de Turing (incluso dos, a veces tres contando Engaño); los dos primeros son horribles y el Guile practicamente nunca se usa.
Para ser honesto, esto es lo que CMake
y make
tienen en común: sus idiomas son bastante horribles. Esto es lo que me viene a la mente:
- No tienen tipos definidos por el usuario;
CMake
tiene tres tipos de datos: cadena, lista y un destino con propiedades.make
tiene uno: cadena;- normalmente pasa argumentos a funciones configurando variables globales.
- Esto se trata parcialmente en CMake moderno: puede establecer las propiedades de un objetivo:
set_property(TARGET helloworld APPEND PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}")
;
- Esto se trata parcialmente en CMake moderno: puede establecer las propiedades de un objetivo:
- la referencia a una variable indefinida se ignora silenciosamente de forma predeterminada;
-
Aquí hay buena información, pero un comentario es completamente incorrecto: cmake tiene un tipo LIST ya que con las funciones LIST adecuadas, lo cual es crucial para muchas tareas del sistema de compilación, hay una pequeña diferencia: cmake.org/cmake/help/git-master/command/list.html
– resolviendoJ
18 de febrero de 2020 a las 4:01
-
@VictorSergienko, no se preguntó en la pregunta del OP, pero estaba esperando el chiste … ¿Qué usas que sientes que es mejor que cualquiera?
– Robert Lugg
23 de diciembre de 2020 a las 21:42
-
Uso make por razones históricas, y lo odio. CMake no está exento de problemas también (intenta compilar de forma cruzada con él), pero para mis propios proyectos, CMake ganaría porque escribes menos código y es compatible con herramientas.
– Víctor Sergio
24 de diciembre de 2020 a las 1:57
-
y enterremos automake y autoconf para siempre por favor
– pm100
1 abr a las 0:20