Понедельник, 25.12.2023 19:34

Базовый обзор CMakeLists.txt. Миграция с Qt5 на Qt6. Часть 2

Базовый обзор CMakeLists.txt. Миграция с Qt5 на Qt6. Часть 2

В прошлой статье мы рассмотрели миграцию с Qt5 на Qt6. В новом цикле посвященном Qt6, мы начали полностью переписывать старые проекты для работы с Qt6.

Сегодня будет рассмотрена структура файла CMakeLists.txt на примере CMAKE-проекта созданного с помощью QtCreator.

Файл CMakeLists.txt 

Файл CMakeLists.txt представляет собой обычный текстовый файл каждая строка которого содержит команду для утилиты CMAKE. Команды могут занимать несколько строк, но всегда заканчиваются символом «)».

Рассмотрим файл автоматически созданный в QtCreator 11.0.3:

cmake_minimum_required(VERSION 3.5)

project(QtFloatWindow VERSION 0.1 LANGUAGES CXX)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)

set(PROJECT_SOURCES
        main.cpp
        mainwindow.cpp
        mainwindow.h
        mainwindow.ui
)

if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
    qt_add_executable(QtFloatWindow
        MANUAL_FINALIZATION
        ${PROJECT_SOURCES}
        floatwindow.h floatwindow.cpp floatwindow.ui
    )
# Define target properties for Android with Qt 6 as:
#    set_property(TARGET QtFloatWindow APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
#                 ${CMAKE_CURRENT_SOURCE_DIR}/android)
# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
else()
    if(ANDROID)
        add_library(QtFloatWindow SHARED
            ${PROJECT_SOURCES}
        )
# Define properties for Android with Qt 5 after find_package() calls as:
#    set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
    else()
        add_executable(QtFloatWindow
            ${PROJECT_SOURCES}
        )
    endif()
endif()

target_link_libraries(QtFloatWindow PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)

# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
# If you are developing for iOS or macOS you should consider setting an
# explicit, fixed bundle identifier manually though.
if(${QT_VERSION} VERSION_LESS 6.1.0)
  set(BUNDLE_ID_OPTION MACOSX_BUNDLE_GUI_IDENTIFIER com.example.QtFloatWindow)
endif()
set_target_properties(QtFloatWindow PROPERTIES
    ${BUNDLE_ID_OPTION}
    MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
    MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
    MACOSX_BUNDLE TRUE
    WIN32_EXECUTABLE TRUE
)

include(GNUInstallDirs)
install(TARGETS QtFloatWindow
    BUNDLE DESTINATION .
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

if(QT_VERSION_MAJOR EQUAL 6)
    qt_finalize_executable(QtFloatWindow)
endif()

Команды CMAKE

cmake_minimum_required

cmake_minimum_required(VERSION 3.5)

Данная команда указывает какая минимальная версия утилиты CMAKE потребуется для сборки проекта, если она больше чем используемая в системе, то при сборке вы получите ошибку. 

Например, если мы изменим цифру на 5.5 и запустим сборку, то получим сообщение об ошибке:

CMake Error at CMakeLists.txt:1 (cmake_minimum_required):
CMake 5.5 or higher is required.  You are running version 3.27.7

project

project(QtFloatWindow VERSION 0.1 LANGUAGES CXX)

Задает имя проекта QtFloatWindow, его версию 0.1, а также язык для сборки, в нашем случае C++

CMAKE позволяет собирать проекты, написанные на разных языках программирования:

ASM
C
CSharp
CUDA
CXX – С++
Fortran
Java
OBJC (Objective C)
OBJCXX (Objective C++)
RC (Windows Resource Compiler)
Swift

set

set(CMAKE_AUTOUIC ON)

set(CMAKE_AUTOMOC ON)

set(CMAKE_AUTORCC ON)

Данные команды указывают использовать запуск утилит Qt в автоматическом режиме:

CMAKE_AUTOUIC – автоматическая компиляция .ui файлов с помощью uic;

CMAKE_AUTOMOC – автоматический запуск Meta-Object Compiler с помощью moc;

CMAKE_AUTORCC  – автоматический запуск Resource Compiler с помощью rcc.

Все эти компиляторы необходимы для успешной сборки проекта с использованием Qt6.

set(CMAKE_CXX_STANDARD 17)

Команда задает стандарт C++, в данном случае это 17. CMAKE поддерживает разнообразные стандарты C++:

98 - C++98
11 - C++11
14 - C++14
17 - C++17 (с версии 3.8)
20 - C++20 (с версии 3.12)
23 - C++23 (с версии 3.20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

Стандарты C++ созданы не просто так. Каждая версия устанавливает требования к написанию программного кода и от версии к версии они могу сильно отличаться. 

С каждой новой версией стандарта в язык вводится новый функционал, которого не было до этого. Если программа написана по стандарту С++17 и использует новые возможности языка, то при попытке собрать проект с использованием стандарта версии C++14 вы получите множество ошибок. Чтобы этого избежать используется команда CMAKE_CXX_STANDARD_REQUIRED которая заставляет компилятор строго следовать указанному стандарту!

find_package

find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)

Команда используется для подключения необходимых библиотек. В данной случае происходит поиск среди библиотек Qt6 и Qt5 и мы подключаем библиотеку компонентов Widgets.

set PROJECT_SOURCES

set(PROJECT_SOURCES
        main.cpp
        mainwindow.cpp
        mainwindow.h
        mainwindow.ui
)

Команда используется для указания всех файлов проекта. Все файлы, добавленные в этот список, будут отображены в списке файлов проекта в QtCreator.  Новый файлы нужно добавлять в конец списка.

if

if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
   qt_add_executable(QtFloatWindow
       MANUAL_FINALIZATION
       ${PROJECT_SOURCES}
        floatwindow.h floatwindow.cpp floatwindow.ui
    )
# Define target properties for Android with Qt 6 as:
#   set_property(TARGET QtFloatWindow APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
#                ${CMAKE_CURRENT_SOURCE_DIR}/android)
# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
else()
    if(ANDROID)
       add_library(QtFloatWindow SHARED
           ${PROJECT_SOURCES}
        )
# Define properties for Android with Qt 5 after find_package() calls as:
#   set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
    else()
        add_executable(QtFloatWindow
           ${PROJECT_SOURCES}
        )
    endif()
endif()

Этот блок команд немного сложнее.

if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)

