Langage qmake
De nombreux fichiers de projet qmake décrivent simplement les sources et les fichiers d'en-tête utilisés par le projet, en utilisant une liste de définitions de name = value et name += value. qmake fournit également d'autres opérateurs, fonctions et champs d'application qui peuvent être utilisés pour traiter les informations fournies dans les déclarations de variables. Ces fonctionnalités avancées permettent de générer des Makefiles pour plusieurs plateformes à partir d'un seul fichier de projet.
Opérateurs
Dans de nombreux fichiers de projet, les opérateurs d'affectation (=) et d'ajout (+=) peuvent être utilisés pour inclure toutes les informations relatives à un projet. Le modèle d'utilisation typique consiste à assigner une liste de valeurs à une variable et à ajouter d'autres valeurs en fonction des résultats de divers tests. Comme qmake définit certaines variables en utilisant des valeurs par défaut, il est parfois nécessaire d'utiliser l'opérateur de suppression (-=) pour filtrer les valeurs qui ne sont pas nécessaires. Les sections suivantes décrivent comment utiliser les opérateurs pour manipuler le contenu des variables.
Attribution de valeurs
L'opérateur = affecte une valeur à une variable :
TARGET = myapp
La ligne ci-dessus attribue la valeur myapp à la variable TARGET, ce qui a pour effet d'écraser toutes les valeurs précédemment attribuées à TARGET par myapp.
Ajout de valeurs
L'opérateur += ajoute une nouvelle valeur à la liste des valeurs d'une variable :
DEFINES += USE_MY_STUFF
La ligne ci-dessus ajoute USE_MY_STUFF à la liste des définitions du pré-processeur à placer dans le Makefile généré.
Suppression de valeurs
L'opérateur -= supprime une valeur de la liste des valeurs d'une variable :
DEFINES -= USE_MY_STUFF
La ligne ci-dessus supprime USE_MY_STUFF de la liste des définitions du pré-processeur à placer dans le Makefile généré.
Ajout de valeurs uniques
L'opérateur *= ajoute une valeur à la liste des valeurs d'une variable, mais seulement si elle n'est pas déjà présente. Cela permet d'éviter que des valeurs soient incluses plusieurs fois dans une variable. Par exemple, dans la ligne ci-dessus,
DEFINES *= USE_MY_STUFF
Dans la ligne ci-dessus, USE_MY_STUFF ne sera ajouté à la liste des définitions du préprocesseur que s'il n'est pas déjà défini. Notez que la fonction unique() peut également être utilisée pour s'assurer qu'une variable ne contient qu'une seule instance de chaque valeur.
Remplacement des valeurs
L'opérateur ~= remplace toutes les valeurs qui correspondent à une expression régulière par la valeur spécifiée :
DEFINES ~= s/QT_[DT].+/QT
Dans la ligne ci-dessus, toutes les valeurs de la liste qui commencent par QT_D ou QT_T sont remplacées par QT.
Expansion de variables
L'opérateur $$ permet d'extraire le contenu d'une variable et peut être utilisé pour transmettre des valeurs entre variables ou les fournir à des fonctions :
EVERYTHING = $$SOURCES $$HEADERS
message("The project contains the following files:")
message($$EVERYTHING)Les variables peuvent être utilisées pour stocker le contenu des variables d'environnement. Celles-ci peuvent être évaluées au moment de l'exécution de qmake, ou incluses dans le Makefile généré pour être évaluées lors de la construction du projet.
Pour obtenir le contenu d'une valeur d'environnement lorsque qmake est exécuté, utilisez l'opérateur $$(...):
DESTDIR = $$(PWD) message(The project will be installed in $$DESTDIR)
Dans l'affectation ci-dessus, la valeur de la variable d'environnement PWD est lue lorsque le fichier de projet est traité.
Pour obtenir le contenu d'une valeur d'environnement au moment où le Makefile généré est traité, utilisez l'opérateur $(...):
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.)
Dans l'affectation ci-dessus, la valeur de PWD est lue immédiatement lorsque le fichier de projet est traité, mais $(PWD) est assigné à DESTDIR dans le Makefile généré. Cela rend le processus de construction plus flexible tant que la variable d'environnement est correctement définie lorsque le Makefile est traité.
Accès aux propriétés de qmake
L'opérateur spécial $$[...] peut être utilisé pour accéder aux propriétés de qmake :
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])
Pour plus d'informations, voir Configuration de qmake.
Les propriétés accessibles avec cet opérateur sont typiquement utilisées pour permettre à des plugins et composants tiers d'être intégrés dans Qt. Par exemple, un plugin Qt Widgets Designer peut être installé avec les plugins intégrés de Qt Widgets Designer si la déclaration suivante est faite dans son fichier de projet :
target.path = $$[QT_INSTALL_PLUGINS]/designer INSTALLS += target
Scopes
Les champs d'application sont similaires aux déclarations if dans les langages de programmation procéduraux. Si une certaine condition est remplie, les déclarations contenues dans la portée sont traitées.
Syntaxe des champs d'application
Les champs d'application se composent d'une condition suivie d'une accolade ouvrante sur la même ligne, d'une séquence de commandes et de définitions, et d'une accolade fermante sur une nouvelle ligne :
<condition> {
<command or definition>
...
}L'accolade ouvrante doit être écrite sur la même ligne que la condition. Les champs d'application peuvent être concaténés pour inclure plus d'une condition, comme décrit dans les sections suivantes.
Portées et conditions
Une portée s'écrit sous la forme d'une condition suivie d'une série de déclarations contenues dans une paire d'accolades. En voici un exemple :
win32 {
SOURCES += paintwidget_win.cpp
}Le code ci-dessus ajoutera le fichier paintwidget_win.cpp aux sources répertoriées dans le Makefile généré lors de la construction pour une plateforme Windows. Lors de la construction pour d'autres plates-formes, la définition sera ignorée.
Les conditions utilisées dans une portée donnée peuvent également être annulées pour fournir un ensemble alternatif de déclarations qui ne seront traitées que si la condition originale est fausse. Par exemple, pour traiter quelque chose lors de la construction pour toutes les plates-formes à l'exception de Windows, annulez la portée comme suit :
!win32 {
SOURCES -= paintwidget_win.cpp
}Les champs d'application peuvent être imbriqués pour combiner plusieurs conditions. Par exemple, pour inclure un fichier particulier pour une certaine plateforme uniquement si le débogage est activé, écrivez ce qui suit :
macx {
CONFIG(debug, debug|release) {
HEADERS += debugging.h
}
}Pour éviter d'écrire plusieurs champs d'application imbriqués, vous pouvez imbriquer les champs d'application à l'aide de l'opérateur :. Les portées imbriquées de l'exemple ci-dessus peuvent être réécrites de la manière suivante :
macx:CONFIG(debug, debug|release) {
HEADERS += debugging.h
}Vous pouvez également utiliser l'opérateur : pour effectuer des affectations conditionnelles sur une seule ligne. Par exemple :
win32:DEFINES += USE_MY_STUFF
La ligne ci-dessus ajoute USE_MY_STUFF à la variable DEFINES uniquement lors de la construction pour la plate-forme Windows. En règle générale, l'opérateur : se comporte comme un opérateur logique ET, réunissant un certain nombre de conditions et exigeant qu'elles soient toutes vraies.
Il existe également l'opérateur | qui agit comme un opérateur logique OR, en réunissant un certain nombre de conditions et en exigeant qu'une seule d'entre elles soit vraie.
win32|macx {
HEADERS += debugging.h
}Si vous devez mélanger les deux opérateurs, vous pouvez utiliser la fonction if pour spécifier la priorité de l'opérateur.
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).
}La condition accepte le caractère générique pour correspondre à une famille de valeurs CONFIG ou de noms de mkspec.
win32-* {
# Matches every mkspec starting with "win32-"
SOURCES += win32_specific.cpp
}Note : Historiquement, vérifier le nom du mkspec avec des caractères génériques comme ci-dessus était la façon dont qmake vérifiait la plate-forme. De nos jours, nous recommandons d'utiliser les valeurs définies par le mkspec dans la variable QMAKE_PLATFORM.
Vous pouvez également fournir des déclarations alternatives à celles d'une portée en utilisant une portée else. Chaque portée else est traitée si les conditions des portées précédentes sont fausses. Cela vous permet d'écrire des tests complexes lorsqu'ils sont combinés avec d'autres portées (séparées par l'opérateur : comme ci-dessus). En voici un exemple :
win32:xml {
message(Building for Windows)
SOURCES += xmlhandler_win.cpp
} else:xml {
SOURCES += xmlhandler.cpp
} else {
message("Unknown configuration")
}Configuration et champs d'application
Les valeurs stockées dans la variable CONFIG sont traitées spécialement par qmake. Chacune des valeurs possibles peut être utilisée comme condition pour une portée. Par exemple, la liste des valeurs contenues dans CONFIG peut être complétée par la valeur opengl:
CONFIG += opengl
À la suite de cette opération, toutes les portées qui testent opengl seront traitées. Nous pouvons utiliser cette fonctionnalité pour donner à l'exécutable final un nom approprié :
opengl {
TARGET = application-gl
} else {
TARGET = application
}Cette fonctionnalité permet de modifier facilement la configuration d'un projet sans perdre tous les paramètres personnalisés qui pourraient être nécessaires pour une configuration spécifique. Dans le code ci-dessus, les déclarations de la première portée sont traitées et l'exécutable final s'appelle application-gl. Toutefois, si opengl n'est pas spécifié, les déclarations de la deuxième portée sont traitées à la place, et l'exécutable final sera appelé application.
Comme il est possible de mettre vos propres valeurs sur la ligne CONFIG, vous disposez d'un moyen pratique de personnaliser les fichiers de projet et d'affiner les Makefiles générés.
Valeurs de l'étendue de la plate-forme
En plus des valeurs win32, macx, et unix utilisées dans de nombreuses conditions de portée, plusieurs autres valeurs intégrées spécifiques à la plate-forme et au compilateur peuvent être testées avec les portées. Celles-ci sont basées sur les spécifications de plate-forme fournies dans le répertoire mkspecs de Qt. Par exemple, les lignes suivantes d'un fichier de projet montrent la spécification actuelle utilisée et testent la spécification linux-g++:
message($$QMAKESPEC)
linux-g++ {
message(Linux)
}Vous pouvez effectuer des tests pour toute autre combinaison plate-forme-compilateur, à condition qu'une spécification existe pour celle-ci dans le répertoire mkspecs.
Variables
La plupart des variables utilisées dans les fichiers de projet sont des variables spéciales que qmake utilise lors de la génération des Makefiles, telles que DEFINES, SOURCES et HEADERS. En outre, vous pouvez créer des variables pour votre propre usage. qmake crée de nouvelles variables avec un nom donné lorsqu'il rencontre une affectation à ce nom. Par exemple, qmake crée de nouvelles variables avec un nom donné lorsqu'il rencontre une affectation à ce nom :
MY_VARIABLE = value
Il n'y a aucune restriction sur ce que vous faites de vos propres variables, car qmake les ignorera à moins qu'il n'ait besoin de les évaluer lors du traitement d'une portée.
Vous pouvez également assigner la valeur d'une variable courante à une autre variable en préfixant $$ au nom de la variable. Par exemple :
MY_DEFINES = $$DEFINES
La variable MY_DEFINES contient maintenant ce qui se trouve dans la variable DEFINES à ce stade du fichier de projet. Cela équivaut également à :
MY_DEFINES = $${DEFINES}La seconde notation vous permet d'ajouter le contenu de la variable à une autre valeur sans séparer les deux par un espace. Par exemple, ce qui suit garantit que l'exécutable final portera un nom qui inclut le modèle de projet utilisé :
TARGET = myproject_$${TEMPLATE}Remplacer les fonctions
qmake fournit une sélection de fonctions intégrées permettant de traiter le contenu des variables. Ces fonctions traitent les arguments qui leur sont fournis et renvoient une valeur, ou une liste de valeurs, comme résultat. Pour affecter un résultat à une variable, utilisez l'opérateur $$ avec ce type de fonction comme vous le feriez pour affecter le contenu d'une variable à une autre :
HEADERS = model.h HEADERS += $$OTHER_HEADERS HEADERS = $$unique(HEADERS)
Ce type de fonction doit être utilisé du côté droit des affectations (c'est-à-dire en tant qu'opérande).
Vous pouvez définir vos propres fonctions pour traiter le contenu des variables comme suit :
defineReplace(functionName){
#function code
}L'exemple de fonction suivant prend un nom de variable comme seul argument, extrait une liste de valeurs de la variable avec la fonction intégrée eval() et compile une liste de fichiers :
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)
}Fonctions de test
qmake fournit des fonctions intégrées qui peuvent être utilisées comme conditions lors de l'écriture des scopes. Ces fonctions ne renvoient pas de valeur, mais indiquent le succès ou l'échec:
count(options, 2) {
message(Both release and debug specified.)
}Ce type de fonction ne doit être utilisé que dans les expressions conditionnelles.
Il est possible de définir ses propres fonctions pour fournir des conditions aux champs d'application. L'exemple suivant teste l'existence de chaque fichier d'une liste et renvoie la valeur "true" si tous les fichiers existent, ou "false" dans le cas contraire :
defineTest(allFiles) {
files = $$ARGS
for(file, files) {
!exists($$file) {
return(false)
}
}
return(true)
}© 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.