# FindProtobuf

Note

If the Protobuf library is built and installed using its CMake-based build system, it provides a package configuration file for use with the `find_package()` command in config mode:

    find_package(Protobuf CONFIG)

In this case, imported targets and CMake commands such as `protobuf_generate()` are provided by the upstream package rather than this module. Additionally, some variables documented here are not available in config mode, as imported targets are preferred. For usage details, refer to the upstream documentation, which is the recommended way to use Protobuf with CMake.

This module works only in module mode.

This module finds the Protocol Buffers library (Protobuf) in module mode:

    find_package(Protobuf [<version>] [...])

Protobuf is an open-source, language-neutral, and platform-neutral mechanism for serializing structured data, developed by Google. It is commonly used for data exchange between programs or across networks.

Added in version 3.6: Support for the `<version>` argument in `find_package(Protobuf <version>)`.

Changed in version 3.6: All input and output variables use the `Protobuf_` prefix. Variables with `PROTOBUF_` prefix are supported for backward compatibility.

## Imported Targets

This module provides the following Imported Targets:

`protobuf::libprotobuf`

  Added in version 3.9.

  Target encapsulating the Protobuf library usage requirements, available if Protobuf library is found.

`protobuf::libprotobuf-lite`

  Added in version 3.9.

  Target encapsulating the `protobuf-lite` library usage requirements, available if Protobuf and its lite library are found.

`protobuf::libprotoc`

  Added in version 3.9.

  Target encapsulating the `protoc` library usage requirements, available if Protobuf and its `protoc` library are found.

`protobuf::protoc`

  Added in version 3.10.

  Imported executable target encapsulating the `protoc` compiler usage requirements, available if Protobuf and `protoc` are found.

## Result Variables

This module defines the following variables:

`Protobuf_FOUND`

  Boolean indicating whether (the requested version of) Protobuf library is found.

`Protobuf_VERSION`

  Added in version 3.6.

  The version of Protobuf found.

`Protobuf_INCLUDE_DIRS`

  Include directories needed to use Protobuf.

`Protobuf_LIBRARIES`

  Libraries needed to link against to use Protobuf.

`Protobuf_PROTOC_LIBRARIES`

  Libraries needed to link against to use the `protoc` library.

`Protobuf_LITE_LIBRARIES`

  Libraries needed to link against to use the `protobuf-lite` library.

## Cache Variables

The following cache variables may also be set:

`Protobuf_INCLUDE_DIR`

  The include directory containing Protobuf headers.

`Protobuf_LIBRARY`

  The path to the `protobuf` library.

`Protobuf_PROTOC_LIBRARY`

  The path to the `protoc` library.

`Protobuf_PROTOC_EXECUTABLE`

  The path to the `protoc` compiler.

`Protobuf_LIBRARY_DEBUG`

  The path to the `protobuf` debug library.

`Protobuf_PROTOC_LIBRARY_DEBUG`

  The path to the `protoc` debug library.

`Protobuf_LITE_LIBRARY`

  The path to the `protobuf-lite` library.

`Protobuf_LITE_LIBRARY_DEBUG`

  The path to the `protobuf-lite` debug library.

`Protobuf_SRC_ROOT_FOLDER`

  When compiling with MSVC, if this cache variable is set, the protobuf-default Visual Studio project build locations will be searched for libraries and binaries:

  - `<Protobuf_SRC_ROOT_FOLDER>/vsprojects/{Debug,Release}`, or

  - `<Protobuf_SRC_ROOT_FOLDER>/vsprojects/x64/{Debug,Release}`

## Hints

This module accepts the following optional variables before calling the `find_package(Protobuf)`:

`Protobuf_DEBUG`

  Added in version 3.6.

  Boolean variable that enables debug messages of this module to be printed for debugging purposes.

`Protobuf_USE_STATIC_LIBS`

  Added in version 3.9.

  Set to ON to force the use of the static libraries. Default is OFF.

