Entendiendo CMakeLists

Familiarizarse con el funcionamiento de los archivos CMakeLists.txt

CMake

En nuestro tutorial de introducción hemos usado CMake como sistema de compilación para nuestra aplicación, aunque solo hemos prestado más atención a uno de nuestros archivos CMakeLists.txt. Aquí vamos a profundizar un poco más sobre cómo funciona.

CMake es útil porque nos permite automatizar la mayoría de las cosas necesarias que hay que hacer antes de compilar.

CMakeLists.txt

Es posible que recuerde este archivo CMakeLists.txt del primer tutorial:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
cmake_minimum_required(VERSION 3.16)
project(helloworld)

find_package(ECM REQUIRED NO_MODULE)
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH})

include(KDEInstallDirs)
include(KDECMakeSettings)
include(KDECompilerSettings NO_POLICY_SCOPE)

find_package(Qt${QT_MAJOR_VERSION} REQUIRED NO_MODULE COMPONENTS
    Core
    Quick
    Test
    Gui
    QuickControls2
    Widgets
)

find_package(KF${QT_MAJOR_VERSION} REQUIRED COMPONENTS
    Kirigami2
    I18n
    CoreAddons
)

add_subdirectory(src)

feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES)

La primera línea, cmake_minimum_required(VERSION 3.16) define la versión de CMake que se va a utilizar.

A continuación, project(helloworld) define el nombre del proyecto.

Luego llegamos a una sección donde incluimos una serie de preferencias necesarias de CMake y de KDE usando extra-cmake-modules. No debe preocuparse demasiado de estas líneas por ahora y tampoco necesitaremos cambiarlas en este tutorial.

La siguiente sección es importante, ya que especifica las dependencias necesarias durante la compilación. Veamos la primera:

11
12
13
14
15
16
17
18
find_package(Qt${QT_MAJOR_VERSION} REQUIRED NO_MODULE COMPONENTS
    Core
    Quick
    Test
    Gui
    QuickControls2
    Widgets
)
  • find_package() encuentra y carga el componente externo.
  • La primera palabra es la infraestructura, Qt. ${QT_MAJOR_VERSION} es una variable de conveniencia proporcionada por extra-make-modules que nos permite escoger la versión de Qt que vamos a usar, 5 o 6, dependiendo de si usamos el indicador -DBUILD_WITH_QT6=ON de CMake.
  • REQUIRED indica a CMake que estas dependencias son necesarias y que debe terminar con un error si no se puede encontrar dicho paquete.
  • NO_MODULE cambia CMake al modo Config. No tenemos que preocuparnos por esto en este momento.
  • COMPONENTS es un parámetro que precede a los componentes específicos de la infraestructura que vamos a incluir.
  • Cada palabra tras COMPONENTS hace referencia a un determinado componente.

La última línea hace que CMake liste los paquetes que ha encontrado. Y sobre esta, add_subdirectory(src) hace que CMake se dirija al directorio src/, donde encontrará otro archivo CMakeLists.txt:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
add_executable(helloworld)

target_sources(helloworld PRIVATE
    main.cpp
    resources.qrc
)

target_link_libraries(helloworld
    Qt${QT_MAJOR_VERSION}::Quick
    Qt${QT_MAJOR_VERSION}::Qml
    Qt${QT_MAJOR_VERSION}::Gui
    Qt${QT_MAJOR_VERSION}::QuickControls2
    Qt${QT_MAJOR_VERSION}::Widgets
    KF${QT_MAJOR_VERSION}::I18n
)

install(TARGETS helloworld ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})

Como la mayor parte del trabajo pesado se realiza en el primer archivo, este es mucho más breve.

  • add_executable() se encarga de generar nuestro ejecutable.
  • target_sources() nos permite añadir los archivos que se usarán en nuestro nuevo ejecutable.
  • target_link_libraries enlaza de forma dinámica las bibliotecas usadas en el código fuente con nuestro ejecutable. Kirigami no está incluido aquí porque estamos usando solo su módulo QML.
  • install() sitúa nuestro ejecutable en el lugar correcto usando ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}, una variable de conveniencia proporcionada por KDEInstallDirs en extra-cmake-modules que instala ejecutables y bibliotecas en sus lugares correctos sin necesidad de indicar su ruta absoluta, de forma similar a GNUInstallDirs.

Esta configuración será útil para desarrollar la mayoría de las aplicaciones de Kirigami.