Sur cette page

qt_add_protobuf

Génère du code source C++ basé sur Qt en utilisant un schéma protobuf.

La commande est définie dans le composant Protobuf du paquetage Qt6. Charger le paquet avec :

find_package(Qt6 REQUIRED COMPONENTS Protobuf)

Cette commande a été introduite dans Qt 6.5.

Utilisez qt_add_protobuf pour invoquer qtprotobufgen dans vos scripts CMake et générer le code à partir des schémas .proto pour vos projets.qtprotobufgen serait invoqué par CMake en utilisant la commande qt_add_protobuf.

Synopsis

qt_add_protobuf(<target>
    PROTO_FILES <file> ...
    [PROTO_INCLUDES <path> ...]
    [QML [QML_URI <uri>]]
    [OUTPUT_DIRECTORY <dir>]
    [GENERATE_PACKAGE_SUBFOLDERS]
    [COPY_COMMENTS]
    [EXPORT_MACRO <infix>]
    [OUTPUT_HEADERS <var>]
    [OUTPUT_TARGETS <var>]
    [HEADER_GUARD <pragma|filename>]
    [GENERATE_NON_FINAL_MESSAGES]
)

Si les commandes sans version sont désactivées, utilisez qt6_add_protobuf() à la place. Elle prend en charge le même ensemble d'arguments que cette commande.

Description de la commande

Les fichiers sources générés par qtprotobufgen sont ensuite ajoutés à la cible. Si la cible existe déjà, les fichiers générés sont ajoutés à la liste des sources de la cible. Si la cible n'existe pas, elle est créée en tant que bibliothèque à laquelle vous devez vous lier.

  • PROTO_FILES spécifie la liste des fichiers .proto utilisés par la procédure de génération de code.
  • PROTO_INCLUDES spécifie la liste des répertoires à rechercher pour les dépendances protobuf.

    Remarque : l'emplacement de PROTO_FILES est implicitement considéré comme faisant partie du chemin d'inclusion de protobuf.

  • QML permet de générer des types de messages compatibles avec QML à partir des définitions de protobuf et de les enregistrer en tant que module QML. Si qt_add_protobuf est appelé sur une cible inexistante ou sur une cible qui n'est pas un module QML, un nouveau module QML sera créé implicitement.
    find_package(Qt6 6.8 REQUIRED COMPONENTS Quick Protobuf ProtobufQuick)
    ...
    qt_add_executable(target
        ...
    )
    // creates a new QML module
    qt_add_protobuf(target
        QML
        ...
    )

    Si la cible est un module QML existant, qt_add_protobuf attachera les types de protobuf générés à ce module.

    find_package(Qt6 6.8 REQUIRED COMPONENTS Quick Protobuf ProtobufQuick)
    ...
    qt_add_qml_module(target
        ...
    )
    // adds to existing QML module
    qt_add_protobuf(target
        QML
        ...
    )

    Note : Si vous utilisez l'argument QML, vous devez ajouter ProtobufQuick dans l'appel find_package. Voir les exemples ci-dessus.

  • QML_URI définit le URI utilisé pour le module QML.

    Chaque module QML doit définir un URI, qui est utilisé dans les instructions d'importation pour exposer ses types de protobuf à QML.

    qt_add_protobuf(target
        QML
        QML_URI proto.uri.example
    )

    Si QML_URI est omis, le nom du paquetage protobuf sera utilisé comme URI du module.

    Remarque : si QML_URI est omis, tous les fichiers .proto spécifiés dans la section PROTO_FILES doivent partager le même nom de paquetage protobuf, car il sera utilisé comme URI par défaut pour le module QML résultant.

    Note : Vous devez éviter de créer plusieurs modules QML protobuf avec le même QML_URI ou le même nom de paquetage proto, car cela entraîne une erreur d'importation dans le contexte QML.

    Remarque : si QML_URI est transmis à la fonction qt_add_protobuf mais que la cible existe déjà, l'argument QML_URI sera ignoré.

    Lisez Modules identifiés pour une discussion plus approfondie sur URI.

  • OUTPUT_DIRECTORY définit le répertoire dans lequel les fichiers générés seront placés. Par défaut, le répertoire de construction actuel est utilisé.
  • GENERATE_PACKAGE_SUBFOLDERS utilise le nom du paquetage spécifié dans les fichiers .proto pour créer la structure du dossier pour les fichiers générés. Par exemple, si le paquet est défini comme : package io.qt.test les fichiers générés seront placés dans OUTPUT_DIRECTORY/io/qt/test/.
  • COPY_COMMENTS copie les commentaires des fichiers .proto dans le code généré.
  • EXPORT_MACRO ne s'applique que lors de la création d'une nouvelle bibliothèque partagée à partir de la <target>. Cette option spécifie le nom de base de la macro d'exportation utilisée dans le code généré. Le nom final de la macro est construit comme QPB_<EXPORT_MACRO>_EXPORT. Si cette option n'est pas définie, le nom de la cible est utilisé comme EXPORT_MACRO.

    Pour plus d'informations, lisez la section Création de bibliothèques partagées.

  • OUTPUT_HEADERS spécifie une variable qui stockera la liste des en-têtes générés. Cette liste peut être utile pour définir des règles d'installation de projet personnalisées.
  • OUTPUT_TARGETS spécifie une variable qui stockera la liste des cibles générées. Cette liste peut être utile pour définir des règles d'installation de projets personnalisés.
  • HEADER_GUARD spécifie le mécanisme utilisé pour protéger les fichiers d'en-tête générés contre l'inclusion multiple. Les valeurs possibles sont pragma, filename. La valeur par défaut est filename. La définition de l'option à pragma génère le mécanisme moderne de protection des fichiers d'en-tête pragma :
    #pragma once
    ...

    L'omission de l'option ou la définition de l'option à filename génère le mécanisme de protection ifdef et utilise le nom de fichier '.proto' comme infixe de protection :

    #ifdef MYMESSAGES_QPB_H
    #define MYMESSAGES_QPB_H
    ...
    #endif // MYMESSAGES_QPB_H

    Sélectionnez le style de garde préféré en fonction de la structure de votre projet.

  • GENERATE_NON_FINAL_MESSAGES génère les classes de messages QtProtobuf sans le spécificateur final. Cette option est fournie à des fins de compatibilité ascendante. Depuis Qt 6.11, les classes de messages QtProtobuf sont générées comme final par défaut. Pour étendre le comportement des messages générés, préférez la composition à l'héritage. Cette option sera supprimée dans Qt7.

