Saltar al contenido

Diferencia entre usar Makefile y CMake para compilar el código

Sé libre de divulgar nuestro sitio y códigos en tus redes sociales, ayúdanos a ampliar esta comunidad.

Solución:

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 integrado), o simplemente desea usar un IDE?

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 en ninja o make o muchos otros generadores, y luego lo haces funcionar. Todas las piezas de script de shell que normalmente se apilan en Makefile 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 de Makefile, 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. Con makeestá 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 lenguaje completo de Turing (incluso dos, a veces tres contando Guile); 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: stringlista y un destino con propiedades. make Tiene uno: string;
  • 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");
  • la referencia a una variable indefinida se ignora silenciosamente de forma predeterminada;

Reseñas y puntuaciones del post

Eres capaz de añadir valor a nuestra información asistiendo con tu experiencia en las reseñas.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *