Razumevanje CMakeLists

Kako se spoprijeti z delovanjem datotek CMakeLists.txt

CMake

V naši uvodni vaji smo uporabili CMake](https://cmake.org/) kot sistem gradnje za našo aplikacijo, vendar smo bili le resnično pozorni na eno od naših datotek CMakeLists.txt. Tukaj bomo podrobneje preučili, kako to deluje.

CMake je uporaben, ker nam omogoča avtomatizacijo veliko stvari, ki jih je treba storiti pred prevajanjem.

Korenska CMakeLists.txt

Morda se spomnite datoteke CMakeLists.txt iz prve vaje:

 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)

Prva vrstica, cmake_minimum_required(), nastavi različico CMake, ki jo bomo klicali.

Nato project(kirigami-tutorial) definira ime projekta.

Nato pridemo do razdelka, kjer vključimo številne potrebne nastavitve CMake in KDE z uporabo extra-cmake-modules. Zagotavljajo niz uporabnih pripomočkov:

  • KDEInstallDirs nudi priročne spremenljivke, kot so ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}, ${KDE_INSTALL_QMLDIR}, ${KDE_INSTALL_BINDIR} in ${KDE_INSTALL_LIBDIR}.
  • KDECMakeSettings ponuja stvari, kot je CMAKE_AUTORCC ON, uninstall cilja, ki se lahko uporablja z cmake --build build/ - -target uninstall in ENABLE_CLAZY.
  • KDECompilerSettings zagotavlja minimalni standard C++, zastavice prevajalnika, kot je -pedantic, in makre najboljših praks, kot je -DQT_NO_CAST_FROM_ASCII, ki zahtevajo eksplicitne pretvorbe, kot je QStringLiteral().
  • ECMFindQmlModule ponuja način zagotavljanja, da se med odvisnosti med izvajanjem QML najde že med prevajanjem.
  • ECMQmlModule ponuja ukaze CMake, kot sta ecm_add_qml_module() in ecm_target_qml_sources().

Naslednji razdelek je pomemben, ker določa, katere odvisnosti bomo vnesli med prevajanjem. Poglejmo prvega:

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() najde in naloži zunanjo knjižnico in njene komponente.
  • REQUIRED sporoča CMake, naj konča z napako, če paketa ni mogoče najti.
  • COMPONENTS je parameter, ki je pred posebnimi sestavnimi deli ogrodja, ki ga bomo vključili.
  • Vsaka beseda za COMPONENTS se nanaša na določeno komponento knjižnice.

