Add experimental C rules using upb. Closes #20

This commit is contained in:
Adam Liddell 2021-02-19 23:04:35 +00:00
parent 2297426c43
commit d62fad4e87
20 changed files with 487 additions and 1 deletions

View File

@ -6,6 +6,7 @@ tasks:
environment:
CC: clang
build_targets:
- "//c/..."
- "//cpp/..."
- "//csharp/..."
- "//d/..."
@ -85,6 +86,7 @@ tasks:
build_flags:
- "--copt=-DGRPC_BAZEL_BUILD"
build_targets:
- "//c/..."
- "//cpp/..."
- "//csharp/..."
- "//d/..."
@ -223,6 +225,46 @@ tasks:
build_targets:
- "//..."
working_directory: example/android/android_grpc_library
c_c_proto_compile_ubuntu1804:
name: 'c: c_proto_compile'
platform: ubuntu1804
build_targets:
- "//..."
working_directory: example/c/c_proto_compile
c_c_proto_compile_windows:
name: 'c: c_proto_compile'
platform: windows
build_targets:
- "//..."
working_directory: example/c/c_proto_compile
c_c_proto_compile_macos:
name: 'c: c_proto_compile'
platform: macos
build_flags:
- "--copt=-DGRPC_BAZEL_BUILD"
build_targets:
- "//..."
working_directory: example/c/c_proto_compile
c_c_proto_library_ubuntu1804:
name: 'c: c_proto_library'
platform: ubuntu1804
build_targets:
- "//..."
working_directory: example/c/c_proto_library
c_c_proto_library_windows:
name: 'c: c_proto_library'
platform: windows
build_targets:
- "//..."
working_directory: example/c/c_proto_library
c_c_proto_library_macos:
name: 'c: c_proto_library'
platform: macos
build_flags:
- "--copt=-DGRPC_BAZEL_BUILD"
build_targets:
- "//..."
working_directory: example/c/c_proto_library
cpp_cpp_proto_compile_ubuntu1804:
name: 'cpp: cpp_proto_compile'
platform: ubuntu1804

View File

