# How to use `protobuf_generate`

This document explains how to use the function `protobuf_generate` which is
provided by protobuf's CMake module.

## Usage

In the same directory that called `find_package(protobuf CONFIG)` and any of its
subdirectories, the CMake function `protobuf_generate` is made available by
[`protobuf-generate.cmake`](../cmake/protobuf-generate.cmake). It can be used to
automatically generate source files from `.proto` schema files at build time.

### Basic example

Let us see how `protobuf_generate` can be used to generate and compile the
source files of a proto schema whenever an object target called `proto-objects`
is built.

Given the following directory structure:

-   `proto/helloworld/helloworld.proto`
-   `CMakeLists.txt`

where `helloworld.proto` is a protobuf schema file and `CMakeLists.txt`
contains:

```cmake
find_package(protobuf CONFIG REQUIRED)

add_library(proto-objects OBJECT "${CMAKE_CURRENT_LIST_DIR}/proto/helloworld/helloworld.proto")

target_link_libraries(proto-objects PUBLIC protobuf::libprotobuf)

set(PROTO_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated")

target_include_directories(proto-objects PUBLIC "$<BUILD_INTERFACE:${PROTO_BINARY_DIR}>")

protobuf_generate(
    TARGET proto-objects
    IMPORT_DIRS "${CMAKE_CURRENT_LIST_DIR}/proto"
    PROTOC_OUT_DIR "${PROTO_BINARY_DIR}")
```

Building the target `proto-objects` will generate the files:

-   `${CMAKE_CURRENT_BINARY_DIR}/generated/helloworld/helloworld.pb.h`
-   `${CMAKE_CURRENT_BINARY_DIR}/generated/helloworld/helloworld.pb.cc`

and (depending on the build system) output:

```shell
[build] [1/2] Running cpp protocol buffer compiler on /proto/helloworld/helloworld.proto
[build] [2/2] Building CXX object /build/generated/helloworld/helloworld.pb.cc.o
```

### gRPC example

`protobuf_generate` can also be customized to invoke plugins like gRPC's
`grpc_cpp_plugin`. Given the same directory structure as in the
[basic example](#basic-example) and let `CMakeLists.txt` contain:

```cmake
find_package(gRPC CONFIG REQUIRED)

add_library(proto-objects OBJECT "${CMAKE_CURRENT_LIST_DIR}/proto/helloworld/helloworld.proto")

target_link_libraries(proto-objects PUBLIC protobuf::libprotobuf gRPC::grpc++)

set(PROTO_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated")
set(PROTO_IMPORT_DIRS "${CMAKE_CURRENT_LIST_DIR}/proto")

target_include_directories(proto-objects PUBLIC "$<BUILD_INTERFACE:${PROTO_BINARY_DIR}>")

protobuf_generate(
    TARGET proto-objects
    IMPORT_DIRS ${PROTO_IMPORT_DIRS}
    PROTOC_OUT_DIR "${PROTO_BINARY_DIR}")

protobuf_generate(
    TARGET proto-objects
    LANGUAGE grpc
    GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc
    PLUGIN "protoc-gen-grpc=\$<TARGET_FILE:gRPC::grpc_cpp_plugin>"
    IMPORT_DIRS ${PROTO_IMPORT_DIRS}
    PROTOC_OUT_DIR "${PROTO_BINARY_DIR}")
```

Then building `proto-objects` will generate and compile:

-   `${CMAKE_CURRENT_BINARY_DIR}/generated/helloworld/helloworld.pb.h`
-   `${CMAKE_CURRENT_BINARY_DIR}/generated/helloworld/helloworld.pb.cc`
-   `${CMAKE_CURRENT_BINARY_DIR}/generated/helloworld/helloworld.grpc.pb.h`
-   `${CMAKE_CURRENT_BINARY_DIR}/generated/helloworld/helloworld.grpc.pb.cc`

And `protoc` will automatically be re-run whenever the schema files change and
`proto-objects` is built.

### Note on unity builds

Since protobuf's generated source files are unsuited for
[jumbo/unity builds](https://cmake.org/cmake/help/latest/prop_tgt/UNITY_BUILD.html)
it is recommended to exclude them from such builds which can be achieved by
adjusting their properties:

```cmake
protobuf_generate(
    OUT_VAR PROTO_GENERATED_FILES
    ...)

set_source_files_properties(${PROTO_GENERATED_FILES} PROPERTIES SKIP_UNITY_BUILD_INCLUSION on)
```

## How it works

For each source file ending in `proto` of the argument provided to `TARGET` or
each file provided through `PROTOS`, `protobuf_generate` will set up a
[add_custom_command](https://cmake.org/cmake/help/latest/command/add_custom_command.html)
which depends on `protobuf::protoc` and the proto files. It declares the
generated source files as `OUTPUT` which means that any target that depends on
them will automatically cause the custom command to execute when it is brought
up to date. The command itself is made up of the arguments for `protoc`, like
the output directory, the schema files, the language to generate for, the
plugins to use, etc.

## Reference

Arguments accepted by `protobuf_generate`.

Flag arguments:

-   `APPEND_PATH` — A flag that causes the base path of all proto schema files
    to be added to `IMPORT_DIRS`.

Single-value arguments:

-   `LANGUAGE` — A single value: cpp or python. Determines what kind of source
    files are being generated.
-   `OUT_VAR` — Name of a CMake variable that will be filled with the paths to
    the generated source files.
-   `EXPORT_MACRO` — Name of a macro that is applied to all generated Protobuf
    message classes and extern variables. It can, for example, be used to
    declare DLL exports.
-   `PROTOC_EXE` — Command name, path, or CMake executable used to run protoc
    commands. Defaults to `protobuf::protoc`.
-   `PROTOC_OUT_DIR` — Output directory of generated source files. Defaults to
    `CMAKE_CURRENT_BINARY_DIR`.
-   `PLUGIN` — An optional plugin executable. This could, for example, be the
    path to `grpc_cpp_plugin`.
-   `PLUGIN_OPTIONS` — Additional options provided to the plugin, such as
    `generate_mock_code=true` for the gRPC cpp plugin.
-   `DEPENDENCIES` — Arguments forwarded to the `DEPENDS` of the underlying
    `add_custom_command` invocation.
-   `TARGET` — CMake target that will have the generated files added as sources.

Multi-value arguments:

-   `PROTOS` — List of proto schema files. If omitted, then every source file
    ending in *proto* of `TARGET` will be used.
-   `IMPORT_DIRS` — A common parent directory for the schema files. For example,
    if the schema file is `proto/helloworld/helloworld.proto` and the import
    directory `proto/` then the generated files are
    `${PROTOC_OUT_DIR}/helloworld/helloworld.pb.h` and
    `${PROTOC_OUT_DIR}/helloworld/helloworld.pb.cc`.
-   `GENERATE_EXTENSIONS` — If LANGUAGE is omitted then this must be set to the
    extensions that protoc generates.
-   `PROTOC_OPTIONS` — Additional arguments that are forwarded to protoc.
