Skip to main content
Skip to content

Pochopenie CMakeLists

Prekrývajúce listy

CMake

V našom úvodnom tutoriáli sme použili CMake ako zostavovací systém pre našu aplikáciu, ale skutočne sme venovali pozornosť iba jednému z našich súborov CMakeLists.txt. Tu si podrobnejšie prejdeme, ako funguje.

CMake je užitočný, pretože nám umožňuje automatizovať väčšinu vecí, ktoré sa musia urobiť pred kompiláciou.

CMakeLists

Možno si pamätáte tento súbor CMakeLists.txt z prvého tutoriálu:

 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
29
30
31
32
33
34
35
36
cmake_minimum_required(VERSION 3.20)
project(kirigami-tutorial)

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

include(KDEInstallDirs)
include(KDECMakeSettings)
include(KDECompilerSettings NO_POLICY_SCOPE)
include(ECMFindQmlModule)
include(ECMQmlModule)

find_package(Qt6 REQUIRED COMPONENTS
    Core
    Quick
    Test
    Gui
    QuickControls2
    Widgets
)

find_package(KF6 REQUIRED COMPONENTS
    Kirigami
    I18n
    CoreAddons
    QQC2DesktopStyle
    IconThemes
)

ecm_find_qmlmodule(org.kde.kirigami REQUIRED)

add_subdirectory(src)

install(PROGRAMS org.kde.tutorial.desktop DESTINATION ${KDE_INSTALL_APPDIR})

feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES)

Prvý riadok cmake_minimum_required() nastavuje verziu CMake, ktorú budeme volať.

Potom project(kirigami-tutorial) definuje názov projektu.

Potom sa dostaneme k sekcii, kde zahrnieme niekoľko nevyhnutných nastavení CMake a KDE pomocou extra-cmake-modules. Poskytujú sadu užitočných nástrojov:

  • KDEInstallDirs poskytuje praktické premenné ako ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}, ${KDE_INSTALL_QMLDIR}, ${KDE_INSTALL_BINDIR} a ${KDE_INSTALL_LIBDIR}.
  • KDECMakeSettings poskytuje veci ako CMAKE_AUTORCC ON, cieľ uninstall, ktorý sa dá použiť s cmake --build build/ --target uninstall, a ENABLE_CLAZY.
  • KDECompilerSettings poskytuje minimálny štandard C++, príznaky kompilátora ako -pedantic a makrá osvedčených postupov ako -DQT_NO_CAST_FROM_ASCII vyžadujúce explicitné konverzie ako QStringLiteral().
  • ECMFindQmlModule poskytuje spôsob, ako zabezpečiť, že runtime závislosť QML sa nájde v čase kompilácie.
  • ECMQmlModule poskytuje príkazy CMake ako ecm_add_qml_module() a ecm_target_qml_sources().

Nasledujúca sekcia je dôležitá, pretože určuje, aké závislosti privedieme v čase kompilácie. Pozrime sa na prvú:

13
14
15
16
17
18
19
20
21
22
23
24
25
26
find_package(Qt6 REQUIRED COMPONENTS
    Core
    Quick
    Test
    Gui
    QuickControls2
    Widgets
)

find_package(KF6 REQUIRED COMPONENTS
    Kirigami
    I18n
    CoreAddons
    QQC2DesktopStyle
  • find_package() nájde a načíta externú knižnicu a jej komponenty.
  • REQUIRED povie CMake, aby skončil s chybou, ak balík nemožno nájsť.
  • COMPONENTS je parameter, ktorý predchádza konkrétnym komponentom frameworku, ktoré zahrnieme.
  • Každé slovo za COMPONENTS odkazuje na konkrétny komponent knižnice.

Riadok install inštruuje CMake na inštaláciu súboru desktop do ${KDE_INSTALL_APPDIR}, čo sa na Linuxe prekladá na $XDG_DATA_DIRS/applications, zvyčajne /usr/share/applications, a na Windows sa prekladá na C:/Program Files/${PROJECT_NAME}/bin/data/applications:

34
install(PROGRAMS org.kde.tutorial.desktop DESTINATION ${KDE_INSTALL_APPDIR})

Posledný riadok umožňuje CMake vypísať, aké balíky našiel, a spôsobí okamžité zlyhanie kompilácie, ak narazí na chybu:

36
feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES)

A nad tým add_subdirectory(src) nasmeruje CMake do priečinka src/, kde nájde ďalší súbor CMakeLists.txt.

CMakeLists

 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
29
30
add_executable(kirigami-hello)

ecm_add_qml_module(kirigami-hello
    URI
    org.kde.tutorial
)

target_sources(kirigami-hello
    PRIVATE
    main.cpp
)

ecm_target_qml_sources(kirigami-hello
    SOURCES
    Main.qml
)

target_link_libraries(kirigami-hello
    PRIVATE
    Qt6::Quick
    Qt6::Qml
    Qt6::Gui
    Qt6::QuickControls2
    Qt6::Widgets
    KF6::I18n
    KF6::CoreAddons
    KF6::IconThemes
)

install(TARGETS kirigami-hello ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})