@ -70,6 +70,9 @@ depend on it explicitly from the relevant top level binaries/libraries.
- **WORKSPACE update needed**: The WORKSPACE imports necessary for Android rules have been updated due to upstream
changes in `grpc-java`. Please see the examples for the latest WORKSPACE template for the Android rules
### C
- Added experimental rules for C using upb [#20](https://github.com/rules-proto-grpc/rules_proto_grpc/issues/20)
### C++
- Non-transitive mode resolves issue where the same proto may be defined more than once
[#25](https://github.com/rules-proto-grpc/rules_proto_grpc/issues/25)

View File

@ -35,6 +35,7 @@ Bazel 4.0 compatibility and updated dependencies are in progress.
- [Installation](#installation)
- [Rules](#rules)
- [Android](/android/README.md)
- [C](/c/README.md)
- [C++](/cpp/README.md)
- [C#](/csharp/README.md)
- [D](/d/README.md)
@ -126,6 +127,8 @@ repository.
| [Android](/android) | [android_grpc_compile](/android#android_grpc_compile) | Generates Android protobuf+gRPC `.jar` artifacts ([example](/example/android/android_grpc_compile)) |
| [Android](/android) | [android_proto_library](/android#android_proto_library) | Generates an Android protobuf library using `android_library` from `rules_android` ([example](/example/android/android_proto_library)) |
| [Android](/android) | [android_grpc_library](/android#android_grpc_library) | Generates Android protobuf+gRPC library using `android_library` from `rules_android` ([example](/example/android/android_grpc_library)) |
| [C](/c) | [c_proto_compile](/c#c_proto_compile) | Generates C protobuf `.h` & `.cc` artifacts ([example](/example/c/c_proto_compile)) |
| [C](/c) | [c_proto_library](/c#c_proto_library) | Generates a C protobuf library using `cc_library`, with dependencies linked ([example](/example/c/c_proto_library)) |
| [C++](/cpp) | [cpp_proto_compile](/cpp#cpp_proto_compile) | Generates C++ protobuf `.h` & `.cc` artifacts ([example](/example/cpp/cpp_proto_compile)) |
| [C++](/cpp) | [cpp_grpc_compile](/cpp#cpp_grpc_compile) | Generates C++ protobuf+gRPC `.h` & `.cc` artifacts ([example](/example/cpp/cpp_grpc_compile)) |
| [C++](/cpp) | [cpp_proto_library](/cpp#cpp_proto_library) | Generates a C++ protobuf library using `cc_library`, with dependencies linked ([example](/example/cpp/cpp_proto_library)) |

21
c/BUILD.bazel Normal file
View File

@ -0,0 +1,21 @@
load("//:defs.bzl", "proto_plugin")
proto_plugin(
name = "upb_plugin",
outputs = [
"{protopath}.upb.h",
"{protopath}.upb.c",
],
tool = "@upb//upbc:protoc-gen-upb",
visibility = ["//visibility:public"],
)
proto_plugin(
name = "upbdefs_plugin",
outputs = [
"{protopath}.upbdefs.h",
"{protopath}.upbdefs.c",
],
tool = "@upb//upbc:protoc-gen-upbdefs",
visibility = ["//visibility:public"],
)

111
c/README.md Normal file
View File

@ -0,0 +1,111 @@
# C rules
Rules for generating C protobuf `.c` & `.h` files and libraries using [upb](https://github.com/protocolbuffers/upb). Libraries are created with the Bazel native `cc_library`
| Rule | Description |
| ---: | :--- |
| [c_proto_compile](#c_proto_compile) | Generates C protobuf `.h` & `.cc` artifacts |
| [c_proto_library](#c_proto_library) | Generates a C protobuf library using `cc_library`, with dependencies linked |
---
## `c_proto_compile`
> NOTE: this rule is EXPERIMENTAL. It may not work correctly or even compile!
Generates C protobuf `.h` & `.cc` artifacts
### `WORKSPACE`
```starlark
load("@rules_proto_grpc//c:repositories.bzl", rules_proto_grpc_c_repos = "c_repos")
rules_proto_grpc_c_repos()
load("@upb//bazel:workspace_deps.bzl", "upb_deps")
upb_deps()
```
### `BUILD.bazel`
```starlark
load("@rules_proto_grpc//c:defs.bzl", "c_proto_compile")
c_proto_compile(
name = "person_c_proto",
protos = ["@rules_proto_grpc//example/proto:person_proto"],
)
c_proto_compile(
name = "place_c_proto",
protos = ["@rules_proto_grpc//example/proto:place_proto"],
)
c_proto_compile(
name = "thing_c_proto",
protos = ["@rules_proto_grpc//example/proto:thing_proto"],
)
```
### Attributes
| Name | Type | Mandatory | Default | Description |
| ---: | :--- | --------- | ------- | ----------- |
| `protos` | `list<ProtoInfo>` | true | `[]` | List of labels that provide a `ProtoInfo` (such as `rules_proto` `proto_library`) |
| `options` | `dict<string, list(string)>` | false | `[]` | Extra options to pass to plugins, as a dict of plugin label -> list of strings. The key * can be used exclusively to apply to all plugins |
| `verbose` | `int` | false | `0` | The verbosity level. Supported values and results are 1: *show command*, 2: *show command and sandbox after running protoc*, 3: *show command and sandbox before and after running protoc*, 4. *show env, command, expected outputs and sandbox before and after running protoc* |
| `prefix_path` | `string` | false | `` | Path to prefix to the generated files in the output directory |
| `extra_protoc_args` | `list<string>` | false | `[]` | A list of extra args to pass directly to protoc, not as plugin options |
### Plugins
- `@rules_proto_grpc//c:upb_plugin`
---
## `c_proto_library`
> NOTE: this rule is EXPERIMENTAL. It may not work correctly or even compile!
Generates a C protobuf library using `cc_library`, with dependencies linked
### `WORKSPACE`
```starlark
load("@rules_proto_grpc//c:repositories.bzl", rules_proto_grpc_c_repos = "c_repos")
rules_proto_grpc_c_repos()
load("@upb//bazel:workspace_deps.bzl", "upb_deps")
upb_deps()
```
### `BUILD.bazel`
```starlark
load("@rules_proto_grpc//c:defs.bzl", "c_proto_library")
c_proto_library(
name = "proto_c_proto",
importpath = "github.com/rules-proto-grpc/rules_proto_grpc/example/proto",
protos = [
"@rules_proto_grpc//example/proto:person_proto",
"@rules_proto_grpc//example/proto:place_proto",
"@rules_proto_grpc//example/proto:thing_proto",
"@com_google_protobuf//:any_proto",
],
)
```
### Attributes
| Name | Type | Mandatory | Default | Description |
| ---: | :--- | --------- | ------- | ----------- |
| `protos` | `list<ProtoInfo>` | true | `[]` | List of labels that provide a `ProtoInfo` (such as `rules_proto` `proto_library`) |
| `options` | `dict<string, list(string)>` | false | `[]` | Extra options to pass to plugins, as a dict of plugin label -> list of strings. The key * can be used exclusively to apply to all plugins |
| `verbose` | `int` | false | `0` | The verbosity level. Supported values and results are 1: *show command*, 2: *show command and sandbox after running protoc*, 3: *show command and sandbox before and after running protoc*, 4. *show env, command, expected outputs and sandbox before and after running protoc* |
| `prefix_path` | `string` | false | `` | Path to prefix to the generated files in the output directory |
| `extra_protoc_args` | `list<string>` | false | `[]` | A list of extra args to pass directly to protoc, not as plugin options |
| `deps` | `list<Label/string>` | false | `[]` | List of labels to pass as deps attr to underlying lang_library rule |

68
c/c_proto_compile.bzl Normal file
View File

@ -0,0 +1,68 @@
"""Generated definition of c_proto_compile."""
load("@rules_proto//proto:defs.bzl", "ProtoInfo")
load(
"//:defs.bzl",
"ProtoLibraryAspectNodeInfo",
"ProtoPluginInfo",
"proto_compile_aspect_attrs",
"proto_compile_aspect_impl",
"proto_compile_attrs",
"proto_compile_impl",
)
# Create aspect for c_proto_compile
c_proto_compile_aspect = aspect(
implementation = proto_compile_aspect_impl,
provides = [ProtoLibraryAspectNodeInfo],
attr_aspects = ["deps"],
attrs = dict(
proto_compile_aspect_attrs,
_plugins = attr.label_list(
doc = "List of protoc plugins to apply",
providers = [ProtoPluginInfo],
default = [
Label("//c:upb_plugin"),
],
),
_prefix = attr.string(
doc = "String used to disambiguate aspects when generating outputs",
default = "c_proto_compile_aspect",
),
),
toolchains = [str(Label("//protobuf:toolchain_type"))],
)
# Create compile rule to apply aspect
_rule = rule(
implementation = proto_compile_impl,
attrs = dict(
proto_compile_attrs,
protos = attr.label_list(
mandatory = False, # TODO: set to true in 4.0.0 when deps removed below
providers = [ProtoInfo],
doc = "List of labels that provide a ProtoInfo (such as rules_proto proto_library)",
),
deps = attr.label_list(
mandatory = False,
providers = [ProtoInfo, ProtoLibraryAspectNodeInfo],
aspects = [c_proto_compile_aspect],
doc = "DEPRECATED: Use protos attr",
),
_plugins = attr.label_list(
doc = "List of protoc plugins to apply",
providers = [ProtoPluginInfo],
default = [
Label("//c:upb_plugin"),
],
),
),
toolchains = [str(Label("//protobuf:toolchain_type"))],
)
# Create macro for converting attrs and passing to compile
def c_proto_compile(**kwargs):
_rule(
verbose_string = "{}".format(kwargs.get("verbose", 0)),
**kwargs
)

31
c/c_proto_library.bzl Normal file
View File

@ -0,0 +1,31 @@
"""Generated definition of c_proto_library."""
load("//c:c_proto_compile.bzl", "c_proto_compile")
load("//internal:compile.bzl", "proto_compile_attrs")
load("@rules_cc//cc:defs.bzl", "cc_library")
def c_proto_library(**kwargs):
# Compile protos
name_pb = kwargs.get("name") + "_pb"
c_proto_compile(
name = name_pb,
**{
k: v
for (k, v) in kwargs.items()
if k in ["protos" if "protos" in kwargs else "deps"] + proto_compile_attrs.keys()
} # Forward args
)
# Create c library
cc_library(
name = kwargs.get("name"),
srcs = [name_pb],
deps = PROTO_DEPS + (kwargs.get("deps", []) if "protos" in kwargs else []),
includes = [name_pb],
visibility = kwargs.get("visibility"),
tags = kwargs.get("tags"),
)
PROTO_DEPS = [
"@upb//:upb",
]

8
c/defs.bzl Normal file
View File

@ -0,0 +1,8 @@
"""c protobuf and grpc rules."""
load(":c_proto_compile.bzl", _c_proto_compile = "c_proto_compile")
load(":c_proto_library.bzl", _c_proto_library = "c_proto_library")
# Export c rules
c_proto_compile = _c_proto_compile
c_proto_library = _c_proto_library

11
c/repositories.bzl Normal file
View File

@ -0,0 +1,11 @@
"""Common dependencies for rules_proto_grpc C rules."""
load(
"//:repositories.bzl",
"rules_proto_grpc_repos",
"upb",
)
def c_repos(**kwargs): # buildifier: disable=function-docstring
rules_proto_grpc_repos(**kwargs)
upb(**kwargs)

View File

@ -21,6 +21,19 @@ android_android_grpc_library_example:
.PHONY: android_examples
android_examples: android_android_proto_compile_example android_android_grpc_compile_example android_android_proto_library_example android_android_grpc_library_example
.PHONY: c_c_proto_compile_example
c_c_proto_compile_example:
cd example/c/c_proto_compile; \
bazel --batch build --verbose_failures --disk_cache=../../bazel-disk-cache //...
.PHONY: c_c_proto_library_example
c_c_proto_library_example:
cd example/c/c_proto_library; \
bazel --batch build --verbose_failures --disk_cache=../../bazel-disk-cache //...
.PHONY: c_examples
c_examples: c_c_proto_compile_example c_c_proto_library_example
.PHONY: cpp_cpp_proto_compile_example
cpp_cpp_proto_compile_example:
cd example/cpp/cpp_proto_compile; \
@ -334,4 +347,4 @@ swift_swift_grpc_library_example:
swift_examples: swift_swift_proto_compile_example swift_swift_grpc_compile_example swift_swift_proto_library_example swift_swift_grpc_library_example
.PHONY: all_examples
all_examples: android_android_proto_compile_example android_android_grpc_compile_example android_android_proto_library_example android_android_grpc_library_example cpp_cpp_proto_compile_example cpp_cpp_grpc_compile_example cpp_cpp_proto_library_example cpp_cpp_grpc_library_example csharp_csharp_proto_compile_example csharp_csharp_grpc_compile_example csharp_csharp_proto_library_example csharp_csharp_grpc_library_example d_d_proto_compile_example d_d_proto_library_example go_go_proto_compile_example go_go_grpc_compile_example go_go_proto_library_example go_go_grpc_library_example grpc-gateway_gateway_grpc_compile_example grpc-gateway_gateway_openapiv2_compile_example grpc-gateway_gateway_grpc_library_example java_java_proto_compile_example java_java_grpc_compile_example java_java_proto_library_example java_java_grpc_library_example js_js_proto_compile_example js_js_grpc_node_compile_example js_js_grpc_web_compile_example js_js_proto_library_example js_js_grpc_node_library_example js_js_grpc_web_library_example objc_objc_proto_compile_example objc_objc_grpc_compile_example objc_objc_proto_library_example php_php_proto_compile_example php_php_grpc_compile_example python_python_proto_compile_example python_python_grpc_compile_example python_python_grpclib_compile_example python_python_proto_library_example python_python_grpc_library_example python_python_grpclib_library_example ruby_ruby_proto_compile_example ruby_ruby_grpc_compile_example ruby_ruby_proto_library_example ruby_ruby_grpc_library_example rust_rust_proto_compile_example rust_rust_grpc_compile_example rust_rust_proto_library_example rust_rust_grpc_library_example scala_scala_proto_compile_example scala_scala_grpc_compile_example scala_scala_proto_library_example scala_scala_grpc_library_example swift_swift_proto_compile_example swift_swift_grpc_compile_example swift_swift_proto_library_example swift_swift_grpc_library_example
all_examples: android_android_proto_compile_example android_android_grpc_compile_example android_android_proto_library_example android_android_grpc_library_example c_c_proto_compile_example c_c_proto_library_example cpp_cpp_proto_compile_example cpp_cpp_grpc_compile_example cpp_cpp_proto_library_example cpp_cpp_grpc_library_example csharp_csharp_proto_compile_example csharp_csharp_grpc_compile_example csharp_csharp_proto_library_example csharp_csharp_grpc_library_example d_d_proto_compile_example d_d_proto_library_example go_go_proto_compile_example go_go_grpc_compile_example go_go_proto_library_example go_go_grpc_library_example grpc-gateway_gateway_grpc_compile_example grpc-gateway_gateway_openapiv2_compile_example grpc-gateway_gateway_grpc_library_example java_java_proto_compile_example java_java_grpc_compile_example java_java_proto_library_example java_java_grpc_library_example js_js_proto_compile_example js_js_grpc_node_compile_example js_js_grpc_web_compile_example js_js_proto_library_example js_js_grpc_node_library_example js_js_grpc_web_library_example objc_objc_proto_compile_example objc_objc_grpc_compile_example objc_objc_proto_library_example php_php_proto_compile_example php_php_grpc_compile_example python_python_proto_compile_example python_python_grpc_compile_example python_python_grpclib_compile_example python_python_proto_library_example python_python_grpc_library_example python_python_grpclib_library_example ruby_ruby_proto_compile_example ruby_ruby_grpc_compile_example ruby_ruby_proto_library_example ruby_ruby_grpc_library_example rust_rust_proto_compile_example rust_rust_grpc_compile_example rust_rust_proto_library_example rust_rust_grpc_library_example scala_scala_proto_compile_example scala_scala_grpc_compile_example scala_scala_proto_library_example scala_scala_grpc_library_example swift_swift_proto_compile_example swift_swift_grpc_compile_example swift_swift_proto_library_example swift_swift_grpc_library_example

View File

View File

@ -0,0 +1,16 @@
load("@rules_proto_grpc//c:defs.bzl", "c_proto_compile")
c_proto_compile(
name = "person_c_proto",
protos = ["@rules_proto_grpc//example/proto:person_proto"],
)
c_proto_compile(
name = "place_c_proto",
protos = ["@rules_proto_grpc//example/proto:place_proto"],
)
c_proto_compile(
name = "thing_c_proto",
protos = ["@rules_proto_grpc//example/proto:thing_proto"],
)

View File

@ -0,0 +1,24 @@
local_repository(
name = "rules_proto_grpc",
path = "../../../",
)
load("@rules_proto_grpc//:repositories.bzl", "rules_proto_grpc_repos", "rules_proto_grpc_toolchains")
rules_proto_grpc_toolchains()
rules_proto_grpc_repos()
load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains")
rules_proto_dependencies()
rules_proto_toolchains()
load("@rules_proto_grpc//c:repositories.bzl", rules_proto_grpc_c_repos = "c_repos")
rules_proto_grpc_c_repos()
load("@upb//bazel:workspace_deps.bzl", "upb_deps")
upb_deps()

View File

View File

@ -0,0 +1,12 @@
load("@rules_proto_grpc//c:defs.bzl", "c_proto_library")
c_proto_library(
name = "proto_c_proto",
importpath = "github.com/rules-proto-grpc/rules_proto_grpc/example/proto",
protos = [
"@rules_proto_grpc//example/proto:person_proto",
"@rules_proto_grpc//example/proto:place_proto",
"@rules_proto_grpc//example/proto:thing_proto",
"@com_google_protobuf//:any_proto",
],
)

View File

@ -0,0 +1,24 @@
local_repository(
name = "rules_proto_grpc",
path = "../../../",
)
load("@rules_proto_grpc//:repositories.bzl", "rules_proto_grpc_repos", "rules_proto_grpc_toolchains")
rules_proto_grpc_toolchains()
rules_proto_grpc_repos()
load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains")
rules_proto_dependencies()
rules_proto_toolchains()
load("@rules_proto_grpc//c:repositories.bzl", rules_proto_grpc_c_repos = "c_repos")
rules_proto_grpc_c_repos()
load("@upb//bazel:workspace_deps.bzl", "upb_deps")
upb_deps()

View File

@ -82,6 +82,15 @@ VERSIONS = {
"sha256": "f329928c62ade05ceda72c4e145fd300722e6e592627d43580dd0a8211c14612",
},
# C
"upb": {
"type": "github",
"org": "protocolbuffers",
"repo": "upb",
"ref": "eb0fdda14b7b211872507a66f7d988f7c24a44c9",
"sha256": "843d0729a0cb53fa2afb46b1c262438beb7477696f31e2fbfd84de97a710f2f1",
},
# C#
"io_bazel_rules_dotnet": {
"type": "github",
@ -417,6 +426,12 @@ def bazel_skylib(**kwargs):
def build_bazel_rules_android(**kwargs):
_generic_dependency("build_bazel_rules_android", **kwargs)
#
# C
#
def upb(**kwargs):
_generic_dependency("upb", **kwargs)
#
# C#
#

View File

@ -35,6 +35,7 @@ Bazel 4.0 compatibility and updated dependencies are in progress.
- [Installation](#installation)
- [Rules](#rules)
- [Android](/android/README.md)
- [C](/c/README.md)
- [C++](/cpp/README.md)
- [C#](/csharp/README.md)
- [D](/d/README.md)

82
tools/rulegen/c.go Normal file
View File

@ -0,0 +1,82 @@
package main
var cWorkspaceTemplate = mustTemplate(`load("@rules_proto_grpc//{{ .Lang.Dir }}:repositories.bzl", rules_proto_grpc_{{ .Lang.Name }}_repos = "{{ .Lang.Name }}_repos")
rules_proto_grpc_{{ .Lang.Name }}_repos()
load("@upb//bazel:workspace_deps.bzl", "upb_deps")
upb_deps()`)
var cProtoLibraryRuleTemplate = mustTemplate(`load("//{{ .Lang.Dir }}:{{ .Lang.Name }}_{{ .Rule.Kind }}_compile.bzl", "{{ .Lang.Name }}_{{ .Rule.Kind }}_compile")
load("//internal:compile.bzl", "proto_compile_attrs")
load("@rules_cc//cc:defs.bzl", "cc_library")
def {{ .Rule.Name }}(**kwargs):
# Compile protos
name_pb = kwargs.get("name") + "_pb"
{{ .Lang.Name }}_{{ .Rule.Kind }}_compile(
name = name_pb,
{{ .Common.ArgsForwardingSnippet }}
)
# Create {{ .Lang.Name }} library
cc_library(
name = kwargs.get("name"),
srcs = [name_pb],
deps = PROTO_DEPS + (kwargs.get("deps", []) if "protos" in kwargs else []),
includes = [name_pb],
visibility = kwargs.get("visibility"),
tags = kwargs.get("tags"),
)
PROTO_DEPS = [
"@upb//:upb",
]`)
// For C, we need to manually generate the files for any.proto
var cProtoLibraryExampleTemplate = mustTemplate(`load("@rules_proto_grpc//{{ .Lang.Dir }}:defs.bzl", "{{ .Rule.Name }}")
{{ .Rule.Name }}(
name = "proto_{{ .Lang.Name }}_{{ .Rule.Kind }}",
importpath = "github.com/rules-proto-grpc/rules_proto_grpc/example/proto",
protos = [
"@rules_proto_grpc//example/proto:person_proto",
"@rules_proto_grpc//example/proto:place_proto",
"@rules_proto_grpc//example/proto:thing_proto",
"@com_google_protobuf//:any_proto",
],
)`)
func makeC() *Language {
return &Language{
Dir: "c",
Name: "c",
DisplayName: "C",
Notes: mustTemplate("Rules for generating C protobuf `.c` & `.h` files and libraries using [upb](https://github.com/protocolbuffers/upb). Libraries are created with the Bazel native `cc_library`"),
Flags: commonLangFlags,
Rules: []*Rule{
&Rule{
Name: "c_proto_compile",
Kind: "proto",
Implementation: aspectRuleTemplate,
Plugins: []string{"//c:upb_plugin"},
WorkspaceExample: cWorkspaceTemplate,
BuildExample: protoCompileExampleTemplate,
Doc: "Generates C protobuf `.h` & `.cc` artifacts",
Attrs: compileRuleAttrs,
Experimental: true,
},
&Rule{
Name: "c_proto_library",
Kind: "proto",
Implementation: cProtoLibraryRuleTemplate,
WorkspaceExample: cWorkspaceTemplate,
BuildExample: cProtoLibraryExampleTemplate,
Doc: "Generates a C protobuf library using `cc_library`, with dependencies linked",
Attrs: libraryRuleAttrs,
Experimental: true,
},
},
}
}

View File

@ -92,6 +92,7 @@ func action(c *cli.Context) error {
languages := []*Language{
makeAndroid(),
makeC(),
makeCpp(),
makeCsharp(),
makeD(),