24
Using Modern CMake with Qt May 13 th 2020 Using Modern CMake with Qt / Kevin Funk (KDAB) 1 Kevin Funk [email protected]

Using Modern CMake with Qt - KDAB...9 May 13th 2020 Using Modern CMake with Qt / Kevin Funk (KDAB) Getting Started with CMake (1)CMake magic that enables Qt-specific behavior for .moc/.qrc/.ui

  • Upload
    others

  • View
    27

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Using Modern CMake with Qt - KDAB...9 May 13th 2020 Using Modern CMake with Qt / Kevin Funk (KDAB) Getting Started with CMake (1)CMake magic that enables Qt-specific behavior for .moc/.qrc/.ui

Using Modern CMake with Qt

May 13th 2020 Using Modern CMake with Qt / Kevin Funk (KDAB)1

Kevin [email protected]

Page 2: Using Modern CMake with Qt - KDAB...9 May 13th 2020 Using Modern CMake with Qt / Kevin Funk (KDAB) Getting Started with CMake (1)CMake magic that enables Qt-specific behavior for .moc/.qrc/.ui

About

Kevin Funk

• Senior Software Engineer

• Sales Engineer

• Consultant and trainer at KDAB since 2009

• Qt developer since 2006

• Contributor to KDE/Qt and Free Software

Page 3: Using Modern CMake with Qt - KDAB...9 May 13th 2020 Using Modern CMake with Qt / Kevin Funk (KDAB) Getting Started with CMake (1)CMake magic that enables Qt-specific behavior for .moc/.qrc/.ui

May 13th 20204 Using Modern CMake with Qt / Kevin Funk (KDAB)

What is CMake?

CMake is a tool to simplify the build process for development projects across different platforms.

CMake automatically generates build systems, such as Makefiles, Ninja and Visual Studio project files.

Page 4: Using Modern CMake with Qt - KDAB...9 May 13th 2020 Using Modern CMake with Qt / Kevin Funk (KDAB) Getting Started with CMake (1)CMake magic that enables Qt-specific behavior for .moc/.qrc/.ui

May 13th 20205 Using Modern CMake with Qt / Kevin Funk (KDAB)

Modern CMake?

• In a nutshell● Code: Forget the commands add_compile_options, include_directories, link_directories,

link_libraries● Instead use their more modern target_* counterparts

● Code: Prefer functions over macros

● Code: Keep internal properties PRIVATE● E.g. do not propagate -Werror

● Modules: Create and use exported targets● Compare ${QT_QTGUI_LIBRARY} (old) vs. Qt5::Gui (modern)

● ...

Page 5: Using Modern CMake with Qt - KDAB...9 May 13th 2020 Using Modern CMake with Qt / Kevin Funk (KDAB) Getting Started with CMake (1)CMake magic that enables Qt-specific behavior for .moc/.qrc/.ui

May 13th 20206 Using Modern CMake with Qt / Kevin Funk (KDAB)

Modern CMake: Advantages

• Requirements are attached to the targets• Automatically propagated as necessary through the build

• Makes creating complex builds much less error-prone

• Selecting modern C++ standards (cross-platform) is simple• Example: target_compile_features(myTarget PUBLIC cxx_std_11)

• OR: set(CMAKE_CXX_STANDARD 11)

set(CMAKE_CXX_STANDARD_REQUIRED ON)

Page 6: Using Modern CMake with Qt - KDAB...9 May 13th 2020 Using Modern CMake with Qt / Kevin Funk (KDAB) Getting Started with CMake (1)CMake magic that enables Qt-specific behavior for .moc/.qrc/.ui

May 13th 2020 Using Modern CMake with Qt / Kevin Funk (KDAB)7

Getting Started

Page 7: Using Modern CMake with Qt - KDAB...9 May 13th 2020 Using Modern CMake with Qt / Kevin Funk (KDAB) Getting Started with CMake (1)CMake magic that enables Qt-specific behavior for .moc/.qrc/.ui

May 13th 20209 Using Modern CMake with Qt / Kevin Funk (KDAB)

Getting Started with CMake

(1) CMake magic that enables Qt-specific behavior for .moc/.qrc/.ui file types

(2) Ensures adding current source and build directory to the include path

(3) This pulls in Qt dependencies (here: Qt Widgets only) and marks them as required

(4) Add an executable target using different source file types

(5) Wrap up: Link to the needed Qt libraries

# Qt with CMake example

