CMake por Ejemplo

Mirko Kiefer
22 de Febrero, 2017 · 4 min de lectura

Cuando tratando de aprender CMake no podía encontrar una buena introducción. La documentación de CMake es bastante completa, pero no es adecuada para un principiante. Hay algunos tutoriales útiles enlazados en el Wiki de CMake, pero la mayoría de ellos solo cubren problemas muy específicos o son demasiado básicos. Así que escribí esta breve introducción de CMake como una versión destilada de lo que descubrí después de trabajar en los documentos y seguir las preguntas de stackoverflow.

Es un trabajo en progreso y trataré de mejorarlo continuamente.

CMake es una meta de construir la herramienta que le permite generar nativo de generar secuencias de comandos para una variedad de plataformas:

  • Unix Makefiles
  • Xcode
  • Visual Studio
  • CodeBlocks
  • Eclipse
  • más…

Ver la lista completa de CMake generadores.

Asumamos que tenemos una aplicación simple con una sola .archivo c.

Creamos un archivoCMakeLists.txt en la raíz de nuestro proyecto.

cmake_minimum_required(VERSION 2.8)project(app_project)add_executable(myapp main.c)install(TARGETS myapp DESTINATION bin)

Eso es todo lo que necesitamos para poder construir nuestra aplicación con cualquiera de los generadores disponibles.

add_executable define nuestro binario con todos los archivos fuente vinculados.

install le dice a cmake que instale nuestro binario en el directorio bin del directorio de instalación.

Building

CMake admite compilaciones fuera de código, por lo que todo nuestro código compilado va a un directorio separado de los orígenes.

Para iniciar una compilación creamos una nueva carpeta:

mkdir _build
cd _build

Y llamamos a cmake con la ruta a la raíz del proyecto (en este caso la carpeta principal):

cmake ..

Esto generará scripts de compilación utilizando el generador predeterminado — en Linux / OSX esto debería ser Makefiles.

Por defecto, cmake instalará nuestra compilación en los directorios del sistema.
Para definir un directorio de instalación personalizado, simplemente lo pasamos a cmake:

cmake .. -DCMAKE_INSTALL_PREFIX=../_install

Para ejecutar el script de compilación, simplemente puede usar el Makefile:

make
make install

Ahora podemos ejecutar nuestro binario desde el directorio de instalación:

../_install/bin/myapp

Si queremos usar un generador diferente lo pasamos a cmake utilizando el parámetro -G:

cmake .. -GXcode

Esto generará un proyecto Xcode fácilmente configurado para construir nuestra aplicación.

Usando CMake con bibliotecas

Para construir una biblioteca usamos un script similar:

cmake_minimum_required(VERSION 2.8)project(libtest_project)add_library(test STATIC test.c)install(TARGETS test DESTINATION lib)
install(FILES test.h DESTINATION include)

CMake construirá la biblioteca como libtest.a e instalará la biblioteca en la carpeta lib del directorio de instalación.También incluimos nuestro archivo de encabezado público en el paso de instalación y le decimos a cmake que lo coloque en include.

En lugar de una biblioteca estática, también podemos construir una biblioteca compartida:

add_library(test SHARED test.c)

Vincular bibliotecas a ejecutables con CMake

Podemos extender nuestro ejecutable desde arriba vinculándolo a nuestro libray libtest.a.

Comencemos agregando el directorio de la biblioteca como un subdirectorio a nuestro proyecto myapp.

Ahora, podemos usar la biblioteca definida en CMakeLists.txt de libtest_project en las listas de Cmakel de myapp.txt:

cmake_minimum_required(VERSION 2.8)project(myapp)add_subdirectory(libtest_project)add_executable(myapp main.c)target_link_libraries(myapp test)install(TARGETS myapp DESTINATION bin)
add_subdirectory hace que la biblioteca test definido en libtestproject disponible para la construcción.
En target_link_libraries le decimos a CMake que lo vincule a nuestro ejecutable. CMake se asegurará de realizar primero la prueba de compilación antes de vincularla a myapp.

Incluyendo bibliotecas externas que usan otros sistemas de compilación

Mientras que CMake disfruta de un interés creciente, todavía hay muchas bibliotecas que usan sistemas de compilación nativos como los Makefiles de Unix. Puede hacer uso de ellos en su proyecto CMake sin tener que reescribir sus scripts de compilación.

Todo lo que necesitamos es el soporte de CMake para proyectos externos y bibliotecas importadas:

ExternalProject_Add(project_luajit
URL http://luajit.org/download/LuaJIT-2.0.1.tar.gz
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/luajit-2.0.1
CONFIGURE_COMMAND ""
BUILD_COMMAND make
INSTALL_COMMAND make install
PREFIX=${CMAKE_CURRENT_BINARY_DIR}/luajit-2.0.1
)ExternalProject_Get_Property(project_luajit install_dir)add_library(luajit STATIC IMPORTED)set_property(TARGET luajit PROPERTY IMPORTED_LOCATION ${install_dir}/lib/libluajit-5.1.a)add_dependencies(luajit project_luajit)add_executable(myapp main.c)include_directories(${install_dir}/include/luajit-2.0)target_link_libraries(myapp luajit)

ExternalProject_Add nos permite agregar un proyecto externo como destino a nuestro proyecto. Si no especifica los comandos como BUILD_COMMAND o INSTALL_COMMAND, CMake busca un CMakeLists.txt externa en el proyecto y ejecutarlo.
En nuestro caso queremos hacer uso de la biblioteca luajit que está construida usando un Makefile.

add_library también admite la importación de bibliotecas ya construidas, solo tenemos que establecer su propiedad IMPORTED_LOCATION.
Calling ExternalProject_Add solo especifica el proyecto externo como destino, pero no lo compila automáticamente. Solo se construirá si le agregamos una dependencia. Por lo tanto, llamamos a add_dependencies para hacer que nuestra biblioteca importada dependa del proyecto externo.

Finalmente podemos enlazar nuestra biblioteca importada como una biblioteca «normal»con target_link_libraries.

Deja una respuesta

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