Résolution des dépendances entre les cibles protobuf

La commande qt_add_protobuf ne prend pas en compte les dépendances entre les fichiers .proto qui sont utilisés pour générer du code pour différentes cibles.

Le projet peut avoir deux ou plusieurs fichiers .proto avec des dépendances :

// test_messages.proto
syntax = "proto3";

package test.messages;

message MyMessage {
    int32 myField = 1;
}
// test_extensions.proto
syntax = "proto3";

import "test_messages.proto";

package test.extensions;

message MyExtension {
    test.messages.MyMessage baseMessage = 1;
    int32 extension = 2;
}

Les fichiers .proto ci-dessus peuvent être utilisés pour générer les bibliothèques autonomes :

qt_add_protobuf(test_messages
    PROTO_FILES
        test_messages.proto
)
...
qt_add_protobuf(test_extensions
    PROTO_FILES
        test_extensions.proto
)
...

Étant donné que la cible test_extensions dépend des messages de la cible test_messages, vous devez lier ces cibles manuellement dans vos scripts CMake:

target_link_libraries(test_extensions PUBLIC test_messages)

Note : Les messages de la cible test_messages sont utilisés dans les fichiers d'en-tête qui appartiennent à la cible test_extensions, donc les cibles qui se lient à test_extensions doivent avoir la cible test_messages comme dépendance transitive. Il est recommandé d'utiliser la portée de liaison PUBLIC, afin d'avoir les propriétés INTERFACE_INCLUDE_DIRECTORIES et INTERFACE_LINK_LIBRARIES appropriées pour les cibles de la bibliothèque protobuf.

Exemple d'utilisation de qt_add_protobuf

Utilisation de qt_add_protobuf

cmake_minimum_required(VERSION 3.16...3.22)
project(MyThings)

find_package(Qt6 REQUIRED COMPONENTS Protobuf)
qt_standard_project_setup()

qt_add_protobuf(MyMessages
    GENERATE_PACKAGE_SUBFOLDERS
    PROTO_FILES
        path/to/message.proto
        path/to/other_message.proto
    PROTO_INCLUDES
        /path/to/proto/include
)

qt_add_executable(MyApp main.cpp)

target_link_libraries(MyApp PRIVATE MyMessages)