cmake_minimum_required(VERSION 3.10.0)

project(helloworld)

set(CMAKE_AUTOMOC ON) ➀set(CMAKE_AUTORCC ON)set(CMAKE_AUTOUIC ON)set(CMAKE_INCLUDE_CURRENT_DIR ON) ➁find_package(Qt5 COMPONENTS Widgets REQUIRED) ➂add_executable(helloworld mainwindow.ui mainwindow.cpp main.cpp resources.qrc) ➃target_link_libraries(helloworld Qt5::Widgets) ➄

Page 8: Using Modern CMake with Qt - KDAB...9 May 13th 2020 Using Modern CMake with Qt / Kevin Funk (KDAB) Getting Started with CMake (1)CMake magic that enables Qt-specific behavior for .moc/.qrc/.ui

May 13th 202010 Using Modern CMake with Qt / Kevin Funk (KDAB)

Running CMake: Command line

# In a terminal# Note these are cross-platform instructions

mkdir buildcd build

cmake .. <additional args> ➀# Build via CMakecmake --build . ➁# OR build via ANY of ➂make nmakeninja...

(1) Run CMake on the source directory (and pass additional arguments if necessary).Build system files will be generated.

(2) Run this to start the build

(3) Instead of going via CMake you can also invoke the build tool directly

Page 9: Using Modern CMake with Qt - KDAB...9 May 13th 2020 Using Modern CMake with Qt / Kevin Funk (KDAB) Getting Started with CMake (1)CMake magic that enables Qt-specific behavior for .moc/.qrc/.ui

May 13th 202011 Using Modern CMake with Qt / Kevin Funk (KDAB)

Running CMake: Command line - contd

# Finding a specific Qt install

cmake -DCMAKE_PREFIX_PATH=/path/to/qt5-install .. <additional args> ➀# ORexport CMAKE_PREFIX_PATH=/path/to/qt5-installcmake .. <additional args> ➁

(1) Set the CMAKE_PREFIX_PATH CMake variable (via command-line args) to describe additional search paths for find_package(...)

(2) OR set CMAKE_PREFIX_PATH as environment variable (works on all supported platforms) before invoking CMake

Page 10: Using Modern CMake with Qt - KDAB...9 May 13th 2020 Using Modern CMake with Qt / Kevin Funk (KDAB) Getting Started with CMake (1)CMake magic that enables Qt-specific behavior for .moc/.qrc/.ui

May 13th 202012 Using Modern CMake with Qt / Kevin Funk (KDAB)

Running CMake: Command line - contd

# In case you’d like to check which Qt version was found...

$ cd build

$ grep Qt5 CMakeCache.txt

//The directory containing a CMake configuration file for Qt5Core.Qt5Core_DIR:PATH=/usr/lib/x86_64-linux-gnu/cmake/Qt5Core//The directory containing a CMake configuration file for Qt5Gui.Qt5Gui_DIR:PATH=/usr/lib/x86_64-linux-gnu/cmake/Qt5Gui…

• In case Qt was NOT found, CMake will obviously complain

Page 11: Using Modern CMake with Qt - KDAB...9 May 13th 2020 Using Modern CMake with Qt / Kevin Funk (KDAB) Getting Started with CMake (1)CMake magic that enables Qt-specific behavior for .moc/.qrc/.ui

May 13th 202014 Using Modern CMake with Qt / Kevin Funk (KDAB)

Running CMake: Via QtCreator

• Simply open the top-level CMakeLists.txt• Go to File Open File or Project→• Select CMakeLists.txt, confirm

• QtCreator will ask you which Qt Kit to use

• Build the project as usual in QtCreator

• Benefits• Built-in CMake configuration GUI

• Built-in Qt Kit handling• Multiple Qt versions in parallel• Debug vs. Release builds, etc.

Page 12: Using Modern CMake with Qt - KDAB...9 May 13th 2020 Using Modern CMake with Qt / Kevin Funk (KDAB) Getting Started with CMake (1)CMake magic that enables Qt-specific behavior for .moc/.qrc/.ui

May 13th 202016 Using Modern CMake with Qt / Kevin Funk (KDAB)

CMake Qt Integration - contd

• With AUTOMOC/AUTORCC/AUTOUIC• No need for

• qt5_wrap_cpp(…)• qt5_wrap_ui(…)• qt5_add_resources(…)

• Simplifies CMake code!

