qt_add_protobuf
使用 protobuf 规范生成基于 Qt 的 C++ 源代码
注意:此命令目前处于技术预览阶段,可能在未来版本中发生变化。
此命令是在 Qt 6.5 中引入的。
通常,通过使用 qt_add_protobuf
命令通过 CMake 来调用 qtprotobufgen
。
qt_add_protobuf(<target> PROTO_FILES <file> ... [COPY_COMMENTS] [GENERATE_PACKAGE_SUBFOLDERS] [EXTRA_NAMESPACE <namespace>] [EXPORT_MACRO <infix>] [QML [QML_URI <uri>]] [PROTO_INCLUDES <path> ...] [OUTPUT_DIRECTORY <dir>] [OUTPUT_HEADERS <var>] [OUTPUT_TARGETS <var>] )
由 qtprotobufgen
生成的源文件将被添加到目标中。如果目标已存在,文件将被 添加 到目标源列表中。如果目标不存在,它将作为一个库创建,您必须将其链接到您的程序中。
参数
COPY_COMMENTS
从.proto
文件中复制注释。如果提供在参数列表中,将与消息和字段相关的注释复制到生成的头文件中。GENERATE_PACKAGE_SUBFOLDERS
为生成的文件生成与.proto
文件包名匹配的文件夹结构。例如,package io.qt.test;
将生成的文件放入io/qt/test/
。EXTRA_NAMESPACE
是为生成的类将使用的可选命名空间。类始终在具有与.proto
文件中指定的包名相同的命名空间中生成。如果使用此选项,则所有内容都将嵌套在额外命名空间内部。EXPORT_MACRO
是用于生成代码的符号导出宏的基本名称。生成的宏名称构造为QPB_<EXPORT_MACRO>_EXPORT
。如果未设置此选项,则不生成宏。QML
通过将它们注册为 QML 模块来启用 QML 上下文中的 QProtobufMessage 类型。Protobuf 类型可以扩展现有的 QML 模块。请参阅代码示例qt_add_qml_module(targetname ... ) qt_add_protobuf(targetname QML ... )
qt_add_executable(targetname ... ) qt_add_protobuf(targetname QML ... )
如果使用非现有目标调用
qt_add_protobuf
或目标不是 QML 模块,将隐式创建新的 QML 模块。如果创建新的 QML 模块,qt_add_qml_module 命令将在qt_add_protobuf
命令内部调用。请参阅代码示例qt_add_executable(targetname ... ) qt_add_protobuf(targetplugin QML QML_URI proto.uri.example )
每个 QML 模块都必须定义一个
URI
名称。其他 QML 模块可以在 import 语句 中使用此名称导入用户应用程序。请使用QML_URI
选项设置URI
名称。它必须指定为点分表示法,例如Qt.Protobuf.Package
。如果省略QML_URI
,则将使用 protobuf 包名称作为模块的URI
。注意:如果向
qt_add_protobuf
命令传递QML_URI
但target
已存在,则忽略QML_URI
参数。注意: 如果跳过
QML_URI
,则qt_add_protobuf
命令中指定的所有 *.proto 文件应该具有相同的protobuf
包名称,因为这将用作结果 QML 模块的默认URI
。注意: 您应避免创建具有相同
QML_URI
或 proto 包名称的多个 QML 模块,因为这会导致 QML 上下文中的导入错误。QML_URI
通过在提供的URI
导入路径中注册它们,在 QML 上下文中启用 QProtobufMessage 类型。URI
选项将用于生成的qmldir
文件的行中,并且还用于通过替换点为正向斜杠来形成目标路径。注意: 请阅读 Identified Modules 以进一步深入讨论
URI
。PROTO_FILES
是将用于生成过程的.proto
文件列表。PROTO_INCLUDES
是将搜索依赖项的目录列表。OUTPUT_DIRECTORY
是放置生成文件的目录。默认情况下,使用当前目录(在评估函数时)。OUTPUT_HEADERS
可以用于指定一个变量,该变量将保存函数创建的头文件列表。此列表对于自定义项目安装规则可能很有用。OUTPUT_TARGETS
可以用于指定一个变量,该变量将保存函数创建的目标列表。此列表对于自定义项目安装规则可能很有用。
解决 protobuf 目标之间的依赖关系
qt_add_protobuf
命令未考虑用于为不同目标生成代码的 .proto
文件之间的依赖关系。
项目可能有两个或更多具有依赖关系的 .proto
文件
syntax = "proto3"; package test.messages; message MyMessage { int32 myField = 1; }
syntax = "proto3"; import "test_messages.proto"; package test.extensions; message MyExtension { test.messages.MyMessage baseMessage = 1; int32 extension = 2; }
上述 .proto
文件可以用于生成独立库
qt_add_protobuf(test_messages PROTO_FILES test_messages.proto ) ... qt_add_protobuf(test_extensions PROTO_FILES test_extensions.proto ) ...
由于 test_extensions
目标依赖于来自 test_messages
目标的消息,因此用户需要在他们的 CMake
脚本中手动链接到此类目标。
target_link_libraries(test_extensions PUBLIC test_messages)
注意: 建议使用 PUBLIC
链接作用域,因为来自 test_messages
目标的消息在属于 test_extensions
目标的头文件中引用,因此链接到 test_extensions
的目标应将 test_messages
目标作为转译依赖项。
示例
使用 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)
在上面的示例中,我们生成一个名为 MyMessages
的库,该库包含通过 PROTO_FILES
选项传递的路径中定义的消息类型。 GENERATE_PACKAGE_SUBFOLDERS
选项用于生成生成文件的文件夹结构。并且 PROTO_INCLUDES
选项告诉 protoc 在指定的目录中查找依赖项或导入。我们创建一个名为 MyApp
的可执行文件目标,并将其链接到 MyMessages
库。
QML 扩展 protobuf 示例
cmake_minimum_required(VERSION 3.16...3.22) project(MyThings) find_package(Qt6 REQUIRED COMPONENTS Protobuf 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)
在上面的 QML 扩展示例中,通过第一次调用 qt_add_protobuf
,我们生成了一个名为 MyMessagesPlugin
的 QML 模块,其中包含传递给 PROTO_FILES
选项的路径中定义的消息类型。我们使用 QML
选项,该选项允许在 QML
上下文中注册 protobuf 消息类型。注册的类型可以通过导入由 QML_URI
设置的路径在 QML
中使用。通过第二次调用 qt_add_protobuf
,我们将自动生成的代码添加到现有的 MyApp
QML 模块中。在这种情况下不需要 QML_URI
。最后,我们为名为 MyApp
的可执行文件创建了一个目标,该可执行文件包含图形部分的 QML 模块,并通过 my.messages.module.uri
导入将 MyMessagesPlugin
载入 main.qml 文件。
安装独立的 Qt Protobuf 库
qt_add_protobuf 命令还会生成用于进一步安装的工件列表。您可以通过指定以下参数来读取这些工件:
qt_add_protobuf(MyProtoLib PROTO_FILES mylib.proto OUTPUT_HEADERS public_headers OUTPUT_TARGETS generated_targets )
该命令将 qt_add_protobuf
命令生成的头文件和目标的列表存储到相应的 public_headers
和 generated_targets
变量中。
使用标准的 CMake install
命令安装工件并为您库生成 config
文件
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)
然后使用在包配置文件中生成的 MyProtoLibTargets
配置。您可以在官方的 CMake 文档 中了解更多关于包创建过程的信息。
安装后,该库作为独立的 CMake 包可用
find_package(Qt6 COMPONENTS Protobuf) find_package(MyProtoLib CONFIG) add_executable(MyApp main.cpp) target_link_libraries(MyApp PRIVATE MyProtoLib::MyProtoLib Qt6::Protobuf)
注意:qt_add_protobuf 不隐式地作为传递依赖项添加 Qt Protobuf
模块,无论是对于 MyProtoLib
目标还是 MyProtoLib
CMake 包。因此,必须进行 Qt Protobuf
模块的查找并显式地将 MyApp
链接到 Qt6::Protobuf
。
另请参阅:qtprotobufgen 工具。
© 2024 Qt 公司有限公司。此处包含的文档贡献的版权属于其各自的所有者。此处提供的文档根据自由软件基金会发布的 GNU 自由文档许可证版本 1.3 的条款进行许可。Qt 和相应的标志是 Finland 和/或其他国家和地区的 The Qt Company Ltd. 的商标。所有其他商标属于其各自的所有者。