Entendre les CMakeLists
CMake
En la nostra guia d'aprenentatge introductòria, emprem el CMake com el sistema de compilació per a la nostra aplicació, però només parem molta atenció a un dels nostres fitxers CMakeLists.txt
. Aquí, repassarem com funcionen amb una mica més de detall.
El CMake és útil perquè ens permet automatitzar gran part de les coses que s'han de fer abans de la compilació.
El CMakeLists.txt arrel
És possible que recordeu aquest fitxer CMakeLists.txt
de la primera guia d'aprenentatge:
|
|
La primera línia, cmake_minimum_required()
estableix la versió del CMake que es cridarà.
Després d'això, project(kirigami-tutorial)
defineix el nom del projecte.
Després arribem a una secció on incloem una sèrie de paràmetres necessaris de CMake i del KDE fent servir extra-cmake-modules. Proporcionen un conjunt d'utilitats:
- KDEInstallDirs proporciona variables d'utilitat com ara
${KDE_INSTALL_TARGETS_DEFAULT_ARGS}
,${KDE_INSTALL_QMLDIR}
,${KDE_INSTALL_BINDIR}
i${KDE_INSTALL_LIBDIR}
. - KDECMakeSettings proporciona coses com
CMAKE_AUTORCC ON
, un objectiuuninstall
que es pot fer servir ambcmake --build build/ --target uninstall
, iENABLE_CLAZY
. - KDECompilerSettings proporciona un estàndard C++ mínim, indicadors del compilador com
-pedantic
, i macros de millors pràctiques com-DQT_NO_CAST_FROM_ASCII
per a necessitar conversions explícites comQStringLiteral()
. - ECMFindQmlModule proporciona una manera d'assegurar que la dependència de QML en temps d'execució es troba en temps de compilació.
- ECMQmlModule proporciona ordres del CMake com
ecm_add_qml_module()
iecm_target_qml_sources()
.
La secció següent és important, perquè especifica quines dependències portarem en temps de compilació. Vegem el primer:
|
|
- find_package() cerca i carrega la biblioteca externa i els seus components.
REQUIRED
fa saber al CMake que surti amb un error si no s'ha pogut trobar el paquet.COMPONENTS
és un paràmetre que precedeix als components específics del marc de treball que incloem.- Cada paraula després de
COMPONENTS
es refereix a un component específic de la biblioteca.
Nota
Si esteu mirant d'afegir qualsevol component llistat a la documentació de l'API de KDE a la vostra aplicació, podeu comprovar la barra lateral dreta per com afegir el component amb el CMake. Per exemple, per al Kirigami, trobareu quelcom com find_package(KF6Kirigami)
, el qual amb l'addició de l'ECM es converteix en:
find_package(KF6 COMPONENTS Kirigami)
Pareu molta atenció als components inclosos, ja que l'omissió dels utilitzats en el nostre codi aturarà la compilació de l'aplicació.
La línia d'instal·lació instrueix al CMake que instal·li el fitxer «desktop» a ${KDE_INSTALL_APPDIR}
, que al Linux es tradueix com $XDG_DATA_DIRS/applications
, normalment /usr/share/applications
, i en el Windows es tradueix com C:/Program Files/${PROJECT_NAME}/bin/data/applications
:
|
|
La línia final permet que el CMake imprimeixi quins paquets ha trobat, i fa que la compilació falli completament si troba un error:
|
|
I a sobre d'això, add_subdirectory(src)
a punta el CMake en el directori src/
, a on troba un altre fitxer CMakeLists.txt
.
src/CMakeLists.txt
|
|
Mentre que el primer fitxer gestionava metadades i cercava biblioteques, aquest consisteix a gestionar dependències i instal·lar l'aplicació. Té les crides següents del CMake:
- add_executable() crea l'objectiu executable que farem servir per a executar el projecte.
ecm_add_qml_module()
crea un objectiu de mòdul QML al qual es podrà accedir via la importació «org.kde.tutorial».- target_sources() afegeix fitxers de codi font C++ a l'objectiu executable.
ecm_target_qml_sources()
afegeix fitxers QML al mòdul.- target_link_libraries() enllaça les biblioteques C++ utilitzades en el nostre codi amb el nostre executable. El Kirigami no s'inclou aquí perquè només estem utilitzant el seu mòdul QML.
- install() instal·la l'executable en el sistema.
La documentació de les dues ordres ECM es pot trobar a l'API dels extra-cmake-modules per a l'ECMQmlModule.
La crida a ecm_add_qml_module()
s'ha fet servir aquí per a modificar l'objectiu de l'executable del codi font C++ tradicional i convertir-lo en alguna cosa que pugui acceptar fitxer QML i codi font C++ source que sigui accessible des del QML en el que s'ha cridat usant l'executable com a objectiu de reserva per a un mòdul QML. Això vol dir que els fitxers QML s'executen directament com a part de l'aplicació, que sovint és el cas de les aplicacions.
També podeu crear un mòdul QML separat que no usi l'executable com a objectiu de reserva utilitzant ecm.add.qml.module()
. En aquest cas, hauríeu de crear un objectiu de biblioteca utilitzant add.library(), enllaçar-lo a un objectiu executable existent utilitzant target_link_libraries()
, i a més d'instal·lar la biblioteca amb install()
haureu de finalitzar el mòdul QML amb ecm_finalize_qml_module() perquè pugui generar dos fitxers: qmldir
i qmltypes
. Aquests fitxers són utilitzats per les aplicacions QtQuick per a trobar mòduls QML separats.
El mètode per a crear un mòdul QML separat s'exemplifica millor a Usar fitxers separats.
Aquests són afegits proporcionats per extra-cmake-modules per a fer que l'ús del registre declaratiu de les Qt faciliti (la substitució als fitxers de recursos de les Qt).
Nota
Aquestes biblioteques han de coincidir amb els components que incloem en el nostre fitxerCMakeLists.txt
anterior. En cas contrari, aquests components no s'inclouran i la nostra aplicació no compilarà.La documentació de les tres ordres ECM es pot trobar a l'API dels extra-cmake-modules per a l'ECMQmlModule.
src/components/CMakeLists.txt
A la guia d'aprenentatge sobre com dividir el codi en fitxers separats, es va introduir un fitxer CMake nou per a permetre mòduls QML separats:
|
|
El requisit perquè aquest fitxer sigui llegit pel CMake és afegir una crida a add_subdirectory()
en el src/CMakeLists.txt
apuntant-hi.
Creem un objectiu nou anomenat kirigami-hello-components
i després el convertim en un mòdul QML utilitzant ecm_add_qml_module() amb el nom d'importació org.kde.tutorial.components
i afegim els fitxers QML pertinents.
La crida a add_library() genera un objectiu nou anomenat kirigami-hello-components
. Aquest objectiu tindrà el seu conjunt propi de fitxers de codi font, fitxers en QML, enllaçarà les seves pròpies biblioteques i així successivament, però necessitarà estar vinculat a l'executable, però una vegada compilat necessitarà estar vinculat a l'executable creat en el src/CMakeLists.txt
. Això es fa afegint el nom de destinació a la llista de biblioteques que s'enllaçaran a l'executable a target_link_libraries()
.
La crida a ecm_add_qml_module()
canvia la biblioteca per a permetre que accepti fitxers QML com abans, però aquesta vegada cal usar GENERATE_PLUGIN_SOURCE. Quan l'executable es fa servir com a objectiu de reserva (com amb kirigami-hello
) no cal generar codi del connector ja que està construït dins l'executable; amb mòduls QML separats com kirigami-hello-components
és necessari el codi del connector.
El qt_add_qml_module() de les Qt originals generen de manera predeterminada un connector junt amb el mòdul QML, però l'ecm_add_qml_module()
de KDE no ho fa per compatibilitat cap enrere.
Una altra cosa que és necessària per als mòduls QML separats és finalitzar l'objectiu. Això significa principalment que el CMake genera dos fitxers, qmldir i qmltypes, que descriuen els mòduls QML que tenim i exporten els seus símbols per al seu ús a la biblioteca. Són importants quan s'instal·la l'aplicació perquè l'executable que s'està executant pugui trobar on són els fitxers QML per a cada mòdul, de manera que s'afegeixen automàticament a l'objectiu.
A continuació, podeu instal·lar l'objectiu com abans.
La pròxima vegada que necessiteu afegir més fitxers QML, recordeu d'incloure'ls en aquest fitxer. Els fitxers C++ que utilitzen la paraula clau QML_ELEMENT que veurem més tard a la guia d'aprenentatge també es poden afegir aquí utilitzant target_sources()
. Podeu separar lògicament el codi creant més mòduls QML amb importacions diferents segons calgui.
Aquesta configuració serà útil en desenvolupar la majoria de les aplicacions escrites amb el Kirigami.