FindProtobuf¶
注意
如果Protobuf库是使用其基于CMake的构建系统构建和安装的,它会提供一个包配置文件,用于在配置模式下与find_package()命令一起使用
find_package(Protobuf CONFIG)
在这种情况下,导入的目标和CMake命令,例如protobuf_generate(),由上游包提供,而不是此模块。此外,此处记录的某些变量在配置模式下不可用,因为导入的目标是首选。有关使用详细信息,请参阅上游文档,这是使用CMake与Protobuf的推荐方式。
此模块仅在模块模式下工作。
此模块在模块模式下查找Protocol Buffers库 (Protobuf)
find_package(Protobuf [<version>] [...])
Protobuf是Google开发的一种开源、语言中立、平台中立的序列化结构化数据的机制。它通常用于程序之间或网络之间的数据交换。
3.6版本新增: 支持find_package(Protobuf <version>)中的<version>参数。
3.6版本更改: 所有输入和输出变量都使用Protobuf_前缀。带有PROTOBUF_前缀的变量为了向后兼容而受支持。
导入的目标¶
此模块提供以下 导入目标
protobuf::libprotobuf版本 3.9 中添加。
封装Protobuf库使用要求的Target,如果找到Protobuf库则可用。
protobuf::libprotobuf-lite版本 3.9 中添加。
封装
protobuf-lite库使用要求的Target,如果找到Protobuf及其lite库则可用。protobuf::libprotoc版本 3.9 中添加。
封装
protoc库使用要求的Target,如果找到Protobuf及其protoc库则可用。protobuf::protoc3.10 版本新增。
封装
protoc编译器使用要求的导入可执行文件Target,如果找到Protobuf和protoc则可用。
结果变量¶
此模块定义了以下变量
Protobuf_FOUND布尔值,表示是否找到(请求版本的)Protobuf库。
Protobuf_VERSION3.6 版本新增。
找到的Protobuf版本。
Protobuf_INCLUDE_DIRS使用Protobuf所需的包含目录。
Protobuf_LIBRARIES链接Protobuf所需的库。
Protobuf_PROTOC_LIBRARIES链接
protoc库所需的库。Protobuf_LITE_LIBRARIES链接
protobuf-lite库所需的库。
缓存变量¶
以下缓存变量也可以设置
Protobuf_INCLUDE_DIR包含Protobuf头文件的包含目录。
Protobuf_LIBRARYprotobuf库的路径。Protobuf_PROTOC_LIBRARYprotoc库的路径。Protobuf_PROTOC_EXECUTABLEprotoc编译器的路径。Protobuf_LIBRARY_DEBUGprotobuf调试库的路径。Protobuf_PROTOC_LIBRARY_DEBUGprotoc调试库的路径。Protobuf_LITE_LIBRARYprotobuf-lite库的路径。Protobuf_LITE_LIBRARY_DEBUGprotobuf-lite调试库的路径。Protobuf_SRC_ROOT_FOLDER当使用MSVC编译时,如果设置了此缓存变量,将会在protobuf默认的Visual Studio项目构建位置搜索库和二进制文件
<Protobuf_SRC_ROOT_FOLDER>/vsprojects/{Debug,Release},或者<Protobuf_SRC_ROOT_FOLDER>/vsprojects/x64/{Debug,Release}
提示¶
此模块在调用find_package(Protobuf)之前接受以下可选变量
Protobuf_DEBUG3.6 版本新增。
布尔变量,用于启用此模块的调试消息以进行调试。
Protobuf_USE_STATIC_LIBS版本 3.9 中添加。
设置为ON以强制使用静态库。默认为OFF。
命令¶
如果找到Protobuf,此模块提供以下命令
生成源文件¶
- protobuf_generate¶
3.13 版本新增。
在构建时自动从
.proto模式文件生成源文件protobuf_generate( [TARGET <target>] [LANGUAGE <lang>] [OUT_VAR <variable>] [EXPORT_MACRO <macro>] [PROTOC_OUT_DIR <out-dir>] [PLUGIN <plugin>] [PLUGIN_OPTIONS <plugin-options>] [DEPENDENCIES <dependencies>...] [PROTOS <proto-files>...] [IMPORT_DIRS <dirs>...] [APPEND_PATH] [GENERATE_EXTENSIONS <extensions>...] [PROTOC_OPTIONS <options>...] [PROTOC_EXE <executable>] [DESCRIPTORS] )
TARGET <target>生成文件作为源添加到其中的CMake目标。当未使用
OUT_VAR <variable>时,此选项是必需的。LANGUAGE <lang>单个值:
cpp或python。确定要生成的源文件类型。默认为cpp。对于其他语言,请使用GENERATE_EXTENSIONS选项。OUT_VAR <variable>将填充生成源文件路径的CMake变量的名称。
EXPORT_MACRO <macro>应用于所有生成的Protobuf消息类和外部变量的预处理器宏的名称。例如,这可以用于声明DLL导出。根据编译的内容,宏应扩展为
__declspec(dllexport)或__declspec(dllimport)。此选项仅在
LANGUAGE为cpp时使用。PROTOC_OUT_DIR <out-dir>生成源文件的输出目录。默认为:
CMAKE_CURRENT_BINARY_DIR。PLUGIN <plugin>3.21 版本新增。
一个可选的插件可执行文件。例如,这可以是
grpc_cpp_plugin的路径。PLUGIN_OPTIONS <plugin-options>版本 3.28 新增。
传递给插件的额外选项,例如gRPC C++插件的
generate_mock_code=true。DEPENDENCIES <dependencies>...版本 3.28 新增。
文件生成所依赖的依赖项。这些将被转发到底层的
add_custom_command(DEPENDS)调用。4.1版本更改:此参数现在接受多个值(
DEPENDENCIES a b c...)。以前,只能指定单个值(DEPENDENCIES "a;b;c;...")。PROTOS <proto-files>...要处理的
.proto模式文件列表。如果同时指定了<target>,这些文件将与该目标的所有.proto源文件合并。IMPORT_DIRS <dirs>...模式文件的一个或多个共同父目录列表。例如,如果模式文件是
proto/helloworld/helloworld.proto且导入目录是proto/,则生成的文件将是<out-dir>/helloworld/helloworld.pb.h和<out-dir>/helloworld/helloworld.pb.cc。APPEND_PATH如果指定,所有proto模式文件的基本路径将附加到
IMPORT_DIRS(它会导致protoc为每个包含.proto文件的目录调用-I参数)。GENERATE_EXTENSIONS <extensions>...如果省略
LANGUAGE,则必须设置此项以指定protoc生成的扩展。PROTOC_OPTIONS <options>...版本 3.28 新增。
直接传递给
protoc编译器的附加命令行选项列表。PROTOC_EXE <executable>4.0 版本新增。
用于生成Protobuf绑定的命令行程序、路径或CMake可执行文件。如果省略,默认使用
protobuf::protoc导入目标。DESCRIPTORS如果指定,命令行选项
--descriptor_set_out=<proto-file>将附加到protoc编译器,用于每个.proto源文件,从而实现自描述消息的创建。此选项只能在<lang>为cpp且Protobuf在模块模式下找到时使用。注意
当Protobuf在配置模式下找到时,此选项不可用。
已废弃的命令¶
以下命令为了向后兼容而提供。
注意
protobuf_generate_cpp()和protobuf_generate_python()命令仅在调用find_package(Protobuf ...)的同一目录范围内才能正确工作。
注意
如果Protobuf在配置模式下找到,自Protobuf 3.0.0版本起,protobuf_generate_cpp()和protobuf_generate_python()命令不可用,除非在调用find_package(Protobuf ...)之前,上游包配置提示变量protobuf_MODULE_COMPATIBLE设置为布尔真。
- protobuf_generate_cpp¶
自4.1版本起废弃:使用
protobuf_generate()。在构建时自动从
.proto模式文件生成C++源文件protobuf_generate_cpp( <sources-variable> <headers-variable> [DESCRIPTORS <variable>] [EXPORT_MACRO <macro>] <proto-files>... )
<sources-variable>要定义的变量名称,其中将包含生成的C++源文件列表。
<headers-variable>要定义的变量名称,其中将包含生成的头文件列表。
DESCRIPTORS <variable>3.10 版本新增。
要定义的变量名称,如果请求,其中将包含生成的描述符文件列表。
注意
当Protobuf在配置模式下找到时,此选项不可用。
EXPORT_MACRO <macro>一个宏的名称,该宏应根据正在编译的内容扩展为
__declspec(dllexport)或__declspec(dllimport)。<proto-files>...一个或多个待处理的
.proto文件。
- protobuf_generate_python¶
自4.1版本起废弃:使用
protobuf_generate()。3.4 版本新增。
在构建时自动从
.proto模式文件生成Python源文件protobuf_generate_python(<python-sources-variable> <proto-files>...)
<python-sources-variable>要定义的变量名称,其中将包含生成的Python源文件列表。
<proto-files>...一个或多个待处理的
.proto文件。
protobuf_generate_cpp()和protobuf_generate_python()命令在调用前接受以下可选变量
Protobuf_IMPORT_DIRS自4.1版本起废弃。
用于搜索导入的
.proto文件的附加目录列表。PROTOBUF_GENERATE_CPP_APPEND_PATH自4.1版本起废弃:使用
protobuf_generate(APPEND_PATH)命令选项。一个布尔变量,如果设置为布尔真,将导致
protoc为每个包含.proto文件的目录调用-I参数。默认情况下,它设置为布尔真。
示例¶
示例:查找Protobuf¶
查找Protobuf库
find_package(Protobuf)
或者,查找Protobuf并指定所需的最低版本
find_package(Protobuf 30)
或者,查找Protobuf并使其成为必需项(如果未找到,则处理会因错误消息而停止)
find_package(Protobuf REQUIRED)
示例:在配置模式下查找Protobuf¶
当Protobuf库使用其基于CMake的构建系统构建和安装时,它可以在配置模式下找到
find_package(Protobuf CONFIG)
然而,一些Protobuf安装可能仍不提供包配置文件。以下示例展示了如何使用CMAKE_FIND_PACKAGE_PREFER_CONFIG变量在配置模式下查找Protobuf,并在找不到配置文件时回退到模块模式
set(CMAKE_FIND_PACKAGE_PREFER_CONFIG TRUE)
find_package(Protobuf)
unset(CMAKE_FIND_PACKAGE_PREFER_CONFIG)
示例:使用Protobuf¶
查找Protobuf并将其导入的库目标链接到项目目标
find_package(Protobuf)
target_link_libraries(example PRIVATE protobuf::libprotobuf)
示例:处理Proto模式文件¶
以下示例演示了如何将添加到目标的所有*.proto模式源文件处理为C++源文件
CMakeLists.txt¶cmake_minimum_required(VERSION 3.24)
project(ProtobufExample)
add_executable(example main.cxx person.proto)
find_package(Protobuf)
if(Protobuf_FOUND)
protobuf_generate(TARGET example)
endif()
target_link_libraries(example PRIVATE protobuf::libprotobuf)
target_include_directories(example PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
person.proto¶syntax = "proto3";
message Person {
string name = 1;
int32 id = 2;
}
main.cxx¶#include <iostream>
#include "person.pb.h"
int main()
{
Person person;
person.set_name("Alice");
person.set_id(123);
std::cout << "Name: " << person.name() << "\n";
std::cout << "ID: " << person.id() << "\n";
return 0;
}
示例:使用Protobuf和gRPC¶
以下示例展示了如何使用Protobuf和gRPC
CMakeLists.txt¶find_package(Protobuf REQUIRED)
find_package(gRPC CONFIG REQUIRED)
add_library(ProtoExample Example.proto)
target_link_libraries(ProtoExample PUBLIC gRPC::grpc++)
protobuf_generate(TARGET ProtoExample)
protobuf_generate(
TARGET ProtoExample
LANGUAGE grpc
PLUGIN protoc-gen-grpc=$<TARGET_FILE:gRPC::grpc_cpp_plugin>
PLUGIN_OPTIONS generate_mock_code=true
GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc
)
示例:升级废弃命令¶
以下示例展示了如何使用废弃命令及其现代替代品将.proto文件处理为C++代码
CMakeLists.txt¶find_package(Protobuf)
if(Protobuf_FOUND)
protobuf_generate_cpp(
proto_sources
proto_headers
EXPORT_MACRO DLL_EXPORT
DESCRIPTORS proto_descriptors
src/protocol/Proto1.proto
src/protocol/Proto2.proto
)
endif()
target_sources(
example
PRIVATE ${proto_sources} ${proto_headers} ${proto_descriptors}
)
target_link_libraries(example PRIVATE protobuf::libprotobuf)
CMakeLists.txt¶find_package(Protobuf)
if(Protobuf_FOUND)
protobuf_generate(
TARGET example
EXPORT_MACRO DLL_EXPORT
IMPORT_DIRS src/protocol
DESCRIPTORS
PROTOS
src/protocol/Proto1.proto
src/protocol/Proto2.proto
)
endif()
target_link_libraries(example PRIVATE protobuf::libprotobuf)
以下示例展示了如何使用废弃命令及其现代替代品将.proto文件处理为Python代码
CMakeLists.txt¶find_package(Protobuf)
if(Protobuf_FOUND)
protobuf_generate_python(python_sources foo.proto)
endif()
add_custom_target(proto_files DEPENDS ${python_sources})
CMakeLists.txt¶find_package(Protobuf)
if(Protobuf_FOUND)
protobuf_generate(
LANGUAGE python
PROTOS foo.proto
OUT_VAR python_sources
)
endif()
add_custom_target(proto_files DEPENDS ${python_sources})