## Commands

This module provides the following commands if Protobuf is found:

### Generating Source Files

protobuf_generate

  Added in version 3.13.

  Automatically generates source files from `.proto` schema files at build time:

      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>`

    The CMake target to which the generated files are added as sources. This option is required when `OUT_VAR <variable>` is not used.

  `LANGUAGE <lang>`

    A single value: `cpp` or `python`. Determines the kind of source files to generate. Defaults to `cpp`. For other languages, use the `GENERATE_EXTENSIONS` option.

  `OUT_VAR <variable>`

    The name of a CMake variable that will be populated with the paths to the generated source files.

  `EXPORT_MACRO <macro>`

    The name of a preprocessor macro applied to all generated Protobuf message classes and extern variables. This can be used, for example, to declare DLL exports. The macro should expand to `__declspec(dllexport)` or `__declspec(dllimport)`, depending on what is being compiled.

    This option is only used when `LANGUAGE` is `cpp`.

  `PROTOC_OUT_DIR <out-dir>`

    The output directory for generated source files. Defaults to: `CMAKE_CURRENT_BINARY_DIR`.

  `PLUGIN <plugin>`

    Added in version 3.21.

    An optional plugin executable. This could be, for example, the path to `grpc_cpp_plugin`.

  `PLUGIN_OPTIONS <plugin-options>`

    Added in version 3.28.

    Additional options passed to the plugin, such as `generate_mock_code=true` for the gRPC C++ plugin.

  `DEPENDENCIES <dependencies>...`

    Added in version 3.28.

    Dependencies on which the generation of files depends on. These are forwarded to the underlying `add_custom_command(DEPENDS)` invocation.

    Changed in version 4.1: This argument now accepts multiple values (`DEPENDENCIES a b c...`). Previously, only a single value could be specified (`DEPENDENCIES "a;b;c;..."`).

  `PROTOS <proto-files>...`

    A list of `.proto` schema files to process. If `<target>` is also specified, these will be combined with all `.proto` source files from that target.

  `IMPORT_DIRS <dirs>...`

    A list of one or more common parent directories for the schema files. For example, if the schema file is `proto/helloworld/helloworld.proto` and the import directory is `proto/`, then the generated files will be `<out-dir>/helloworld/helloworld.pb.h` and `<out-dir>/helloworld/helloworld.pb.cc`.

  `APPEND_PATH`

    If specified, the base paths of all proto schema files are appended to `IMPORT_DIRS` (it causes `protoc` to be invoked with `-I` argument for each directory containing a `.proto` file).

  `GENERATE_EXTENSIONS <extensions>...`

    If `LANGUAGE` is omitted, this must be set to specify the extensions generated by `protoc`.

  `PROTOC_OPTIONS <options>...`

    Added in version 3.28.

    A list of additional command-line options passed directly to the `protoc` compiler.

  `PROTOC_EXE <executable>`

    Added in version 4.0.

    The command-line program, path, or CMake executable used to generate Protobuf bindings. If omitted, `protobuf::protoc` imported target is used by default.

  `DESCRIPTORS`

    If specified, a command-line option `--descriptor_set_out=<proto-file>` is appended to `protoc` compiler for each `.proto` source file, enabling the creation of self-describing messages. This option can only be used when `<lang>` is `cpp` and Protobuf is found in module mode.

    Note

    This option is not available when Protobuf is found in config mode.

### Deprecated Commands

The following commands are provided for backward compatibility.

Note

The `protobuf_generate_cpp()` and `protobuf_generate_python()` commands work correctly only within the same directory scope, where `find_package(Protobuf ...)` is called.

Note

If Protobuf is found in config mode, the `protobuf_generate_cpp()` and `protobuf_generate_python()` commands are not available as of Protobuf version 3.0.0, unless the upstream package configuration hint variable `protobuf_MODULE_COMPATIBLE` is set to boolean true before calling `find_package(Protobuf ...)`.

protobuf_generate_cpp

  Deprecated since version 4.1: Use `protobuf_generate()`.

  Automatically generates C++ source files from `.proto` schema files at build time:

      protobuf_generate_cpp(
        <sources-variable>
        <headers-variable>
        [DESCRIPTORS <variable>]
        [EXPORT_MACRO <macro>]
        <proto-files>...
      )

  `<sources-variable>`

    Name of the variable to define, which will contain a list of generated C++ source files.

  `<headers-variable>`

    Name of the variable to define, which will contain a list of generated header files.

  `DESCRIPTORS <variable>`

    Added in version 3.10.

    Name of the variable to define, which will contain a list of generated descriptor files if requested.

    Note

    This option is not available when Protobuf is found in config mode.

  `EXPORT_MACRO <macro>`

    Name of a macro that should expand to `__declspec(dllexport)` or `__declspec(dllimport)`, depending on what is being compiled.

  `<proto-files>...`

    One of more `.proto` files to be processed.

protobuf_generate_python

  Deprecated since version 4.1: Use `protobuf_generate()`.

  Added in version 3.4.

  Automatically generates Python source files from `.proto` schema files at build time:

      protobuf_generate_python(<python-sources-variable> <proto-files>...)

  `<python-sources-variable>`

    Name of the variable to define, which will contain a list of generated Python source files.

  `<proto-files>...`

    One or more `.proto` files to be processed.

The `protobuf_generate_cpp()` and `protobuf_generate_python()` commands accept the following optional variables before being invoked:

`Protobuf_IMPORT_DIRS`

  Deprecated since version 4.1.

  A list of additional directories to search for imported `.proto` files.

`PROTOBUF_GENERATE_CPP_APPEND_PATH`

  Deprecated since version 4.1: Use `protobuf_generate(APPEND_PATH)` command option.

  A boolean variable that, if set to boolean true, causes `protoc` to be invoked with `-I` argument for each directory containing a `.proto` file. By default, it is set to boolean true.

## Examples

### Examples: Finding Protobuf

Finding Protobuf library:

    find_package(Protobuf)

Or, finding Protobuf and specifying a minimum required version:

    find_package(Protobuf 30)

Or, finding Protobuf and making it required (if not found, processing stops with an error message):

    find_package(Protobuf REQUIRED)

### Example: Finding Protobuf in Config Mode

When Protobuf library is built and installed using its CMake-based build system, it can be found in config mode:

    find_package(Protobuf CONFIG)

However, some Protobuf installations might still not provide package configuration file. The following example shows, how to use the `CMAKE_FIND_PACKAGE_PREFER_CONFIG` variable to find Protobuf in config mode and falling back to module mode if config file is not found:

    set(CMAKE_FIND_PACKAGE_PREFER_CONFIG TRUE)
    find_package(Protobuf)
    unset(CMAKE_FIND_PACKAGE_PREFER_CONFIG)

### Example: Using Protobuf

Finding Protobuf and linking its imported library target to a project target:

    find_package(Protobuf)
    target_link_libraries(example PRIVATE protobuf::libprotobuf)

### Example: Processing Proto Schema Files

The following example demonstrates how to process all `*.proto` schema source files added to a target into C++ source files:

`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;
    }

### Example: Using Protobuf and gRPC

The following example shows how to use Protobuf and 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
    )

### Examples: Upgrading Deprecated Commands

The following example shows how to process `.proto` files to C++ code, using a deprecated command and its modern replacement:

`CMakeLists.txt` with deprecated command

    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` with upgraded code

    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)

The following example shows how to process `.proto` files to Python code, using a deprecated command and its modern replacement:

`CMakeLists.txt` with deprecated command

    find_package(Protobuf)

    if(Protobuf_FOUND)
      protobuf_generate_python(python_sources foo.proto)
    endif()

    add_custom_target(proto_files DEPENDS ${python_sources})

`CMakeLists.txt` with upgraded code

    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})