Uso de CMake para construir aplicaciones en Linux
CMake es un sistema de construcción automatizado multiplataforma que utiliza un archivo denominado CMakeLists.txt para describir el proceso de compilación. Permite generar archivos de construcción estándar, como Makefiles para Unix o proyectos de Visual C++ para Windows. El archivo CMakeLists.txt se puede crear manualmente o mediante scripts. CMake ofrece una sintaxis más concisa que autoconfig.
El flujo de trabajo en Linux para generar y compilar con CMaker es el siguiente:
- Crear el archivo CMakeLists.txt.
- Ejecutar el comando
cmake RUTAoccmake RUTApara generar el Makefile, donde RUTA es el directorio que contiene el CMakeLists.txt. - Utilizar el comando
makepara iniciar la compilación.
Ejemplo básico de proyecto
Consideremos un proyecto con un único archivo fuente denominado app.cpp:
int main() { std::cout << "¡Hola desde CMake!" << std::endl; return 0; }
</figure>Para configurar este proyecto, creamos un CMakeLists.txt en el mismo directorio:
<figure><figcaption>Configruación inicial del CMakeLists.txt</figcaption>```
cmake_minimum_required(VERSION 3.10)
project(ProyectoDemo)
set(FUENTES app.cpp)
add_executable(aplicacion ${FUENTES})
cmake_minimum_requiredestablece la versión mínima requerida.projectdefine el nombre del proyecto.setasigna el archivo fuente a la variable FUENTES.add_executablecrea un ejecutable llamado "aplicacion" a partir de los fuentes listados.
Después de crear el CMakeLists.txt, ejecutamos CMake en el directorio del proyecto para generar el Makefile:
$ make [ 50%] Building CXX object CMakeFiles/aplicacion.dir/app.cpp.o [100%] Linking CXX executable aplicacion [100%] Built target aplicacion
</figure>### Configuraciones adicionales
Para activar soporte de C++17, se puede añadir al CMakeLists.txt:
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON)
Para enlazar con bibliotecas externas como pthread:
target_link_libraries(aplicacion pthread)
Establecer la ruta de salida de los ejecutables:
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
Indicar directorios adicionales para búsqueda de bibliotecas:
link_directories(/ruta/a/bibliotecas)
### Variables predefinidas en CMake
- `PROJECT_NAME`: Nombre del proyecto definido con project()
- `CMAKE_SOURCE_DIR`: Directorio raíz del proyecto
- `CMAKE_BINARY_DIR`: Directorio donde se ejecutó cmake
- `CMAKE_CURRENT_SOURCE_DIR`: Directorio del CMakeLists.txt actual
- `CMAKE_RUNTIME_OUTPUT_DIRECTORY`: Ruta de salida para ejecutables
- `CMAKE_LIBRARY_OUTPUT_DIRECTORY`: Ruta de salida para bibliotecas compartidas
- `BUILD_SHARED_LIBS`: Tipo de biblioteca por defecto (shared/static)
- `CMAKE_CXX_FLAGS`: Opciones de compilación para C++
- `CMAKE_BUILD_TYPE`: Tipo de construcción (Debug/Release)
### Gestión de dependencias
El comando `add_dependencies` permite establecer dependencias entre objetivos:
add_dependencies(objetivo_principal dependencia1 dependencia2)
Para localizar bibliotecas del sistema:
find_library(RUTA_BIBLIOTECA yaml-cpp) if(RUTA_BIBLIOTECA) target_link_libraries(aplicacion ${RUTA_BIBLIOTECA}) endif()
El comando `find_package` proporciona una interfaz de alto nivel para encontrar paquetes de software con archivos CMake de configuración:
find_package(Boost REQUIRED COMPONENTS filesystem) if(Boost_FOUND) target_include_directories(aplicacion PRIVATE ${Boost_INCLUDE_DIRS}) target_link_libraries(aplicacion ${Boost_LIBRARIES}) endif()