Розбираємося із CMakeLists

Ознайомлюємося із тим, як працюють файли CMakeLists.txt

CMake

У нашому вступному підручнику ми використали CMake як систему збирання для нашої програми, але приділили увагу лише одному з файлів CMakeLists.txt. Цей розділ ми присвятимо докладнішому вивченню принципів його роботи.

CMake є корисним, оскільки за його допомогою ми можемо автоматизувати більшу частину роботи, яку слід виконати до компіляції.

CMakeLists.txt

Можливо, ви пам'ятаєте цей файл 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
cmake_minimum_required(VERSION 3.16)
project(helloworld)

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

include(KDEInstallDirs)
include(KDECMakeSettings)
include(KDECompilerSettings NO_POLICY_SCOPE)

find_package(Qt${QT_MAJOR_VERSION} REQUIRED NO_MODULE COMPONENTS
    Core
    Quick
    Test
    Gui
    QuickControls2
    Widgets
)

find_package(KF${QT_MAJOR_VERSION} REQUIRED COMPONENTS
    Kirigami2
    I18n
    CoreAddons
)

add_subdirectory(src)

feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES)

Перший рядок, cmake_minimum_required(VERSION 3.16), встановлює версію CMake, яку буде викликано.

Після цього project(helloworld) визначає назву проєкту.

Далі, маємо розділ, у якому ми включимо декілька потрібних параметрів CMake і KDE за допомогою extra-cmake-modules. Зараз немає сенсу надто перейматися цими рядками — ми не будемо змінювати їх у цьому підручнику.

Наступний розділ є важливим, оскільки у ньому визначають, які залежності ми використовуватимемо під час компіляції. Погляньмо на початок:

11
12
13
14
15
16
17
18
find_package(Qt${QT_MAJOR_VERSION} REQUIRED NO_MODULE COMPONENTS
    Core
    Quick
    Test
    Gui
    QuickControls2
    Widgets
)
  • find_package() знаходить і завантажує зовнішній компонент.
  • Першим словом є бібліотека, Qt. ${QT_MAJOR_VERSION} є зручною змінною, доступ до якої надає extra-cmake-modules. За її допомогою ми можемо вибрати використану версію Qt, 5 або 6, залежно від того, чи використовуємо ми прапорець CMake -DBUILD_WITH_QT6=ON.
  • REQUIRED повідомляє CMake, що ці залежності є справді обов'язковими і що програма має повідомити про помилку і завершити роботу, якщо пакунок не буде знайдено.
  • NO_MODULE перемикає CMake у режим Config. Зараз перейматися цим немає сенсу.
  • COMPONENTS — параметр, який передує специфічним компонентам бібліотеки, які ми включатимемо.
  • Кожне слово після COMPONENTS вказує на компонент.

Останній рядок дозволяє CMake вивести список пакунків, які було знайдено. А вище, add_subdirectory(src) вказує CMake каталог src/, де програма знайде інший файл CMakeLists.txt:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
add_executable(helloworld)

target_sources(helloworld PRIVATE
    main.cpp
    resources.qrc
)

target_link_libraries(helloworld
    Qt${QT_MAJOR_VERSION}::Quick
    Qt${QT_MAJOR_VERSION}::Qml
    Qt${QT_MAJOR_VERSION}::Gui
    Qt${QT_MAJOR_VERSION}::QuickControls2
    Qt${QT_MAJOR_VERSION}::Widgets
    KF${QT_MAJOR_VERSION}::I18n
)

install(TARGETS helloworld ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})

Оскільки більша частина визначається першим файлом, цей файл є набагато коротшим.

  • add_executable() відповідає за створення нашого виконуваного файла.
  • target_sources() надає нам змогу додавати файли, які буде використано у нашому новому виконуваному файлі.
  • target_link_libraries() динамічно пов'язує ціль із бібліотеками, які використовуються у нашому коді для створення виконуваного файла. Kirigami не включено сюди, оскільки ми використовуємо лише її модуль QML.
  • install() розташовує наш виконуваний файл у належному місці за допомогою ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}, зручної змінної, яку надає KDEInstallDirs у extra-cmake-modules, і яка встановлює виконувані файли та бібліотеки у належному місці, без потреби у визначенні абсолютних шляхів, подібно до GNUInstallDirs.

Такими налаштуваннями можна скористатися для створення більшості програм на основі Kirigami.