Erste Schritte mit CMake
CMake ist eine Sammlung von Werkzeugen, mit denen sich Anwendungen erstellen, testen und verpacken lassen. Genau wie Qt ist es auf allen gängigen Entwicklungsplattformen verfügbar. Es wird zudem von verschiedenen IDEs unterstützt, darunter Qt Creator und Visual Studio Code.
In diesem Abschnitt zeigen wir Ihnen die grundlegendste Vorgehensweise, um Qt in einem CMake-Projekt zu verwenden. Zunächst erstellen wir eine einfache Konsolenanwendung. Anschließend erweitern wir das Projekt zu einer GUI-Anwendung, die Qt Widgets.
Wenn Sie wissen möchten, wie Sie ein bestehendes CMake-Projekt mit Qt erstellen, lesen Sie die Dokumentation zur Erstellung von Projekten mit CMake über die Befehlszeile.
Um die Grundlagen für den Einstieg in CMake zu erlernen, belegen Sie den Kurs „Building with CMake: Getting Started with CMake and Qt“ in der Qt Academy.
Erstellen einer C++-Konsolenanwendung
Ein „ CMake “-Projekt wird durch Dateien definiert, die in der Sprache CMake geschrieben sind. Die Hauptdatei heißt „ CMakeLists.txt “ und befindet sich in der Regel im selben Verzeichnis wie die eigentlichen Programmquelldateien.
Hier ist eine typische „ CMakeLists.txt “-Datei für eine Konsolenanwendung, die in C++ unter Verwendung von Qt geschrieben wurde:
cmake_minimum_required(VERSION 3.16)
project(helloworld VERSION 1.0.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Qt6 REQUIRED COMPONENTS Core)
qt_standard_project_setup()
qt_add_executable(helloworld
main.cpp
)
target_link_libraries(helloworld PRIVATE Qt6::Core)Sehen wir uns den Inhalt einmal genauer an.
cmake_minimum_required(VERSION 3.16)cmake_minimum_required() Gibt die Mindestversion von CMake an, die für die erfolgreiche Konfiguration des Projekts erforderlich ist. Informationen zur von Qt benötigten Mindestversion findest du unter „Unterstützte CMake-Versionen “.
project(helloworld VERSION 1.0.0 LANGUAGES CXX)project() Legt einen Projektnamen und die Standard-Projektversion fest. Das Argument „ LANGUAGES “ teilt CMake mit, dass das Programm in C++ geschrieben ist.
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)Qt 6 erfordert einen Compiler, der C++ Version 17 oder neuer unterstützt. Wenn Sie dies durch die Einstellung der Variablen ` CMAKE_CXX_STANDARD` und ` CMAKE_CXX_STANDARD_REQUIRED ` erzwingen, gibt CMake eine Fehlermeldung aus, falls der Compiler zu alt ist.
find_package(Qt6 REQUIRED COMPONENTS Core)Dadurch wird CMake angewiesen, nach Qt 6 zu suchen und das Modul „ Core “ bereitzustellen. Es macht keinen Sinn, fortzufahren, wenn „ CMake “ das Modul nicht finden kann. Daher setzen wir das Flag „ REQUIRED “, damit CMake in diesem Fall den Vorgang abbricht. Weitere Informationen finden Sie unter „Qt in CMake-Projekten verfügbar machen“.
Bei Erfolg setzt das Modul einige CMake-Variablen, die unter „Modulvariablen“ dokumentiert sind. Außerdem importiert es das Ziel „ Qt6::Core “, das wir im Folgenden verwenden.
qt_standard_project_setup()Der Befehl ` qt_standard_project_setup()` legt projektweite Standardwerte für eine typische Qt-Anwendung fest.
Unter anderem setzt dieser Befehl die Variable „ CMAKE_AUTOMOC “ auf „ ON “, wodurch CMake angewiesen wird, Regeln automatisch so einzurichten, dass der Qt-Meta-Object Compiler er (moc) bei Bedarf transparent aufgerufen wird.
Einzelheiten finden Sie in der Referenz zu ` qt_standard_project_setup()`.
qt_add_executable(helloworld
main.cpp
)qt_add_executable() teilt CMake mit, dass wir eine ausführbare Datei (also keine Bibliothek) namens „ helloworld “ als Ziel erstellen möchten. Es handelt sich um einen Wrapper um den integrierten Befehl „ add_executable() “ und bietet zusätzliche Logik zur automatischen Abwicklung von Vorgängen wie dem Verknüpfen von Qt-Plugins in statischen Qt-Builds, der plattformspezifischen Anpassung von Bibliotheksnamen und so weiter.
Das Ziel sollte aus der C++-Quelldatei ` main.cpp` erstellt werden.
In der Regel werden hier keine Header-Dateien aufgeführt. Dies unterscheidet sich von qmake, wo Header-Dateien explizit aufgeführt werden müssen, damit sie von Meta-Object Compiler (moc) verarbeitet werden.
Informationen zum Erstellen von Bibliotheken finden Sie unter qt_add_library().
target_link_libraries(helloworld PRIVATE Qt6::Core)Schließlich teilt „ target_link_libraries “ CMake mit, dass die ausführbare Datei „ helloworld “ Qt Core , indem auf das Ziel ` Qt6::Core ` verwiesen wird, das durch den obigen Aufruf von ` find_package() ` importiert wurde. Dadurch werden nicht nur die richtigen Argumente an den Linker übergeben, sondern es wird auch sichergestellt, dass die richtigen Include-Verzeichnisse und Compiler-Definitionen an den C++-Compiler übergeben werden. Das Schlüsselwort „ PRIVATE “ ist für ein ausführbares Ziel zwar nicht zwingend erforderlich, es hat sich jedoch bewährt, es anzugeben. Wäre „ helloworld “ eine Bibliothek statt einer ausführbaren Datei, müsste entweder „ PRIVATE “ oder „ PUBLIC “ angegeben werden („PUBLIC “, wenn die Bibliothek in ihren Headern etwas aus „ Qt6::Core “ erwähnt, andernfalls „ PRIVATE “).
Erstellen einer C++-GUI-Anwendung
Im letzten Abschnitt haben wir die Datei „CMakeLists.txt“ für eine einfache Konsolenanwendung gezeigt. Wir werden nun eine GUI-Anwendung erstellen, die das Qt Widgets Modul verwendet.
Hier ist die vollständige Projektdatei:
cmake_minimum_required(VERSION 3.16)
project(helloworld VERSION 1.0.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Qt6 REQUIRED COMPONENTS Widgets)
qt_standard_project_setup()
qt_add_executable(helloworld
mainwindow.ui
mainwindow.cpp
main.cpp
)
target_link_libraries(helloworld PRIVATE Qt6::Widgets)
set_target_properties(helloworld PROPERTIES
WIN32_EXECUTABLE ON
MACOSX_BUNDLE ON
)Lassen Sie uns die vorgenommenen Änderungen gemeinsam durchgehen.
find_package(Qt6 REQUIRED COMPONENTS Widgets)Im Aufruf von „ find_package “ ersetzen wir „ Core “ durch „ Widgets “. Dadurch wird das Modul „ Qt6Widgets “ gefunden und die Ziele „ Qt6::Widgets “ bereitgestellt, gegen die wir später verknüpfen.
qt_standard_project_setup()Zusätzlich zu ` CMAKE_AUTOMOC` setzt `qt_standard_project_setup()` die Variable ` CMAKE_AUTOUIC ` auf ` ON`. Dadurch werden automatisch Regeln erstellt, um Qt's „User Interface Compiler “ (uic) auf die Quelldateien unter ` .ui ` anzuwenden.
qt_add_executable(helloworld
mainwindow.ui
mainwindow.cpp
main.cpp
)Wir fügen eine „Qt Widgets “-Designer-Datei (mainwindow.ui) und die dazugehörige C++-Quelldatei (mainwindow.cpp) zu den Quellen des Anwendungsziels hinzu.
Hinweis: Eineweitere Möglichkeit, „ .ui “-Dateien zu Ihrem Projekt hinzuzufügen, besteht darin, anstelle von „ AUTOUIC “ den Befehl „qt_add_ui()“ zu verwenden.
target_link_libraries(helloworld PRIVATE Qt6::Widgets)Im Befehl „ target_link_libraries “ verknüpfen wir mit „ Qt6::Widgets “ anstelle von „ Qt6::Core “. Beachten Sie, dass die Anwendung weiterhin mit „ Qt6::Core “ verknüpft wird, da „ Qt6::Widgets “ davon abhängt.
set_target_properties(helloworld PROPERTIES
WIN32_EXECUTABLE ON
MACOSX_BUNDLE ON
)Abschließend legen wir Eigenschaften für unser Anwendungsziel fest, die folgende Auswirkungen haben:
- Verhindern, dass unter Windows ein Konsolenfenster erstellt wird.
- Erstellen eines Anwendungsbundles unter macOS.
Weitere Informationen zu diesen Ziel-Eigenschaften finden Sie in der CMake-Dokumentation.
Projektstrukturierung
Projekte, die mehr als nur ein Ziel enthalten, profitieren von einer übersichtlichen Struktur der Projektdateien. Wir werden die Unterverzeichnis-Funktion von CMake nutzen.
Da wir planen, das Projekt um weitere Ziele zu erweitern, verschieben wir die Quelldateien der Anwendung in ein Unterverzeichnis und erstellen dort eine neue Datei „ CMakeLists.txt “.
<project root>
├── CMakeLists.txt
└── src
└── app
├── CMakeLists.txt
├── main.cpp
├── mainwindow.cpp
├── mainwindow.h
└── mainwindow.uiDie „ CMakeLists.txt “-Datei auf oberster Ebene enthält die allgemeinen Projekteinstellungen sowie die Aufrufe von „ find_package “ und „ add_subdirectory “:
cmake_minimum_required(VERSION 3.16)
project(helloworld VERSION 1.0.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Qt6 REQUIRED COMPONENTS Widgets)
qt_standard_project_setup()
add_subdirectory(src/app)Variablen, die in dieser Datei festgelegt werden, sind in den Projektdateien der Unterverzeichnisse sichtbar.
Die Projektdatei der Anwendung „ src/app/CMakeLists.txt “ enthält das ausführbare Ziel:
qt_add_executable(helloworld
mainwindow.ui
mainwindow.cpp
main.cpp
)
target_link_libraries(helloworld PRIVATE Qt6::Widgets)
set_target_properties(helloworld PROPERTIES
WIN32_EXECUTABLE ON
MACOSX_BUNDLE ON
)Eine solche Struktur erleichtert das Hinzufügen weiterer Ziele zum Projekt, wie beispielsweise Bibliotheken oder Unit-Tests.
Hinweis: Fügen Sie das Build-Verzeichnis Ihres Projekts zur Liste der ausgeschlossenen Verzeichnisse aller auf Ihrem System laufenden Antivirenprogrammehinzu .
Bibliotheken erstellen
Wenn das Projekt wächst, möchten Sie möglicherweise Teile Ihres Anwendungscodes in eine Bibliothek auslagern, die von der Anwendung und möglicherweise auch von Unit-Tests verwendet wird. In diesem Abschnitt wird gezeigt, wie Sie eine solche Bibliothek erstellen.
Unsere Anwendung enthält derzeit Geschäftslogik direkt in der Datei „ main.cpp “. Wir extrahieren den Code in eine neue statische Bibliothek namens „ businesslogic “ im Unterverzeichnis „ "src/businesslogic" “, wie im vorherigen Abschnitt erläutert.
Der Einfachheit halber besteht die Bibliothek nur aus einer einzigen C++-Quelldatei und der dazugehörigen Header-Datei, die von der Datei „ main.cpp “ der Anwendung eingebunden wird:
<project root>
├── CMakeLists.txt
└── src
├── app
│ ├── ...
│ └── main.cpp
└── businesslogic
├── CMakeLists.txt
├── businesslogic.cpp
└── businesslogic.hWerfen wir einen Blick auf die Projektdatei der Bibliothek (src/businesslogic/CMakeLists.txt).
qt_add_library(businesslogic STATIC
businesslogic.cpp
)
target_link_libraries(businesslogic PRIVATE Qt6::Core)
target_include_directories(businesslogic INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})Gehen wir den Inhalt einmal durch.
qt_add_library(businesslogic STATIC
businesslogic.cpp
)Der Befehl ` add_library` erstellt die Bibliothek „ businesslogic “. Später werden wir die Anwendung mit diesem Ziel verknüpfen.
Das Schlüsselwort „ STATIC “ bezeichnet eine statische Bibliothek. Wenn wir eine gemeinsam genutzte oder dynamische Bibliothek erstellen wollten, würden wir das Schlüsselwort „ SHARED “ verwenden.
target_link_libraries(businesslogic PRIVATE Qt6::Core)Wir haben eine statische Bibliothek und müssen eigentlich keine anderen Bibliotheken verknüpfen. Da unsere Bibliothek jedoch Klassen aus QtCore verwendet, fügen wir eine Verknüpfungsabhängigkeit zu Qt6::Core hinzu. Dadurch werden die erforderlichen Include-Pfade für QtCore und die Präprozessor-Definitionen eingebunden.
target_include_directories(businesslogic INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})Die API der Bibliothek ist in der Header-Datei businesslogic/businesslogic.h definiert. Durch den Aufruf von `target_include_directories` stellen wir sicher, dass der absolute Pfad zum Verzeichnis businesslogic automatisch als Include-Pfad zu allen Zielen hinzugefügt wird, die unsere Bibliothek verwenden.
Dadurch sind wir in „ main.cpp “ nicht mehr darauf angewiesen, relative Pfade zu verwenden, um „ businesslogic.h “ zu finden. Stattdessen können wir einfach schreiben
#include <businesslogic.h>Zuletzt müssen wir das Unterverzeichnis der Bibliothek zur Projektdatei auf oberster Ebene hinzufügen:
add_subdirectory(src/app)
add_subdirectory(src/businesslogic)Verwendung von Bibliotheken
Um die im vorherigen Abschnitt erstellte Bibliothek zu verwenden, weisen wir CMake an, eine Verknüpfung mit ihr herzustellen:
target_link_libraries(helloworld PRIVATE
businesslogic
Qt6::Widgets
)Dadurch wird sichergestellt, dass „ businesslogic.h “ beim Kompilieren von „main.cpp“ gefunden wird. Außerdem wird die statische Bibliothek „businesslogic“ Teil der ausführbaren Datei „ helloworld “.
In CMake-Begriffen legt die Bibliothek „ businesslogic “ Nutzungsanforderungen (den Include-Pfad) fest, die jeder Nutzer unserer Bibliothek (die Anwendung) erfüllen muss. Der Befehl „ target_link_libraries “ sorgt dafür.
Ressourcen hinzufügen
Wir möchten in unserer Anwendung einige Bilder anzeigen und fügen diese daher mithilfe des Qt-Ressourcensystems hinzu.
qt_add_resources(helloworld imageresources
PREFIX "/images"
FILES logo.png splashscreen.png
)Der Befehl `qt_add_resources()` erstellt automatisch eine Qt-Ressource, die die referenzierten Bilder enthält. Im C++-Quellcode können Sie auf die Bilder zugreifen, indem Sie das angegebene Ressourcenpräfix voranstellen:
logoLabel->setPixmap(QPixmap(":/images/logo.png"));Der Befehl `qt_add_resources()` erwartet als erstes Argument entweder einen Variablennamen oder einen Zielnamen. Wir empfehlen, die zielbasierte Variante dieses Befehls zu verwenden, wie im obigen Beispiel gezeigt.
Übersetzungen hinzufügen
Übersetzungen von Zeichenketten in einem Qt-Projekt werden in „ .ts “-Dateien kodiert. Diese „ .ts “-Dateien werden zu binären „ .qm “-Dateien kompiliert, die dann von der Qt-Anwendung zur Laufzeit geladen werden. Weitere Informationen finden Sie unter „Internationalisierung mit Qt “.
In diesem Abschnitt wird beschrieben, wie Sie der Anwendung „ helloworld “ eine deutsche und eine französische Übersetzung hinzufügen.
Geben Sie beide Sprachen mit ` qt_standard_project_setup()` an:
qt_standard_project_setup(I18N_TRANSLATED_LANGUAGES de fr)Rufen Sie anschließend `qt_add_translations()` für das Ziel auf, das die „ .qm “-Dateien laden soll:
qt_add_translations(helloworld)Bei der ersten Konfiguration erstellt dieser Befehl die Dateien „ helloworld_de.ts “ und „ helloworld_fr.ts “ im Quellverzeichnis des Projekts. Diese Dateien enthalten die übersetzten Zeichenfolgen und sollten unter Versionskontrolle gestellt werden.
Der Befehl erstellt außerdem Regeln für das Build-System, um automatisch „ .qm “-Dateien aus den „ .ts “-Dateien zu generieren. Standardmäßig werden die „ .qm “-Dateien in eine Ressource eingebettet und sind unter dem Ressourcenpräfix „ "/i18n" “ zugänglich.
Um die Einträge in der Datei „ .ts “ zu aktualisieren, erstellen Sie das Ziel „ update_translations “:
$ cmake --build . --target update_translationsUm die Generierung der „ .qm “-Dateien manuell auszulösen, bauen Sie das Ziel „ release_translations “:
$ cmake --build . --target release_translationsWeitere Informationen dazu, wie Sie die Handhabung von „ .ts “-Dateien und deren Einbettung in eine Ressource beeinflussen können, finden Sie in der Dokumentation zu „qt_add_translations“.
Der Befehl `qt_add_translations() ` ist ein Komfort-Wrapper. Für eine detailliertere Steuerung der Verarbeitung von ` .ts `- und ` .qm `-Dateien verwenden Sie die zugrunde liegenden Befehle `qt_add_lupdate() ` und `qt_add_lrelease()`.
Weiterführende Literatur
Die offizielle CMake-Dokumentation ist eine unschätzbare Quelle für die Arbeit mit CMake.
Das offizielle CMake-Tutorial behandelt gängige Aufgaben im Zusammenhang mit dem Build-System.
Das Buch „Professional CMake: A Practical Guide“ bietet eine hervorragende Einführung in die wichtigsten CMake-Funktionen.
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.