• Also leads to faster overall builds(!)$ cat ./ssrc/icemon_autogen/mocs_compilation.cpp// This file is autogenerated. Changes will be overwritten.#include "EWIEGA46WW/moc_fakemonitor.cpp"#include "EWIEGA46WW/moc_hostinfo.cpp"#include "EWIEGA46WW/moc_icecreammonitor.cpp"

Page 13: Using Modern CMake with Qt - KDAB...9 May 13th 2020 Using Modern CMake with Qt / Kevin Funk (KDAB) Getting Started with CMake (1)CMake magic that enables Qt-specific behavior for .moc/.qrc/.ui

May 13th 202017 Using Modern CMake with Qt / Kevin Funk (KDAB)

CMake Qt Integration - contd

• Special casing regarding CMake AUTOMOC• Q_OBJECT or Q_GADGET based subclass in header?

• Nothing needs to be done• CMake will run moc on the header

• … inside a source file?• In that case add an #include "<basename>.moc” at the end of the source file• CMake will run moc on the source file instead

• Also looks for other Qt macros requiring moc, e.g. Q_PLUGIN_METADATA• List of macros-of-interest can be extended by the user

Page 14: Using Modern CMake with Qt - KDAB...9 May 13th 2020 Using Modern CMake with Qt / Kevin Funk (KDAB) Getting Started with CMake (1)CMake magic that enables Qt-specific behavior for .moc/.qrc/.ui

May 13th 2020 Using Modern CMake with Qt / Kevin Funk (KDAB)18

Special Cases

Page 15: Using Modern CMake with Qt - KDAB...9 May 13th 2020 Using Modern CMake with Qt / Kevin Funk (KDAB) Getting Started with CMake (1)CMake magic that enables Qt-specific behavior for .moc/.qrc/.ui

May 13th 202019 Using Modern CMake with Qt / Kevin Funk (KDAB)

Translations handling

(1) CMake functions for translation handling are inside the Qt LinguistTools module

(2) Call qt5_create_translations() on source code (.cpp and .ui files).

• Calls lupdate to generate or update .ts files ( in source dir)→

• Calls lrelease to generate .qm files ( in build dir)→

cmake_minimum_required(VERSION 3.10.0)

project(translation-demo)

# Business as usual, setup CMAKE_AUTOMOC, etc...

find_package(Qt5 COMPONENTS Widgets LinguistTools REQUIRED) ➀qt5_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} demo_de.ts demo_fr.ts) ➁add_executable(helloworld ... main.cpp ${QM_FILES}) ➂target_link_libraries(helloworld Qt5::Widgets)

Page 16: Using Modern CMake with Qt - KDAB...9 May 13th 2020 Using Modern CMake with Qt / Kevin Funk (KDAB) Getting Started with CMake (1)CMake magic that enables Qt-specific behavior for .moc/.qrc/.ui

May 13th 202020 Using Modern CMake with Qt / Kevin Funk (KDAB)

Translations handling - contd

• Notice that CMake rules are driving lupdate & lrelease automatically

• Generated .qm files can be loaded in the application using the QTranslator::load() function

# Building the project...

[2/7] Generating translations/demo_de.tsScanning directory '...cmake-qttranslations-example'...Updating 'translations/demo_de.ts'... Found 1 source text(s) (0 new and 1 already existing)[3/7] Generating translations/demo_fr.ts…

[4/7] Generating demo_de.qmUpdating '.../cmake-qttranslations-example/demo_de.qm'... Generated 0 translation(s) (0 finished and 0 unfinished) Ignored 1 untranslated source text(s)[5/7] Generating demo_fr.qm…

Page 17: Using Modern CMake with Qt - KDAB...9 May 13th 2020 Using Modern CMake with Qt / Kevin Funk (KDAB) Getting Started with CMake (1)CMake magic that enables Qt-specific behavior for .moc/.qrc/.ui

May 13th 202021 Using Modern CMake with Qt / Kevin Funk (KDAB)

Big resources handling

• You might need to embed large files into resources (QRCs)• For example: Databases, larger image assets, …

• But: compiler will likely fail with an “out of memory”• (numerous bug reports about this)

• Fix (new in Qt 5.12):• qt5_add_big_resources(…)

• CMake counterpart to QMake’s CONFIG+=resources_big

• Similar to qt5_add_resources(…), but directly generates object files instead of C++ code

Page 18: Using Modern CMake with Qt - KDAB...9 May 13th 2020 Using Modern CMake with Qt / Kevin Funk (KDAB) Getting Started with CMake (1)CMake magic that enables Qt-specific behavior for .moc/.qrc/.ui