Dans l'exemple ci-dessus, nous générons une bibliothèque appelée MyMessages, qui contient les types de messages définis dans les chemins passés à l'option PROTO_FILES. L'option GENERATE_PACKAGE_SUBFOLDERS permet de générer une structure de dossier pour les fichiers générés. L'option PROTO_INCLUDES indique à protoc de rechercher des dépendances ou des importations dans les répertoires spécifiés. Nous créons une cible pour un exécutable appelé MyApp, que nous lions à la bibliothèque MyMessages.

Exemple de protobuf étendu QML

cmake_minimum_required(VERSION 3.16...3.22)
project(MyThings)

find_package(Qt6 REQUIRED COMPONENTS Protobuf ProtobufQuick Quick)
qt_standard_project_setup()

qt_add_protobuf(MyMessagesPlugin
    QML
    QML_URI my.messages.module.uri
    PROTO_FILES
        path/to/message.proto
        path/to/other_message.proto
    PROTO_INCLUDES
        /path/to/proto/include
)

qt_add_protobuf(MyApp
    QML
    PROTO_FILES
        path/to/internal_message.proto
    PROTO_INCLUDES
        /path/to/proto/include
)

qt_add_qml_module(MyApp
    URI example.uri
    VERSION 1.0
    QML_FILES qml/main.qml
)

qt_add_executable(MyApp main.cpp)
target_link_libraries(MyApp PRIVATE Quick)

Dans l'exemple QML étendu ci-dessus, le premier appel à qt_add_protobuf génère un module QML appelé MyMessagesPlugin, qui contient les types de messages définis dans les chemins d'accès transmis à l'option PROTO_FILES. Nous utilisons l'option QML, qui permet l'enregistrement des types de messages proto dans le contexte QML. Les types enregistrés seront disponibles dans QML en important un chemin défini par l'option QML_URI. Par un second appel à qt_add_protobuf, nous ajoutons du code auto-généré dans le module QML existant MyApp. L'appel à QML_URI n'est pas nécessaire dans ce cas. Enfin, nous créons une cible pour un exécutable appelé MyApp, qui possède un module QML pour la partie graphique et charge MyMessagesPlugin dans le fichier main.qml via l'importation my.messages.module.uri.

Installation de la bibliothèque autonome Qt Protobuf

La commande qt_add_protobuf produit également des listes d'artefacts pour une installation ultérieure. Vous pouvez lire ces artefacts en spécifiant les arguments OUTPUT_HEADERS, et OUTPUT_TARGETS comme suit :

qt_add_protobuf(MyProtoLib
    PROTO_FILES
        mylib.proto
    OUTPUT_HEADERS
        public_headers
    OUTPUT_TARGETS
        generated_targets
)

La commande enregistre la liste des fichiers d'en-tête et des cibles produits par la commande qt_add_protobuf dans les variables public_headers et generated_targets.

Utilisez la commande CMake install standard pour installer les artefacts et générer les fichiers config pour votre bibliothèque :

include(GNUInstallDirs)
set_target_properties(MyProtoLib PROPERTIES
    PUBLIC_HEADER
        "${public_headers}"
    INTERFACE_INCLUDE_DIRECTORIES
        "$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}>"
)
install(TARGETS ${generated_targets} EXPORT MyProtoLibTargets
    PUBLIC_HEADER
        DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
)
install(EXPORT MyProtoLibTargets NAMESPACE MyProtoLib:: DESTINATION lib/cmake/MyProtoLib)

Utilisez ensuite la configuration MyProtoLibTargets générée dans le fichier de configuration du paquet. Vous pouvez en savoir plus sur le processus de création de paquets dans la documentation officielle de CMake.

Après l'installation, la bibliothèque est disponible en tant que paquet CMake autonome :

find_package(Qt6 COMPONENTS Protobuf)
find_package(MyProtoLib CONFIG)

add_executable(MyApp main.cpp)
target_link_libraries(MyApp PRIVATE MyProtoLib::MyProtoLib Qt6::Protobuf)

Note : qt_add_protobuf n'ajoute pas implicitement le module Qt Protobuf comme dépendance transitive, ni pour la cible MyProtoLib, ni pour le paquetage CMake MyProtoLib. Par conséquent, la Qt Protobuf et la liaison explicite de MyApp à Qt6::Protobuf sont donc obligatoires.

Voir aussi L'outil qtprotobufgen.

© 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.