A Bazel rule to generate language agnostic code with protoc plugins.
git_repository(
name = "rules_protoc_gen",
remote = "https://github.com/fischor/rules_protoc_gen",
commit = "<current-commit>",
)
# You also need bazel_skylib, since rules_proto_gen uses that.
http_archive(
name = "bazel_skylib",
sha256 = "1c531376ac7e5a180e0237938a2536de0c54d93f5c278634818e0efc952dd56c",
urls = [
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.0.3/bazel-skylib-1.0.3.tar.gz",
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.0.3/bazel-skylib-1.0.3.tar.gz",
],
)
load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
bazel_skylib_workspace()
Rules to run and generate code with protoc plugins.
rules_protoc_gen provides two rules to generate output from proto_library
targets with proto plugins:
protoc_plugin
is used to define a plugin.
protoc_output
is used to generate output using a defined plugin.
Bazel requires to define the set of outputs a target generates before its build action is run.
Different protoc plugins use different strategies of producing outputs.
rules_protoc_gen
currently supports two ways of producing outputs that should cover every use case: based on a suffix or by letting the rule user manually specify the set of outputs.
However, you also can describe other ways of producing outputs by writing rules that return the ProtocPluginInfo
provider.
A common way to generate outputs for a protoc plugin is to generate one output file for every proto input file.
For example, a Python plugin might generate one ".py" for each ".proto" file its requested to generate code for.
That way, e.g. for "a/b/c.proto" a file named "a/b/c.py" and for "a/b/d.proto" a file named "a/b/d.py" would be generated.
To describe this behaviour, use the protoc_plugin
rule with a suffix
attribute set to ".py".
Another plugin might produce files based on file options specified in the proto file.
The official Golang plugin bases the names of its outputs files under the go_package
option.
For example, for a file name x.proto
that specified a option go_package = "github.com/fischor/okg
it would generate a file named github.com/fischor/pkg/x.pb.go
To describe this behaviour either write your own rule that returns a ProtoPluginInfo
provider or simply use the protoc_plugin
rule with the predeclared_outputs
attribute set to True
and specify the files that are expected to be generated when the plugin is used with protoc_output
in protoc_putputs
outputs
attribute.
There are endless ways of how a plugin might generate outputs.
As a fallback, a plugin using predeclared outputs always lets the user specify which outputs are generated for each protoc_output
target.
load("@rules_protoc_gen//:def.bzl", "protoc_plugin")
protoc_plugin(
name = "my_plugin",
executable = ":myexecutable",
suffix = ".pb.py",
)
# or alternatively
protoc_plugin(
name = "my_other_plugin",
executable = ":myexecutable",
predeclared_outputs = True,
)
load("@rules_proto//proto:defs.bzl", "proto_library")
load("@rules_protoc_gen//:def.bzl", "protoc_output")
proto_library(
name = "foo_proto",
srcs = ["foo.proto"],
visibility = ["//visibility:public"],
)
protoc_output(
name = "foo_my_plugin_output",
plugin = "//path/to:my_plugin"
protos = [":foo_proto"],
)
protoc_output(
name = "foo_my_other_plugin_output",
plugin = "//path/to:my_other_plugin"
protos = [":foo_proto"],
outputs = [
"my/proto/package/foo.py",
]
)
protoc_output(name, data, options, outputs, plugin, plugin_out, protoc, protos)
Runs a protoc plugin.
ATTRIBUTES
Name | Description | Type | Mandatory | Default |
---|---|---|---|---|
name | A unique name for this target. | Name | required | |
data | Files added to the actions execution environment such that the plugin can access them. | List of labels | optional | [] |
options | Options passed to the plugin. For example: ["x=3", "y=5"] will be passed as
to the command line line when running protoc with the plugin ( <plugin-name> ). The options are subject to ctx.expanded_locations: For example, use
to obtain the runfile location of :my_data_file and passed it as config option to the plugin. :my_data_file must be passed in the data attribute for the expansion to work. Do not use the locations (note the s ) directive. |
List of strings | optional | [] |
outputs | Optional output attributes passed to the plugins. For plugin that define the their outputs using predeclared outputs, this is the list of predeclared outputs. See ProtocPluginInfo.output for more information. |
List of strings | optional | [] |
plugin | The plugin to run. | Label | required | |
plugin_out | The output root to generate the files to. This will be passed as --<plugin-name>_out=<plugin_out> to the protoc executable. Defaults to <bazel_package>/<target_name>/ . When using a different value, this will affect where to plugin generates its outputs files to. Each file that the plugin returns will be placed under <plugin_out>/<generated_filename> . Bazel requires that all files must be generated under the current Bazel package, so when setting plugin_out set it in a way that the resulting outputs are generated accordingly. |
String | optional | "" |
protoc | The protoc executable. | Label | optional | @com_google_protobuf//:protoc |
protos | The proto libraries to generate code for. | List of labels | optional | [] |
protoc_plugin(name, data, default_options, executable, predeclared_outputs, suffix)
Describes a generic protoc plugin.
This rule allows to describe and reuse configuration for a protoc plugin that either uses a suffix replacement approach or predeclared outputs to describe the files it generates.
See documentation for suffix
and predeclared_outputs
for more information.
ATTRIBUTES
Name | Description | Type | Mandatory | Default |
---|---|---|---|---|
name | A unique name for this target. | Name | required | |
data | Files that should be added to the execution environment whenever the plugin is run. | List of labels | optional | [] |
default_options | Options that should be passed to the plugin whenever it is run. Note that, if you are using protoc_output , there can also options be passed to the plugin using protoc_output s options attribute on a per target basis.For example: ["x=3", "y=5"] will be passed as
to the command line line when running protoc with the plugin ( <plugin-name> ). The options are subject to ctx.expanded_locations: For example, use
to obtain the runfile location of :my_data_file and passed it as config option to the plugin. :my_data_file must be passed in the data attribute for the expansion to work. Do not use the locations (note the s ) directive. |
List of strings | optional | [] |
executable | The plugin executable. | Label | optional | None |
predeclared_outputs | If true, the plugin is configured to accept a list of predeclared outputs when used in a protoc_output target. The list of predeclared outputs is passed in the outputs attribute of the protoc_output rule. |
Boolean | optional | False |
suffix | If set, the plugin is expected to generate one file per input file that is named after the input file but replaces the ".proto" suffix with the provided one. Either the suffix attribute or the predeclared_outputs attributes must be set, but not both at the same time. |
String | optional | "" |
Public providers for rules_protoc_gen.
ProtocPluginInfo(executable, default_options, runfiles, outputs, outputs_kwargs)
A protoc plugin.
FIELDS
Name | Description |
---|---|
executable | The plugin executable. |
default_options | Options passed to the plugin whenever it is run. For example: ["x=3", "y=5"] will be passed as
to the command line line when running protoc with the plugin ( <plugin-name> ). |
runfiles | Runfiles required by the executable. |
outputs | Function that derives the names of the files the plugin generates from a set of input files. The function signature is
where protos is a list of ProtoInfo providers, output_args is a list of strings and **kwargs are the providers outputs_kwargs .When using protoc_output the protos are obtain from the protos attribute and the outputs_attr are obtained from the outputs attribute. |
outputs_kwargs | Predefined keyword arguments passed to the output function. |