May 13th 2020 Using Modern CMake with Qt / Kevin Funk (KDAB)22

General Recommendations

Page 19: Using Modern CMake with Qt - KDAB...9 May 13th 2020 Using Modern CMake with Qt / Kevin Funk (KDAB) Getting Started with CMake (1)CMake magic that enables Qt-specific behavior for .moc/.qrc/.ui

May 13th 202023 Using Modern CMake with Qt / Kevin Funk (KDAB)

General Recommendations

• Do not overuse global variables, “global” commands• Also do not overwrite vars like CMAKE_CXX_FLAGS, amend them!

• Avoid functions like include_directories(…), link_libraries(...)

• Embrace using targets and properties• Propagate properties where needed – using PUBLIC keyword

• This includes compile definitions, flags, include paths, etc.• Keep in mind: For a given target dependency chain A B C,→ →

properties set PUBLICly on target C “bubble” up to target A Useful!⇒• Avoids repetitive CMake code

Page 20: Using Modern CMake with Qt - KDAB...9 May 13th 2020 Using Modern CMake with Qt / Kevin Funk (KDAB) Getting Started with CMake (1)CMake magic that enables Qt-specific behavior for .moc/.qrc/.ui

May 13th 202024 Using Modern CMake with Qt / Kevin Funk (KDAB)

General Recommendations - contd

• Do not overuse file(GLOB ...)• It would be trivial to simply add all .cpp files:

• But: CMake needs to be re-run in case new .cpp files are added, otherwise the build system might simply ignore them – error prone!

• Better: List all files in the add_executable(…) or add_library(…) call

file(GLOB SRC_FILES ${PROJECT_SOURCE_DIR}/src/*.cpp)add_executable(myProject ${SRC_FILES})# … and done!

Page 21: Using Modern CMake with Qt - KDAB...9 May 13th 2020 Using Modern CMake with Qt / Kevin Funk (KDAB) Getting Started with CMake (1)CMake magic that enables Qt-specific behavior for .moc/.qrc/.ui

May 13th 202025 Using Modern CMake with Qt / Kevin Funk (KDAB)

General Recommendations - contd

• Improving CMake runtime performance• Consider switching to the Ninja generator

• Much simpler build system (compared to e.g. Visual Studio’s msbuild)• Thus easier and quicker to generate for CMake• Also the build tool itself is much more compact• Just reads a single file containing build instructions

• See also: https://blog.kitware.com/improving-cmakes-runtime-performance/

• Last but not least: Treat CMake like production code!• Keep it clean and also refactor when needed

Page 22: Using Modern CMake with Qt - KDAB...9 May 13th 2020 Using Modern CMake with Qt / Kevin Funk (KDAB) Getting Started with CMake (1)CMake magic that enables Qt-specific behavior for .moc/.qrc/.ui

May 13th 202026 Using Modern CMake with Qt / Kevin Funk (KDAB)

Resources

● Well-written intro to Modern CMake:● https://cliutils.gitlab.io/modern-cmake/

● Qt and CMake Whitepaper (brand new!)● https://www.kdab.com/wp-content/uploads/stories/KDAB-whitepaper-CMake.pdf

● Qt5 CMake Manual● https://doc.qt.io/qt-5/cmake-manual.html

Page 23: Using Modern CMake with Qt - KDAB...9 May 13th 2020 Using Modern CMake with Qt / Kevin Funk (KDAB) Getting Started with CMake (1)CMake magic that enables Qt-specific behavior for .moc/.qrc/.ui

May 13th 202027 Using Modern CMake with Qt / Kevin Funk (KDAB)

KDAB Services

Page 24: Using Modern CMake with Qt - KDAB...9 May 13th 2020 Using Modern CMake with Qt / Kevin Funk (KDAB) Getting Started with CMake (1)CMake magic that enables Qt-specific behavior for .moc/.qrc/.ui

May 13th 202028 Using Modern CMake with Qt / Kevin Funk (KDAB)

› Learn more at www.resources.qt.io › Try for Free at www.qt.io/download/

Qt World Summit 2020, Palm Springs, October 20-22www.qtworldsummit.com

Follow us: Website: www.kdab.comTwitter: @KDABQtLinkedin: /company/kdab/Youtube: /KDAB/My mail: [email protected]

Using Modern CMake with Qt / Kevin Funk (KDAB)28

Thank you!