Namestitvena vrstica naroči CMakeu, naj namesti namizno datoteko v ${KDE_INSTALL_APPDIR}, kar se v Linuxu prevede v $XDG_DATA_DIRS/applications, običajno /usr/share/applications, v sistemu Windows pa v C:/Program Datoteke/${PROJECT_NAME}/bin/data/applications`:

32
add_subdirectory(src)

Zadnja vrstica omogoča CMake-u, da natisne, katere pakete je našel, in takoj povzroči neuspeh prevajanja, če naleti na napako:

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

In nad tem add_subdirectory(src) usmeri CMake v imenik src/, kjer najde drugo datoteko CMakeLists.txt.

src/CMakeLists.txt

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

Medtem ko je prva datoteka obravnavala metapodatke in iskanje knjižnic, bo ta zajemala obdelavo odvisnosti in namestitev aplikacije. Ima naslednje klice CMake:

  • add_executable() ustvari izvršljivo tarčo, ki jo bomo uporabili za izvajanje našega projekta.
  • ecm_add_qml_module() ustvari cilj modula QML, ki bo dostopen prek uvoza "org.kde.tutorial".
  • target_sources() doda izvorne datoteke C++ izvršljivemu cilju.
  • ecm_target_qml_sources() doda datoteke QML v modul.
  • target_link_libraries() povezuje knjižnice C++, uporabljene v naši kodi, z našo izvršljivo datoteko. Kirigami tukaj ni vključen, ker uporabljamo samo njegov modul QML.
  • install() namesti izvršljivo datoteko v sistem.

Dokumentacijo za oba ukaza ECM lahko najdete v API-ju extra-cmake-modules za ECMQmlModule.

Klic ecm_add_qml_module() je bil tukaj uporabljen za spreminjanje tradicionalnega izvršljivega cilja izvorne kode C++ in ga spremeni v nekaj, kar lahko sprejme datoteke QML in izvorno kodo C++, ki je dostopna iz QML v tako imenovanem uporaba izvršljive datoteke kot podpornega cilja za modul QML. To pomeni, da se datoteke QML izvajajo neposredno kot del aplikacije, kar pogosto velja za aplikacije.

Ustvarite lahko tudi ločen modul QML, ki ne uporablja izvršljive datoteke kot podpornega cilja z uporabo ecm_add_qml_module(). V tem primeru bi ustvarili ciljno knjižnico z uporabo add_library(), jo povezali z obstoječim izvršljivim ciljem z uporabo target_link_libraries( ) in poleg namestitve knjižnice z install() boste morali dokončati modul QML z ecm_finalize_qml_module(), tako da ustvari lahko dve datoteki: qmldir in qmltypes. Te datoteke uporabljajo aplikacije QtQuick za iskanje ločenih modulov QML.

Metoda za ustvarjanje ločenega modula QML je bolje prikazana v Uporaba ločenih datotek.

To so dodatki, ki jih zagotavljajo extra-cmake-modules za lažjo uporabo deklarativne registracije Qt (zamenjavo za Datoteke virov Qt).

Dokumentacijo za vse tri ukaze lahko najdete v API-ju extra-cmake-modules za ECMQmlModule.

src/components/CMakeLists.txt

V učbeniku o kako svojo kodo razdeliti na ločene datoteke je bila uvedena nova datoteka CMake, ki omogoča ločene module 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
    AddEditDialog.qml
    KountdownDelegate.qml
)

ecm_finalize_qml_module(kirigami-hello-components)

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

Zahteva, da CMake prebere to datoteko, je dodajanje klica add_subdirectory() v src/CMakeLists.txt, ki kaže nanjo.

Ustvarimo nov cilj z imenom kirigami-hello-components in ga nato spremenimo v modul QML z uporabo ecm_add_qml_module() pod uvoženiim imenom org.kde.tutorial.components in dodajte ustrezne datoteke QML.

Klic add_library() ustvari nov cilj, imenovan kirigami-hello-components. Ta cilj bo imel lasten nabor datotek izvorne kode, datotek QML, povezal lastne knjižnice in tako naprej, vendar mora biti povezan z izvedljivo datoteko, ko pa je preveden, mora biti povezan z izvedljivo datoteko, ustvarjeno v src/CMakeLists.txt. To storite tako, da ciljno ime dodate na seznam knjižnic, ki bodo povezane z izvršljivo datoteko v target_link_libraries().

Klic ecm_add_qml_module() spremeni knjižnico, da ji omogoči sprejemanje datotek QML kot prej, toda tokrat moramo uporabiti GENERATE_PLUGIN_SOURCE . Ko se izvršljiva datoteka uporablja kot podporni cilj (kot pri kirigami-hello), ji ni treba generirati kode vtičnika, saj je vgrajena v izvršljivo datoteko; z ločenimi moduli QML, kot je kirigami-hello-components, je potrebna koda vtičnika.

Upstream Qt qt_add_qml_module() privzeto ustvari vtičnik skupaj z modulom QML , vendar KDE-jev ecm_add_qml_module() privzeto ne omogoča združljivosti za nazaj.

Druga stvar, ki je potrebna za ločene module QML, je dokončanje cilja. To predvsem pomeni, da CMake ustvari dve datoteki, qmldir in qmltypes, ki opisujeta module QML, ki jih imamo, in izvozi njihove simbole za uporabo v knjižnici. Pomembni so pri namestitvi vaše aplikacije, tako da lahko izvršljiva datoteka, ki se izvaja, najde, kje so datoteke QML za vsak modul, tako da so samodejno dodane v cilj.

Nato lahko preprosto namestite cilj kot prej.

Ko boste naslednjič morali dodati več datotek QML, jih ne pozabite vključiti v to datoteko. Datoteke C++, ki uporabljajo ključno besedo QML_ELEMENT, ki jo bomo videli veliko kasneje v učbeniku, lahko dodate tudi tukaj z uporabo target_sources( ). Svojo kodo lahko logično ločite tako, da po potrebi ustvarite več modulov QML z različnimi uvozi.

Ta nastavitev bo uporabna pri razvoju večine programov oz. aplikacij Kirigami.