qmake Sprache
Viele qmake-Projektdateien beschreiben einfach die vom Projekt verwendeten Quellen und Headerdateien, indem sie eine Liste von name = value
und name += value
Definitionen verwenden. qmake bietet auch andere Operatoren, Funktionen und Bereiche, die verwendet werden können, um die in den Variablendeklarationen enthaltenen Informationen zu verarbeiten. Diese erweiterten Funktionen ermöglichen es, Makefiles für mehrere Plattformen aus einer einzigen Projektdatei zu erzeugen.
Operatoren
In vielen Projektdateien können die Operatoren Zuweisung (=
) und Anhängen (+=
) verwendet werden, um alle Informationen über ein Projekt aufzunehmen. Das typische Anwendungsmuster besteht darin, einer Variablen eine Liste von Werten zuzuweisen und je nach dem Ergebnis verschiedener Tests weitere Werte anzuhängen. Da qmake bestimmte Variablen mit Standardwerten definiert, ist es manchmal notwendig, den Entfernungsoperator (-=
) zu verwenden, um Werte herauszufiltern, die nicht benötigt werden. In den folgenden Abschnitten wird beschrieben, wie Sie mit Hilfe von Operatoren den Inhalt von Variablen manipulieren können.
Zuweisung von Werten
Der Operator =
weist einer Variablen einen Wert zu:
TARGET = myapp
Die obige Zeile setzt die Variable TARGET auf myapp
. Dadurch werden alle zuvor für TARGET
gesetzten Werte mit myapp
überschrieben.
Anhängen von Werten
Der Operator +=
fügt einen neuen Wert an die Liste der Werte in einer Variablen an:
DEFINES += USE_MY_STUFF
Die obige Zeile fügt USE_MY_STUFF
an die Liste der Präprozessor-Definitionen an, die in das generierte Makefile aufgenommen werden sollen.
Entfernen von Werten
Der Operator -=
entfernt einen Wert aus der Liste der Werte in einer Variablen:
DEFINES -= USE_MY_STUFF
Die obige Zeile entfernt USE_MY_STUFF
aus der Liste der Präprozessor-Definitionen, die in das generierte Makefile eingefügt werden sollen.
Hinzufügen eindeutiger Werte
Der *=
-Operator fügt einen Wert zur Liste der Werte in einer Variablen hinzu, aber nur, wenn er nicht bereits vorhanden ist. Dadurch wird verhindert, dass Werte mehrfach in eine Variable aufgenommen werden. Ein Beispiel:
DEFINES *= USE_MY_STUFF
In der obigen Zeile wird USE_MY_STUFF
nur dann zur Liste der Präprozessor-Definitionen hinzugefügt, wenn er nicht bereits definiert ist. Beachten Sie, dass die Funktion unique() auch verwendet werden kann, um sicherzustellen, dass eine Variable nur eine Instanz jedes Wertes enthält.
Ersetzen von Werten
Der Operator ~=
ersetzt alle Werte, die mit einem regulären Ausdruck übereinstimmen, durch den angegebenen Wert:
DEFINES ~= s/QT_[DT].+/QT
In der obigen Zeile werden alle Werte in der Liste, die mit QT_D
oder QT_T
beginnen, durch QT
ersetzt.
Variablenerweiterung
Der Operator $$
wird verwendet, um den Inhalt einer Variablen zu extrahieren, und kann verwendet werden, um Werte zwischen Variablen zu übergeben oder sie an Funktionen zu liefern:
EVERYTHING = $$SOURCES $$HEADERS message("The project contains the following files:") message($$EVERYTHING)
Variablen können verwendet werden, um den Inhalt von Umgebungsvariablen zu speichern. Diese können zum Zeitpunkt der Ausführung von qmake ausgewertet werden oder in das generierte Makefile aufgenommen werden, um bei der Erstellung des Projekts ausgewertet zu werden.
Um den Inhalt einer Umgebungsvariablen zu erhalten, wenn qmake läuft, verwenden Sie den $$(...)
Operator:
DESTDIR = $$(PWD) message(The project will be installed in $$DESTDIR)
In der obigen Zuweisung wird der Wert der Umgebungsvariablen PWD
gelesen, wenn die Projektdatei verarbeitet wird.
Um den Inhalt eines Umgebungswertes zum Zeitpunkt der Verarbeitung des generierten Makefiles zu erhalten, verwenden Sie den $(...)
Operator:
DESTDIR = $$(PWD) message(The project will be installed in $$DESTDIR) DESTDIR = $(PWD) message(The project will be installed in the value of PWD) message(when the Makefile is processed.)
In der obigen Zuweisung wird der Wert von PWD
sofort gelesen, wenn die Projektdatei verarbeitet wird, aber $(PWD)
wird im generierten Makefile DESTDIR
zugewiesen. Dies macht den Build-Prozess flexibler, solange die Umgebungsvariable bei der Verarbeitung des Makefiles korrekt gesetzt ist.
Zugriff auf qmake-Eigenschaften
Der spezielle $$[...]
Operator kann verwendet werden, um auf qmake-Eigenschaften zuzugreifen:
message(Qt version: $$[QT_VERSION]) message(Qt is installed in $$[QT_INSTALL_PREFIX]) message(Qt resources can be found in the following locations:) message(Documentation: $$[QT_INSTALL_DOCS]) message(Header files: $$[QT_INSTALL_HEADERS]) message(Libraries: $$[QT_INSTALL_LIBS]) message(Binary files (executables): $$[QT_INSTALL_BINS]) message(Plugins: $$[QT_INSTALL_PLUGINS]) message(Data files: $$[QT_INSTALL_DATA]) message(Translation files: $$[QT_INSTALL_TRANSLATIONS]) message(Settings: $$[QT_INSTALL_CONFIGURATION]) message(Examples: $$[QT_INSTALL_EXAMPLES])
Weitere Informationen finden Sie unter Konfigurieren von qmake.
Die Eigenschaften, auf die mit diesem Operator zugegriffen werden kann, werden typischerweise verwendet, um die Integration von Plugins und Komponenten von Drittanbietern in Qt zu ermöglichen. Zum Beispiel kann ein Qt Widgets Designer Plugin zusammen mit Qt Widgets Designer's eingebauten Plugins installiert werden, wenn die folgende Deklaration in seiner Projektdatei gemacht wird:
target.path = $$[QT_INSTALL_PLUGINS]/designer INSTALLS += target
Scopes
Scopes sind vergleichbar mit if
Anweisungen in prozeduralen Programmiersprachen. Wenn eine bestimmte Bedingung erfüllt ist, werden die Deklarationen innerhalb des Scopes abgearbeitet.
Scope-Syntax
Scopes bestehen aus einer Bedingung, gefolgt von einer öffnenden geschweiften Klammer in derselben Zeile, einer Folge von Befehlen und Definitionen und einer schließenden geschweiften Klammer in einer neuen Zeile:
<condition> { <command or definition> ... }
Die öffnende geschweifte Klammer muss in dieselbe Zeile wie die Bedingung geschrieben werden. Bereiche können verkettet werden, um mehr als eine Bedingung zu enthalten, wie in den folgenden Abschnitten beschrieben.
Bereiche und Bedingungen
Ein Bereich wird als Bedingung geschrieben, gefolgt von einer Reihe von Deklarationen, die in einem Paar geschweifter Klammern enthalten sind. Ein Beispiel:
win32 { SOURCES += paintwidget_win.cpp }
Der obige Code fügt die Datei paintwidget_win.cpp
zu den im generierten Makefile aufgelisteten Quellen hinzu, wenn er für eine Windows-Plattform erstellt wird. Bei der Erstellung für andere Plattformen wird die Definition ignoriert.
Die in einem bestimmten Bereich verwendeten Bedingungen können auch negiert werden, um einen alternativen Satz von Deklarationen bereitzustellen, die nur verarbeitet werden, wenn die ursprüngliche Bedingung falsch ist. Um zum Beispiel etwas zu verarbeiten, wenn es für alle Plattformen außer Windows erstellt wird, negieren Sie den Bereich wie folgt:
!win32 { SOURCES -= paintwidget_win.cpp }
Bereiche können verschachtelt werden, um mehr als eine Bedingung zu kombinieren. Um beispielsweise eine bestimmte Datei für eine bestimmte Plattform nur dann einzubinden, wenn das Debugging aktiviert ist, schreiben Sie Folgendes:
macx { CONFIG(debug, debug|release) { HEADERS += debugging.h } }
Um sich das Schreiben vieler verschachtelter Bereiche zu sparen, können Sie Bereiche mit dem Operator :
verschachteln. Die verschachtelten Bereiche im obigen Beispiel können auf folgende Weise umgeschrieben werden:
macx:CONFIG(debug, debug|release) { HEADERS += debugging.h }
Sie können auch den :
Operator verwenden, um einzeilige bedingte Zuweisungen durchzuführen. Ein Beispiel:
win32:DEFINES += USE_MY_STUFF
Die obige Zeile fügt der DEFINES-Variablen USE_MY_STUFF
nur bei der Erstellung für die Windows-Plattform hinzu. Im Allgemeinen verhält sich der Operator :
wie ein logischer UND-Operator, der eine Reihe von Bedingungen miteinander verknüpft und verlangt, dass alle wahr sind.
Es gibt auch den Operator |
, der sich wie ein logischer ODER-Operator verhält und mehrere Bedingungen miteinander verknüpft, von denen nur eine wahr sein muss.
win32|macx { HEADERS += debugging.h }
Wenn Sie beide Operatoren mischen müssen, können Sie die Funktion if
verwenden, um den Vorrang der Operatoren festzulegen.
if(win32|macos):CONFIG(debug, debug|release) { # Do something on Windows and macOS, # but only for the debug configuration. } win32|if(macos:CONFIG(debug, debug|release)) { # Do something on Windows (regardless of debug or release) # and on macOS (only for debug). }
Die Bedingung akzeptiert das Platzhalterzeichen, um mit einer Familie von CONFIG
Werten oder mkspec-Namen übereinzustimmen.
win32-* { # Matches every mkspec starting with "win32-" SOURCES += win32_specific.cpp }
Hinweis: Historisch gesehen war die Überprüfung des mkspec-Namens mit Platzhaltern wie oben der Weg von qmake, die Plattform zu überprüfen. Heutzutage empfehlen wir, Werte zu verwenden, die durch die mkspec in der QMAKE_PLATFORM
Variable definiert sind.
Sie können auch alternative Deklarationen zu denen innerhalb eines Bereichs angeben, indem Sie einen else
Bereich verwenden. Jeder Bereich else
wird abgearbeitet, wenn die Bedingungen für die vorangehenden Bereiche falsch sind. Auf diese Weise können Sie komplexe Tests schreiben, wenn Sie sie mit anderen Bereichen kombinieren (wie oben durch den Operator :
getrennt). Ein Beispiel:
win32:xml { message(Building for Windows) SOURCES += xmlhandler_win.cpp } else:xml { SOURCES += xmlhandler.cpp } else { message("Unknown configuration") }
Konfiguration und Bereiche
Die in der CONFIG Variable gespeicherten Werte werden von qmake speziell behandelt. Jeder der möglichen Werte kann als Bedingung für einen Bereich verwendet werden. Zum Beispiel kann die Liste der Werte, die CONFIG
enthält, um den Wert opengl
erweitert werden:
CONFIG += opengl
Als Ergebnis dieser Operation werden alle Bereiche, die auf opengl
testen, verarbeitet. Wir können diese Funktion verwenden, um der endgültigen ausführbaren Datei einen geeigneten Namen zu geben:
opengl { TARGET = application-gl } else { TARGET = application }
Diese Funktion macht es einfach, die Konfiguration für ein Projekt zu ändern, ohne alle benutzerdefinierten Einstellungen zu verlieren, die für eine bestimmte Konfiguration erforderlich sein könnten. Im obigen Code werden die Deklarationen im ersten Bereich verarbeitet, und die endgültige ausführbare Datei wird application-gl
genannt. Wenn jedoch opengl
nicht angegeben ist, werden stattdessen die Deklarationen im zweiten Bereich verarbeitet, und die endgültige ausführbare Datei wird application
genannt.
Da es möglich ist, eigene Werte in die Zeile CONFIG
einzutragen, bietet dies eine bequeme Möglichkeit zur Anpassung von Projektdateien und zur Feinabstimmung der generierten Makefiles.
Werte für den Plattformbereich
Zusätzlich zu den Werten win32
, macx
und unix
, die in vielen Scope-Bedingungen verwendet werden, können verschiedene andere eingebaute plattform- und compilerspezifische Werte mit Scopes getestet werden. Diese basieren auf den Plattformspezifikationen, die im mkspecs
Verzeichnis von Qt bereitgestellt werden. Die folgenden Zeilen aus einer Projektdatei zeigen zum Beispiel die aktuell verwendete Spezifikation und testen auf die Spezifikation linux-g++
:
message($$QMAKESPEC) linux-g++ { message(Linux) }
Sie können für jede andere Plattform-Compiler-Kombination testen, solange eine Spezifikation für diese im Verzeichnis mkspecs
existiert.
Variablen
Viele der in den Projektdateien verwendeten Variablen sind spezielle Variablen, die qmake bei der Erzeugung von Makefiles verwendet, wie z.B. DEFINES, SOURCES und HEADERS. Außerdem können Sie Variablen für Ihren eigenen Gebrauch erstellen. qmake erstellt neue Variablen mit einem bestimmten Namen, wenn es auf eine Zuweisung zu diesem Namen trifft. Ein Beispiel:
MY_VARIABLE = value
Es gibt keine Einschränkungen, was Sie mit Ihren eigenen Variablen machen, da qmake sie ignoriert, es sei denn, es muss sie bei der Verarbeitung eines Bereichs auswerten.
Sie können auch den Wert einer aktuellen Variablen einer anderen Variablen zuweisen, indem Sie dem Variablennamen $$ voranstellen. Zum Beispiel:
MY_DEFINES = $$DEFINES
Die Variable MY_DEFINES enthält nun den Wert der Variable DEFINES an dieser Stelle in der Projektdatei. Dies ist auch äquivalent zu:
MY_DEFINES = $${DEFINES}
Die zweite Schreibweise ermöglicht es Ihnen, den Inhalt der Variablen an einen anderen Wert anzuhängen, ohne die beiden durch ein Leerzeichen zu trennen. Die folgende Schreibweise stellt zum Beispiel sicher, dass die endgültige ausführbare Datei einen Namen erhält, der die verwendete Projektvorlage enthält:
TARGET = myproject_$${TEMPLATE}
Ersetzen von Funktionen
qmake bietet eine Auswahl an eingebauten Funktionen, mit denen der Inhalt von Variablen verarbeitet werden kann. Diese Funktionen verarbeiten die ihnen übergebenen Argumente und geben als Ergebnis einen Wert oder eine Liste von Werten zurück. Um ein Ergebnis einer Variablen zuzuweisen, verwenden Sie den $$
Operator mit diesem Funktionstyp, so wie Sie den Inhalt einer Variablen einer anderen zuweisen würden:
HEADERS = model.h HEADERS += $$OTHER_HEADERS HEADERS = $$unique(HEADERS)
Dieser Funktionstyp sollte auf der rechten Seite von Zuweisungen (d. h. als Operand) verwendet werden.
Sie können Ihre eigenen Funktionen für die Verarbeitung des Inhalts von Variablen wie folgt definieren:
defineReplace(functionName){ #function code }
Die folgende Beispielfunktion nimmt einen Variablennamen als einziges Argument, extrahiert mit der eingebauten Funktion eval() eine Liste von Werten aus der Variable und kompiliert eine Liste von Dateien:
defineReplace(headersAndSources) { variable = $$1 names = $$eval($$variable) headers = sources = for(name, names) { header = $${name}.h exists($$header) { headers += $$header } source = $${name}.cpp exists($$source) { sources += $$source } } return($$headers $$sources) }
Testfunktionen
qmake bietet eingebaute Funktionen, die als Bedingungen beim Schreiben von Bereichen verwendet werden können. Diese Funktionen geben keinen Wert zurück, sondern zeigen stattdessen Erfolg oder Misserfolg an:
count(options, 2) { message(Both release and debug specified.) }
Diese Art von Funktionen sollte nur in bedingten Ausdrücken verwendet werden.
Es ist möglich, eigene Funktionen zu definieren, um Bedingungen für Scopes zu erstellen. Das folgende Beispiel prüft, ob jede Datei in einer Liste existiert und gibt true zurück, wenn sie alle existieren, oder false, wenn nicht:
defineTest(allFiles) { files = $$ARGS for(file, files) { !exists($$file) { return(false) } } return(true) }
© 2025 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.