Compreender o CMakeLists

Tentar compreender como funcionam os ficheiros CMakeLists.txt

CMake

No nosso tutorial introdutório, usámos o CMake como sistema de compilação para a nossa aplicação, mas só prestámos atenção a um dos nossos ficheiros CMakeLists.txt. Aqui, vamos ver como funcionam os CMakeLists com um pouco mais de detalhe.

O CMake é útil porque nos permite automatizar muitas das coisas que precisam de ser feitas antes da compilação.

CMakeLists.txt

Poderá recordar este ficheiro CMakeLists.txt do primeiro 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)

The first line, cmake_minimum_required(VERSION 3.16) sets the version of CMake we will be calling.

After that, project(helloworld) defines the name of the project.

Depois chegamos a um secção onde incluímos um conjunto de definições necessárias do CMake e KDE, usando o extra-cmake-modules. Não se deverá preocupar demasiado com estas linhas por agora e não será necessário alterá-las neste tutorial.

The following section is important, because it specifies which dependencies we'll be bringing in at compile time. Let's look at the first:

11
12
13
14
15
16
17
18
find_package(Qt${QT_MAJOR_VERSION} REQUIRED NO_MODULE COMPONENTS
    Core
    Quick
    Test
    Gui
    QuickControls2
    Widgets
)
  • O find_package() procura e carrega o componente externo.
  • The first word is the framework, Qt. ${QT_MAJOR_VERSION} is a convenience variable provided by extra-cmake-modules that lets us choose the Qt version to be used, 5 or 6, depending on whether we use the CMake flag -DBUILD_WITH_QT6=ON.
  • REQUIRED tells CMake that these dependencies are indeed required and that it shall exit with an error if the package can not be found.
  • NO_MODULE switches CMake into the Config mode. We don't need to worry about that at the moment.
  • O COMPONENTS é um parâmetro que antecede os componentes específicos da plataforma que iremos incluir.
  • Cada palavra a seguir ao COMPONENTS refere-se a um componente específico.

The final line lets CMake print out which packages it has found. And above that, add_subdirectory(src) points CMake into the src/ directory, where it finds another CMakeLists.txt file:

 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})

Dado que a maior parte do trabalho pesado é feito pelo primeiro ficheiro, este é bastante mais pequeno.

  • add_executable() takes care of generating our executable.
  • target_sources() lets us add files that will be used by our new executable.
  • target_link_libraries() dynamically links the libraries used in our code to our executable. Kirigami is not included here because we are using only its QML module.
  • install() puts our executable in its right place by using ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}, a convenience variable provided by KDEInstallDirs in extra-cmake-modules that installs executables and libraries in their right place for you without needing to specify the absolute path, similarly to GNUInstallDirs.

Esta configuração será útil quando estiver a desenvolver a maioria das aplicações de Kirigami.