Розбираємося із CMakeLists
CMake
У нашому вступному підручнику ми використали CMake як систему збирання для нашої програми, але приділили увагу лише одному з файлів CMakeLists.txt
. Цей розділ ми присвятимо докладнішому вивченню принципів його роботи.
CMake є корисним, оскільки за його допомогою ми можемо автоматизувати більшу частину роботи, яку слід виконати до компіляції.
Кореневий CMakeLists.txt
Можливо, ви пам'ятаєте цей файл CMakeLists.txt
з першого підручника:
|
|
Перший рядок, cmake_minimum_required()
, встановлює версію CMake, яку буде викликано.
Після цього project(kirigami-tutorial)
визначає назву проєкту.
Далі, маємо розділ, у якому ми включимо декілька потрібних параметрів CMake і KDE за допомогою extra-cmake-modules. Вони забезпечують роботу корисних допоміжних інструментів:
- У KDEInstallDirs передбачено зручні змінні, зокрема
${KDE_INSTALL_TARGETS_DEFAULT_ARGS}
,${KDE_INSTALL_QMLDIR}
,${KDE_INSTALL_BINDIR}
та${KDE_INSTALL_LIBDIR}
. - KDECMakeSettings містить речі, подібні до
CMAKE_AUTORCC ON
, цільuninstall
, якою можна скористатися за допомогоюcmake --build build/ --target uninstall
, іENABLE_CLAZY
. - KDECompilerSettings містить мінімальний стандарт C++, прапорці компіляції, зокрема
-pedantic
, і найкращі стандартні макроси, зокрема-DQT_NO_CAST_FROM_ASCII
для встановлення вимог щодо явних перетворень, зокремаQStringLiteral()
. - ECMFindQmlModule містить спосіб забезпечення виявлення динамічної залежності QML під час компіляції.
- ECMQmlModule містить команди CMake, зокрема
ecm_add_qml_module()
іecm_target_qml_sources()
.
Наступний розділ є важливим, оскільки у ньому визначають, які залежності ми використовуватимемо під час компіляції. Погляньмо на початок:
|
|
- find_package() знаходить і завантажує зовнішню бібліотеку та її компоненти.
REQUIRED
повідомляє CMake, що програма має повідомити про помилку, якщо пакунок не буде знайдено.COMPONENTS
— параметр, який передує специфічним компонентам бібліотеки, які ми включатимемо.- Кожне слово після
COMPONENTS
вказує на компонент бібліотеки.
Нотатка
Якщо ви хочете додати будь-які компоненти зі списку у документації до програмного інтерфейсу KDE до вашої програми, ви можете звернутися до коду правої бічної панелі, щоб ознайомитися зі способом додавання компонента за допомогою CMake. Наприклад, для Kirigami ви побачите щось подібне до find_package(KF6Kirigami)
, що з додаванням ECM стає чимось подібним до такого:
find_package(KF6 COMPONENTS Kirigami)
Значну увагу слід звернути на включення компонентів, оскільки пропускання компонентів, які використано у вашому коді, призведе до неможливості зібрати вашу програму.
Рядок встановлення повідомляє CMake, що слід встановити стільничний файл до ${KDE_INSTALL_APPDIR}
, що у Linux буде перенесено як $XDG_DATA_DIRS/applications
, зазвичай /usr/share/applications
, а у Windows буде перенесено як C:/Program Files/${PROJECT_NAME}/bin/data/applications
:
|
|
Останній рядок дозволяє CMake вивести список пакунків, які було знайдено, і призводить до негайного припинення компіляції, якщо станеться помилка:
|
|
А вище, add_subdirectory(src)
вказує CMake каталог src/
, де програма знайде інший файл CMakeLists.txt
.
src/CMakeLists.txt
|
|
Перший файл обробляв метадані і пошук бібліотек, цей файл містить команди обробки залежностей та встановлення програми. У ньому містяться такі виклики CMake:
- add_executable() створює виконуваний файл, яким ми користуватимемося для запуску результатів нашого проєкту.
ecm_add_qml_module()
створює ціль — модуль QML, — доступ до якої здійснюватиметься за допомогою імпортування «org.kde.tutorial».- target_sources() додає файли початкового коду мовою C++ до виконуваної цілі проєкту.
ecm_target_qml_sources()
додає до модуля файли QML.- target_link_libraries() пов'язує ціль із бібліотеками C++, які використовуються у нашому коді для створення виконуваного файла. Kirigami не включено сюди, оскільки ми використовуємо лише її модуль QML.
- install() встановлює виконуваний файл у системі.
Документацію з двох команд ECM можна знайти у програмному інтерфейсі extra-cmake-modules для ECMQmlModule.
Виклик ecm_add_qml_module()
тут було використано, щоб модифікувати традиційну ціль збирання початкового коду C++, виконуваний файл, і перетворити її на щось, що може приймати файли QML, і початковий код C++ буде доступним з QML у межах того, що називається використання виконуваного файла як резервної цілі для модуля QML. Це означає, що файли QML запускаються безпосередньо як частина програми, що часто буває для програм.
Ви також можете створити окремий модуль QML, який не використовує виконуваний файл як резервну ціль, за допомогою ecm_add_qml_module()
. У цьому випадку ви могли б створити ціль-бібліотеку з використанням add_library(), скомпонувати її із наявною ціллю — виконуваним файлом — за допомогою target_link_libraries()
, і на додачу до встановлення бібліотеки за допомогою install()
вам довелося б створити остаточну версію модуля QML за допомогою ecm_finalize_qml_module(), так, щоб він міг створити два файли: qmldir
і qmltypes
. Ці файли програми QtQuick використовують для пошуку окремих модулів QML.
Спосіб створення окремого модуля QML краще описано у розділі щодо використання окремих файлів.
Ці доповнення, які містяться у extra-cmake-modules, призначено для спрощення використання декларативної реєстрації Qt (заміни файлів ресурсів Qt).
Нотатка
Ці бібліотеки мають відповідати компонентам, які ми включили до нашого попереднього файлаCMakeLists.txt
— інакше ці компоненти не буде включено і нашу програму не можна буде зібрати.Документацію до усіх трьох команд ECM можна знайти у програмному інтерфейсі extra-cmake-modules для ECMQmlModule.
src/components/CMakeLists.txt
У підручнику щодо того, як поділити ваш код на окремі файли було впроваджено новий файл CMake для забезпечення роботи окремих модулів QML:
|
|
Щоб цей файл прочитала CMake слід додати виклик add_subdirectory()
до src/CMakeLists.txt
, який вказуватиме сюди.
Ми створюємо нову ціль із назвою kirigami-hello-components
, а потім перетворюємо її на модуль QML за допомогою using ecm_add_qml_module() із назвою імпортування org.kde.tutorial.components
і додаємо пов'язані файли QML.
Виклик add_library() створює нову ціль із назвою kirigami-hello-components
. Ця ціль матиме власний набір файлів початкового коду, файлів QML, компонує власні бібліотеки тощо, але її доведеться скомпонувати з виконуваним файлом, а коли її буде скомпільовано, її слід скомпонувати із виконуваним файлом, який створено у src/CMakeLists.txt
. Ця мета досягається додаванням назви цілі до списку бібліотек, які буде скомпоновано до виконуваного файла у target_link_libraries()
.
Виклик ecm_add_qml_module()
змінює бібліотеку так, щоб дозволити їй приймати файли QML, як і раніше, але цього разу нам слід скористатися GENERATE_PLUGIN_SOURCE. Якщо як резервну ціль використано виконуваний файл (як у kirigami-hello
), вона не потребує створення коду додатка, оскільки її буде зібрано до виконуваного файла; із окремими модулями QML, зокрема kirigami-hello-components
, код додатка є обов'язковим.
Основна команда Qt qt_add_qml_module() типово створює додаток разом із модулем QML, а ecm_add_qml_module()
KDE типово не робить цього з міркувань зворотної сумісності.
Іншою річчю, яка потрібна для окремих модулів QML, є завершення цілі. Це, в основному, означає, що CMake створює два файли, qmldir і qmltypes, які описують наші модулі QML та експортує їхні символи для використання у бібліотеці. Вони є важливими при встановленні вашої програми, щоб запущений виконуваний файл міг знайти місце, де перебувають файли кожного модуля QML, щоб їх можна було автоматично додати до цілі.
Далі ви можете встановити ціль, як і раніше.
Наступного разу, коли вам буде потрібно додати файли QML, не забудьте включити їх до цього файла. Файли C++, які використовують ключове слово QML_ELEMENT, які ми побачимо набагато пізніше у цьому підручнику, також можна додати саме тут за допомогою target_sources()
. Якщо потрібно, ви можете логічно розділити ваш код створенням додаткових модулів QML із різними імпортуваннями.
Такими налаштуваннями можна скористатися для створення більшості програм на основі Kirigami.