Zatiaľ čo prvý súbor spracovával metadáta a hľadanie knižníc, tento bude pozostávať zo spracovania závislostí a inštalácie aplikácie. Obsahuje nasledujúce volania CMake:

  • add_executable() vytvára spustiteľný cieľ, ktorý použijeme na spustenie nášho projektu.
  • ecm_add_qml_module() vytvára cieľ modulu QML, ktorý bude dostupný prostredníctvom importu "org.kde.tutorial".
  • target_sources() pridáva zdrojové súbory C++ do spustiteľného cieľa.
  • ecm_target_qml_sources() pridáva súbory QML do modulu.
  • target_link_libraries() prepája knižnice C++ používané v našom kóde s naším spustiteľným súborom. Kirigami tu nie je zahrnuté, pretože používame iba jeho modul QML.
  • install() nainštaluje spustiteľný súbor do systému.

Dokumentácia pre tieto dva príkazy ECM sa nachádza v API extra-cmake-modules pre ECMQmlModule.

Volanie ecm_add_qml_module() sa tu použilo na modifikáciu tradičného spustiteľného cieľa zdrojového kódu C++ a jeho premenu na niečo, čo môže prijať súbory QML a zdrojový kód C++ prístupný z QML v tom, čo sa nazýva použitie spustiteľného súboru ako podporného cieľa pre modul QML. To znamená, že súbory QML sa spúšťajú priamo ako súčasť aplikácie, čo je často prípad aplikácií.

Môžete tiež vytvoriť samostatný modul QML, ktorý nepoužíva spustiteľný súbor ako podporný cieľ pomocou ecm_add_qml_module(). V tomto prípade by ste vytvorili cieľ knižnice pomocou add_library(), prepojili ho s existujúcim spustiteľným cieľom pomocou target_link_libraries() a okrem inštalácie knižnice pomocou install() budete musieť finalizovať modul QML pomocou ecm_finalize_qml_module(), aby mohol vygenerovať dva súbory: qmldir a qmltypes. Tieto súbory používajú aplikácie QtQuick na nájdenie samostatných modulov QML.

Metóda na vytvorenie samostatného modulu QML je lepšie znázornená v Používanie samostatných súborov.

Toto sú doplnky poskytované extra-cmake-modules na uľahčenie používania deklaratívnej registrácie Qt (náhrada za súbory zdrojov Qt).

Dokumentácia pre všetky tri príkazy sa nachádza v API extra-cmake-modules pre ECMQmlModule.

CMakeLists

V tutoriáli o rozdelení kódu do samostatných súborov bol predstavený nový súbor CMake umožňujúci samostatné moduly QML:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
add_library(kirigami-hello-components)

ecm_add_qml_module(kirigami-hello-components
    URI "org.kde.tutorial.components"
    GENERATE_PLUGIN_SOURCE
)

ecm_target_qml_sources(kirigami-hello-components
    SOURCES
    AddDialog.qml
    KountdownDelegate.qml
)

ecm_finalize_qml_module(kirigami-hello-components)

install(TARGETS kirigami-hello-components ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})

Požiadavkou na to, aby CMake čítal tento súbor, je pridanie volania add_subdirectory() v src/CMakeLists.txt smerujúceho naň.

Vytvoríme nový cieľ s názvom kirigami-hello-components a potom ho premeníme na modul QML pomocou ecm_add_qml_module() pod importným názvom org.kde.tutorial.components a pridáme príslušné súbory QML.

Volanie add_library() generuje nový cieľ s názvom kirigami-hello-components. Tento cieľ bude mať vlastnú sadu zdrojových kódových súborov, súborov QML, prepojí vlastné knižnice atď., ale po skompilovaní musí byť prepojený so spustiteľným súborom vytvoreným v src/CMakeLists.txt. To sa robí pridaním názvu cieľa do zoznamu knižníc, ktoré budú prepojené so spustiteľným súborom v target_link_libraries().

Volanie ecm_add_qml_module() zmení knižnicu tak, aby mohla prijímať súbory QML ako predtým, ale tentoraz musíme použiť GENERATE_PLUGIN_SOURCE. Keď sa spustiteľný súbor používa ako podporný cieľ (ako pri kirigami-hello), nepotrebuje generovať kód pluginu, pretože je zabudovaný do spustiteľného súboru; pri samostatných moduloch QML ako kirigami-hello-components je kód pluginu nevyhnutný.

Upstream qt_add_qml_module() od Qt štandardne generuje plugin spolu s modulom QML, ale ecm_add_qml_module() od KDE tak štandardne nerobí kvôli spätnej kompatibilite.

Ďalšia vec, ktorá je nevyhnutná pre samostatné moduly QML, je finalizácia cieľa. To hlavne znamená, že CMake generuje dva súbory, qmldir a qmltypes, ktoré popisujú moduly QML a exportujú ich symboly na použitie v knižnici. Sú dôležité pri inštalácii vašej aplikácie, aby spustený spustiteľný súbor dokázal nájsť, kde sú súbory QML pre každý modul, preto sú automaticky pridané k cieľu.

Potom môžete jednoducho nainštalovať cieľ ako predtým.

Nabudúce, keď budete potrebovať pridať ďalšie súbory QML, nezabudnite ich zahrnúť do tohto súboru. Súbory C++, ktoré používajú kľúčové slovo QML_ELEMENT, ktoré uvidíme oveľa neskôr v tutoriáli, sa tu tiež dajú pridať pomocou target_sources(). Svoj kód môžete logicky oddeliť vytvorením ďalších modulov QML s rôznymi importmi podľa potreby.

Toto nastavenie bude užitočné pri vývoji väčšiny aplikácií Kirigami.