CMAKE позволяет управлять процессом сборки проекта с помощью условий. В данном случае мы проверяем, чтобы версия Qt была как минимум 6.0.0.

Если это так, то выполняется следующий блок:

qt_add_executable

   qt_add_executable(QtFloatWindow
       MANUAL_FINALIZATION
       ${PROJECT_SOURCES}
        floatwindow.h floatwindow.cpp floatwindow.ui
    )

Команда задает имя исполняемого файла, который будет создан после окончания сборки проекта, для данного проекта в Windows это QtFloatWindow.exe.

Параметр MANUAL_FINALIZATION означает что мы самостоятельно запустим окончательную фазу сборки проекта. Как правило это нужно сделать в самом конце файла.

${PROJECT_SOURCES} – ранее мы указывали список файлов с исходным кодом, они будут автоматически добавлены в процессе сборки с помощью этой переменной.

else()
    if(ANDROID)
        add_library(QtFloatWindow SHARED
           ${PROJECT_SOURCES}
        )
# Define properties for Android with Qt 5 after find_package() calls as:
#   set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
    else()
        add_executable(QtFloatWindow
           ${PROJECT_SOURCES}
        )
    endif()
endif()

Если у нас Qt версии 5, то производится попытка собрать проект с другими параметрами.

target_link_libraries

target_link_libraries(QtFloatWindow PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)

Указывает какие библиотеки использовать в процессе сборки.

# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
# If you are developing for iOS or macOS you should consider setting an
# explicit, fixed bundle identifier manually though.
if(${QT_VERSION} VERSION_LESS 6.1.0)
  set(BUNDLE_ID_OPTION MACOSX_BUNDLE_GUI_IDENTIFIER com.example.QtFloatWindow)
endif()
set_target_properties(QtFloatWindow PROPERTIES
   ${BUNDLE_ID_OPTION}
   MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
   MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
    MACOSX_BUNDLE TRUE
    WIN32_EXECUTABLE TRUE
)

Указывает дополнительные параметры, главным образом для iOS

include и install

include(GNUInstallDirs)
install(TARGETS QtFloatWindow
    BUNDLE DESTINATION .
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

Указывает какие каталоги в Linux будут использованы для установки собранной программы.

qt_finalize_executable

if(QT_VERSION_MAJOR EQUAL 6)
    qt_finalize_executable(QtFloatWindow)
endif()

Указывает, что настройка завершена и можно запускать финальные процедуры.

После того как CMAKE закончит чтение всех команд из файла, запускается процесс сборки проекта согласно заданным параметрам. 

Заключение

Сегодня мы рассмотрели содержимое файла CMakeLists.txt созданного средой разработки Qt Creator, команды в каждой строке и определили, зачем они нужны и когда применяются.

Категория Qt6
Теги Qt Qt6 CMAKE

Добавить комментарий

Простой текст

  • HTML-теги не обрабатываются и показываются как обычный текст
  • Строки и абзацы переносятся автоматически.
  • Адреса веб-страниц и email-адреса преобразовываются в ссылки автоматически.
Просмотров: 147