CMakeLists begrijpen
CMake
In ons inleidende handboek gebruiken we CMake als het bouwsysteem voor onze toepassing, maar we hebben slechts alleen wat meer aandacht besteed aan een van onze bestanden CMakeLists.txt
. Hier gaan we het in meer detail hebben over dit werkt.
CMake is nuttig omdat het ons is staat stelt om veel van de zaken die gedaan moeten worden alvorens te compileren te automatiseren.
De basis CMakeLists.txt
Misschien herinnert u zich dit bestand CMakeLists.txt
uit de eerste handleiding:
|
|
De eerste regel, cmake_minimum_required()
stelt de versie van CMake in die we willen aanroepen.
Daarna, definieert project(kirigami-tutorial)
de naam van het project.
Daarna krijgen we een sectie waar we een aantal noodzakelijke CMake en KDE-instellingen invoegen met gebruik van extra-cmake-modules. Ze leveren een set van nuttige hulpmiddelen:
- KDEInstallDirs levert gemaksvariabelen zoals
${KDE_INSTALL_TARGETS_DEFAULT_ARGS}
,${KDE_INSTALL_QMLDIR}
,${KDE_INSTALL_BINDIR}
en${KDE_INSTALL_LIBDIR}
. - KDECMakeSettings levert zaken zoals
CMAKE_AUTORCC ON
, eenuninstall
doel dat gebruikt kan worden metcmake --build build/ --target uninstall
enENABLE_CLAZY
. - KDECompilerSettings levert minimale C++ standaard compilervlaggen zoals
-pedantic
, en beste praktijk-macro's zoals-DQT_NO_CAST_FROM_ASCII
om expliciete conversies zoalsQStringLiteral()
te vereisen. - ECMFindQmlModule levert een manier om een runtime QML afhankelijkheid te verzekeren die gevonden is bij compileren.
- ECMQmlModule levert CMake commando's zoals
ecm_add_qml_module()
enecm_target_qml_sources()
.
De volgende sectie is belangrijk, omdat het specificeert welke afhankelijkheden we zullen inbrengen bij compileren. Laten we naar de eerste kijken:
|
|
- find_package() zoekt en laadt de externe bibliotheek en zijn componenten.
REQUIRED
vertelt CMake te eindigen met een fout als het pakket niet gevonden kan worden.COMPONENTS
is een parameter die vooraf gaat aan de specifieke componenten van het framework dat we zullen invoegen.- Elk woord na
COMPONENTS
refereert naar een specifieke component van de bibliotheek.
Notitie
Als u zoekt om componenten in de lijst in de KDE API documentation aan uw toepassing toe te voegen, dan zou u de rechter zijbalk kunnen controleren op hoe de component met CMake toe te voegen. Bijvoorbeeld, voor Kirigami zult u iets vinden zoals find_package(KF6Kirigami2)
, dat met de toevoeging van ECM wordt:
find_package(KF6 COMPONENTS Kirigami)
Let goed op uw ingevoegde componenten, omdat weglaten van die gebruikt worden in onze code onze toepassing niet laten compileren.
De installatieregel instrueert CMake om het desktop-bestand in ${KDE_INSTALL_APPDIR}
te installeren, die onder Linux vertaalt naar $XDG_DATA_DIRS/applications
, gewoonlijk /usr/share/applications
en onder Windows vertaalt naar C:/Program Files/${PROJECT_NAME}/bin/data/applications
:
|
|
De laatste regel laat CMake tonen welke pakketten het heeft gevonden en het laat compileren mislukken onmiddellijk als het een fout ontdekt:
|
|
En bovendien dat add_subdirectory(src)
CMake laat wijzen naar de map 'src/', waar het een ander bestand CMakeLists.txt
vindt:
src/CMakeLists.txt
|
|
Terwijl het eerste bestand metagegevens behandelt en bibliotheken zoekt, zal deze bestaan uit behandeling van afhankelijkheden en de toepassing installeren. Deze heeft de volgende CMake aanroepen:
- add_executable maakt het uitvoerbare doel dat we willen gebruiken om het project te runnen.
ecm_add_qml_module()
maakt een QML-moduledoel aan die toegankelijk zal zijn via het importeren van "org.kde.tutorial".- target_sources() voegt C++ bronbestanden toe aan het uitvoerbare doel.
ecm_target_qml_sources()
voegt QML-bestanden toe aan de module.- target_link_libraries() koppelt de C++-bibliotheken, die gebruikt worden in onze code, aan ons uitvoerbare bestand. Kirigami is hier niet meegenomen omdat we alleen zijn QML-module gebruiken.
- install() installeert het uitvoerbare bestand in het systeem.
De documentatie voor de twee ECM commando's is te vinden in de extra-cmake-modules API voor ECMQmlModule.
De aanroep van ecm_add_qml_module()
was hier gebruikt om het uitvoerbare doel van de traditionele C++ broncode te wijzigen en het om te zetten in iets dat QML-bestanden en C++ broncode kan accepteren die toegankelijk is vanuit QML in wat wordt genoemd het uitvoerbare bestand als achtergronddoel gebruiken voor een QML-module. Dit betekent dat de QML-bestanden direct worden uitgevoerd als onderdeel van de toepassing, wat vaak het geval is voor toepassingen.
U kunt ook een aparte QML-module aanmaken die niet het uitvoerbare bestand gebruikt als doel op de achtergrond met ecm_add_qml_module()
. In zo'n geval zou u een bibliotheekdoel moeten aanmaken met add_library() en het koppelen aan een bestaand uitvoerbaardoel met target_link_libraries()
en bovendien het installeren van de bibliotheek met install()
dan moet u de QML-module afmaken met ecm_finalize_qml_module() het kan dus twee bestanden genereren: qmldir
en qmltypes
. Deze bestanden worden gebruikt door QtQuick toepassingen om aparte QML-modules te vinden.
De methode voor aanmaken van een aparte QML-module wordt beter geïllustreerd in Aparte bestanden gebruiken.
Dit zij toevoegingen geleverd door extra-cmake-modules om het gebruik van Qt declarative registration (de vervanging van Qt hulpbronbestanden) gemakkelijker te maken.
Notitie
Deze bibliotheken zouden overeen moeten komen met de componenten die we hebben ingevoegd in ons vorige bestandCMakeLists.txt
, anders zullen deze componenten niet ingevoegd worden en zal onze toepassing niet compileren.De documentatie voor alle drie commando's is te vinden in de extra-cmake-modules API voor ECMQmlModule.
src/components/CMakeLists.txt
In de instructie over hoe uw code in separate bestanden te splitsen, werd een nieuw CMake-bestand geïntroduceerd om separate QML modules mogelijk te maken:
|
|
Om dit bestand door CMake te laten lezen is het aanroepen (call) van add_subdirectory()
vereist in src/CMakeLists.txt
dat er naar verwijst.
We creëren een nieuw doel kirigami-hello-components
genaamd en zetten het om naar een QML module met de hulp van ecm_add_qml_module() met de importnaam org.kde.tutorial.components
en voegen daar de relevante QML-bestanden toe.
De aanroep naar add_library() genereert een nieuw doel genaamd kirigami-hello-components
. Dit doel zal zijn eigen set broncode-bestanden, QML-bestanden, zijn eigen bibliotheken (libraries) aankoppelen enz., maar het moet nog wel gelinkt worden naar de executable, ook moet het nadat het gecompileerd is nog gelinkt worden naar de executable gecreëerd aan de hand van src/CMakeLists.txt
. Dit wordt gedaan door de doelnaam toe te voegen aan de lijst van bibliotheken (libraries) die gelinkt worden met de executable in target_link_libraries()
.
De aanroep naar ecm_add_qml_module()
stelt de bibliotheek zodanig in dat het net zoals eerder QML-bestanden accepteert, maar deze keer moeten we [GENERATE_PLUGIN_SOURCE] (https://api.kde.org/ecm/module/ECMQmlModule.html) gebruiken. Als het programma wordt gebruikt als een achtergronddoel (zoals bij kirigami-hello
) dan hoeft het geen plugin code te generen omdat het in het uitvoerbare bestand is ingebouwd; bij separate QML modules zoals kirigami-hello-componenten
is de plugin code noodzakelijk.
Upstream Qt's qt_add_qml_module() genereert standaard samen met de QML module een plugin, maar KDE's ecm_add_qml_module()
doet dat standaard niet vanwege de backwards compatibility.
Daarnaast is het noodzakelijk om de QML modules te scheiden om het doel af te maken. Dit houd hoofdzakelijk is dat CMake twee bestanden genereert, [qmldir en qmltypes] (https://doc.qt.io/qt-6/qtqml-modules-qmldir.html), die de QML modules beschrijven die we hebben en hun symbolen exporteren om in de bibliotheek te gebruiken. Ze zijn belangrijk bij het installeren van uw programma zodat het uitvoerbare bestand voor elke module de QML-bestanden kan vinden, zodat ze automatisch aan het doel kunnen worden toegevoegd.
Het doel kan dan gewoon net zoals vroeger geïnstalleerd worden.
De volgende keer dat u meer QML-bestanden moet toevoegen, onthoud om ze in te voegen in dit bestand. C++ bestanden die de QML_ELEMENT sleutelwoorden gebruiken die we veel later zullen zien in de handleiding kunnen hier ook toegevoegd worden met target_sources()
. U kunt uw code logisch scheiden door meer QML-modulen aan te maken door naar behoefte verschillende zaken te importeren.
Deze opzet zal bruikbaar zijn bij ontwikkelen van de meeste Kirigami toepassingen.