1*d4726bddSHONG Yifan# Copyright 2018 The Bazel Authors. All rights reserved. 2*d4726bddSHONG Yifan# 3*d4726bddSHONG Yifan# Licensed under the Apache License, Version 2.0 (the "License"); 4*d4726bddSHONG Yifan# you may not use this file except in compliance with the License. 5*d4726bddSHONG Yifan# You may obtain a copy of the License at 6*d4726bddSHONG Yifan# 7*d4726bddSHONG Yifan# http://www.apache.org/licenses/LICENSE-2.0 8*d4726bddSHONG Yifan# 9*d4726bddSHONG Yifan# Unless required by applicable law or agreed to in writing, software 10*d4726bddSHONG Yifan# distributed under the License is distributed on an "AS IS" BASIS, 11*d4726bddSHONG Yifan# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*d4726bddSHONG Yifan# See the License for the specific language governing permissions and 13*d4726bddSHONG Yifan# limitations under the License. 14*d4726bddSHONG Yifan 15*d4726bddSHONG Yifan"""Rust Protobuf Rules""" 16*d4726bddSHONG Yifan 17*d4726bddSHONG Yifanload("@rules_proto//proto:defs.bzl", "ProtoInfo") 18*d4726bddSHONG Yifanload( 19*d4726bddSHONG Yifan "//proto/protobuf:toolchain.bzl", 20*d4726bddSHONG Yifan _generate_proto = "rust_generate_proto", 21*d4726bddSHONG Yifan _generated_file_stem = "generated_file_stem", 22*d4726bddSHONG Yifan) 23*d4726bddSHONG Yifan 24*d4726bddSHONG Yifan# buildifier: disable=bzl-visibility 25*d4726bddSHONG Yifanload("//rust/private:rustc.bzl", "rustc_compile_action") 26*d4726bddSHONG Yifan 27*d4726bddSHONG Yifan# buildifier: disable=bzl-visibility 28*d4726bddSHONG Yifanload("//rust/private:utils.bzl", "can_build_metadata", "compute_crate_name", "determine_output_hash", "find_toolchain", "transform_deps") 29*d4726bddSHONG Yifan 30*d4726bddSHONG YifanRustProtoInfo = provider( 31*d4726bddSHONG Yifan doc = "Rust protobuf provider info", 32*d4726bddSHONG Yifan fields = { 33*d4726bddSHONG Yifan "proto_sources": "List[string]: list of source paths of protos", 34*d4726bddSHONG Yifan "transitive_proto_sources": "depset[string]", 35*d4726bddSHONG Yifan }, 36*d4726bddSHONG Yifan) 37*d4726bddSHONG Yifan 38*d4726bddSHONG Yifandef _compute_proto_source_path(file, source_root_attr): 39*d4726bddSHONG Yifan """Take the short path of file and make it suitable for protoc. 40*d4726bddSHONG Yifan 41*d4726bddSHONG Yifan Args: 42*d4726bddSHONG Yifan file (File): The target source file. 43*d4726bddSHONG Yifan source_root_attr (str): The directory relative to which the `.proto` \ 44*d4726bddSHONG Yifan files defined in the proto_library are defined. 45*d4726bddSHONG Yifan 46*d4726bddSHONG Yifan Returns: 47*d4726bddSHONG Yifan str: The protoc suitible path of `file` 48*d4726bddSHONG Yifan """ 49*d4726bddSHONG Yifan 50*d4726bddSHONG Yifan # Bazel creates symlinks to the .proto files under a directory called 51*d4726bddSHONG Yifan # "_virtual_imports/<rule name>" if we do any sort of munging of import 52*d4726bddSHONG Yifan # paths (e.g. using strip_import_prefix / import_prefix attributes) 53*d4726bddSHONG Yifan virtual_imports = "/_virtual_imports/" 54*d4726bddSHONG Yifan if virtual_imports in file.path: 55*d4726bddSHONG Yifan return file.path.split(virtual_imports)[1].split("/", 1)[1] 56*d4726bddSHONG Yifan 57*d4726bddSHONG Yifan # For proto, they need to be requested with their absolute name to be 58*d4726bddSHONG Yifan # compatible with the descriptor_set passed by proto_library. 59*d4726bddSHONG Yifan # I.e. if you compile a protobuf at @repo1//package:file.proto, the proto 60*d4726bddSHONG Yifan # compiler would generate a file descriptor with the path 61*d4726bddSHONG Yifan # `package/file.proto`. Since we compile from the proto descriptor, we need 62*d4726bddSHONG Yifan # to pass the list of descriptors and the list of path to compile. 63*d4726bddSHONG Yifan # For the precedent example, the file (noted `f`) would have 64*d4726bddSHONG Yifan # `f.short_path` returns `external/repo1/package/file.proto`. 65*d4726bddSHONG Yifan # In addition, proto_library can provide a proto_source_path to change the base 66*d4726bddSHONG Yifan # path, which should a be a prefix. 67*d4726bddSHONG Yifan path = file.short_path 68*d4726bddSHONG Yifan 69*d4726bddSHONG Yifan # Strip external prefix. 70*d4726bddSHONG Yifan path = path.split("/", 2)[2] if path.startswith("../") else path 71*d4726bddSHONG Yifan 72*d4726bddSHONG Yifan # Strip source_root. 73*d4726bddSHONG Yifan if path.startswith(source_root_attr): 74*d4726bddSHONG Yifan return path[len(source_root_attr):] 75*d4726bddSHONG Yifan else: 76*d4726bddSHONG Yifan return path 77*d4726bddSHONG Yifan 78*d4726bddSHONG Yifandef _rust_proto_aspect_impl(target, ctx): 79*d4726bddSHONG Yifan """The implementation of the `rust_proto_aspect` aspect 80*d4726bddSHONG Yifan 81*d4726bddSHONG Yifan Args: 82*d4726bddSHONG Yifan target (Target): The target to which the aspect is applied 83*d4726bddSHONG Yifan ctx (ctx): The rule context which the targetis created from 84*d4726bddSHONG Yifan 85*d4726bddSHONG Yifan Returns: 86*d4726bddSHONG Yifan list: A list containg a `RustProtoInfo` provider 87*d4726bddSHONG Yifan """ 88*d4726bddSHONG Yifan if ProtoInfo not in target: 89*d4726bddSHONG Yifan return None 90*d4726bddSHONG Yifan 91*d4726bddSHONG Yifan if hasattr(ctx.rule.attr, "proto_source_root"): 92*d4726bddSHONG Yifan source_root = ctx.rule.attr.proto_source_root 93*d4726bddSHONG Yifan else: 94*d4726bddSHONG Yifan source_root = "" 95*d4726bddSHONG Yifan 96*d4726bddSHONG Yifan if source_root and source_root[-1] != "/": 97*d4726bddSHONG Yifan source_root += "/" 98*d4726bddSHONG Yifan 99*d4726bddSHONG Yifan sources = [ 100*d4726bddSHONG Yifan _compute_proto_source_path(f, source_root) 101*d4726bddSHONG Yifan for f in target[ProtoInfo].direct_sources 102*d4726bddSHONG Yifan ] 103*d4726bddSHONG Yifan transitive_sources = [ 104*d4726bddSHONG Yifan f[RustProtoInfo].transitive_proto_sources 105*d4726bddSHONG Yifan for f in ctx.rule.attr.deps 106*d4726bddSHONG Yifan if RustProtoInfo in f 107*d4726bddSHONG Yifan ] 108*d4726bddSHONG Yifan return [RustProtoInfo( 109*d4726bddSHONG Yifan proto_sources = sources, 110*d4726bddSHONG Yifan transitive_proto_sources = depset(transitive = transitive_sources, direct = sources), 111*d4726bddSHONG Yifan )] 112*d4726bddSHONG Yifan 113*d4726bddSHONG Yifan_rust_proto_aspect = aspect( 114*d4726bddSHONG Yifan doc = "An aspect that gathers rust proto direct and transitive sources", 115*d4726bddSHONG Yifan implementation = _rust_proto_aspect_impl, 116*d4726bddSHONG Yifan attr_aspects = ["deps"], 117*d4726bddSHONG Yifan) 118*d4726bddSHONG Yifan 119*d4726bddSHONG Yifandef _gen_lib(ctx, grpc, srcs, lib): 120*d4726bddSHONG Yifan """Generate a lib.rs file for the crates. 121*d4726bddSHONG Yifan 122*d4726bddSHONG Yifan Args: 123*d4726bddSHONG Yifan ctx (ctx): The current rule's context object 124*d4726bddSHONG Yifan grpc (bool): True if the current rule is a `gRPC` rule. 125*d4726bddSHONG Yifan srcs (list): A list of protoc suitible file paths (str). 126*d4726bddSHONG Yifan lib (File): The File object where the rust source file should be written 127*d4726bddSHONG Yifan """ 128*d4726bddSHONG Yifan content = ["extern crate protobuf;"] 129*d4726bddSHONG Yifan if grpc: 130*d4726bddSHONG Yifan content.append("extern crate grpc;") 131*d4726bddSHONG Yifan content.append("extern crate tls_api;") 132*d4726bddSHONG Yifan for f in srcs.to_list(): 133*d4726bddSHONG Yifan content.append("pub mod %s;" % _generated_file_stem(f)) 134*d4726bddSHONG Yifan content.append("pub use %s::*;" % _generated_file_stem(f)) 135*d4726bddSHONG Yifan if grpc: 136*d4726bddSHONG Yifan content.append("pub mod %s_grpc;" % _generated_file_stem(f)) 137*d4726bddSHONG Yifan content.append("pub use %s_grpc::*;" % _generated_file_stem(f)) 138*d4726bddSHONG Yifan ctx.actions.write(lib, "\n".join(content)) 139*d4726bddSHONG Yifan 140*d4726bddSHONG Yifandef _expand_provider(lst, provider): 141*d4726bddSHONG Yifan """Gathers a list of a specific provider from a list of targets. 142*d4726bddSHONG Yifan 143*d4726bddSHONG Yifan Args: 144*d4726bddSHONG Yifan lst (list): A list of Targets 145*d4726bddSHONG Yifan provider (Provider): The target provider type to extract `lst` 146*d4726bddSHONG Yifan 147*d4726bddSHONG Yifan Returns: 148*d4726bddSHONG Yifan list: A list of providers of the type from `provider`. 149*d4726bddSHONG Yifan """ 150*d4726bddSHONG Yifan return [el[provider] for el in lst if provider in el] 151*d4726bddSHONG Yifan 152*d4726bddSHONG Yifandef _rust_proto_compile(protos, descriptor_sets, imports, crate_name, ctx, is_grpc, compile_deps, toolchain): 153*d4726bddSHONG Yifan """Create and run a rustc compile action based on the current rule's attributes 154*d4726bddSHONG Yifan 155*d4726bddSHONG Yifan Args: 156*d4726bddSHONG Yifan protos (depset): Paths of protos to compile. 157*d4726bddSHONG Yifan descriptor_sets (depset): A set of transitive protobuf `FileDescriptorSet`s 158*d4726bddSHONG Yifan imports (depset): A set of transitive protobuf Imports. 159*d4726bddSHONG Yifan crate_name (str): The name of the Crate for the current target 160*d4726bddSHONG Yifan ctx (ctx): The current rule's context object 161*d4726bddSHONG Yifan is_grpc (bool): True if the current rule is a `gRPC` rule. 162*d4726bddSHONG Yifan compile_deps (list): A list of Rust dependencies (`List[Target]`) 163*d4726bddSHONG Yifan toolchain (rust_toolchain): the current `rust_toolchain`. 164*d4726bddSHONG Yifan 165*d4726bddSHONG Yifan Returns: 166*d4726bddSHONG Yifan list: A list of providers, see `rustc_compile_action` 167*d4726bddSHONG Yifan """ 168*d4726bddSHONG Yifan 169*d4726bddSHONG Yifan # Create all the source in a specific folder 170*d4726bddSHONG Yifan proto_toolchain = ctx.toolchains[Label("//proto/protobuf:toolchain_type")] 171*d4726bddSHONG Yifan output_dir = "%s.%s.rust" % (crate_name, "grpc" if is_grpc else "proto") 172*d4726bddSHONG Yifan 173*d4726bddSHONG Yifan # Generate the proto stubs 174*d4726bddSHONG Yifan srcs = _generate_proto( 175*d4726bddSHONG Yifan ctx, 176*d4726bddSHONG Yifan descriptor_sets, 177*d4726bddSHONG Yifan protos = protos, 178*d4726bddSHONG Yifan imports = imports, 179*d4726bddSHONG Yifan output_dir = output_dir, 180*d4726bddSHONG Yifan proto_toolchain = proto_toolchain, 181*d4726bddSHONG Yifan is_grpc = is_grpc, 182*d4726bddSHONG Yifan ) 183*d4726bddSHONG Yifan 184*d4726bddSHONG Yifan # and lib.rs 185*d4726bddSHONG Yifan lib_rs = ctx.actions.declare_file("%s/lib.rs" % output_dir) 186*d4726bddSHONG Yifan _gen_lib(ctx, is_grpc, protos, lib_rs) 187*d4726bddSHONG Yifan srcs.append(lib_rs) 188*d4726bddSHONG Yifan 189*d4726bddSHONG Yifan # And simulate rust_library behavior 190*d4726bddSHONG Yifan output_hash = determine_output_hash(lib_rs, ctx.label) 191*d4726bddSHONG Yifan rust_lib = ctx.actions.declare_file("%s/lib%s-%s.rlib" % ( 192*d4726bddSHONG Yifan output_dir, 193*d4726bddSHONG Yifan crate_name, 194*d4726bddSHONG Yifan output_hash, 195*d4726bddSHONG Yifan )) 196*d4726bddSHONG Yifan rust_metadata = None 197*d4726bddSHONG Yifan if can_build_metadata(toolchain, ctx, "rlib"): 198*d4726bddSHONG Yifan rust_metadata = ctx.actions.declare_file("%s/lib%s-%s.rmeta" % ( 199*d4726bddSHONG Yifan output_dir, 200*d4726bddSHONG Yifan crate_name, 201*d4726bddSHONG Yifan output_hash, 202*d4726bddSHONG Yifan )) 203*d4726bddSHONG Yifan 204*d4726bddSHONG Yifan # Gather all dependencies for compilation 205*d4726bddSHONG Yifan compile_action_deps = depset( 206*d4726bddSHONG Yifan transform_deps( 207*d4726bddSHONG Yifan compile_deps + 208*d4726bddSHONG Yifan proto_toolchain.grpc_compile_deps if is_grpc else proto_toolchain.proto_compile_deps, 209*d4726bddSHONG Yifan ), 210*d4726bddSHONG Yifan ) 211*d4726bddSHONG Yifan 212*d4726bddSHONG Yifan providers = rustc_compile_action( 213*d4726bddSHONG Yifan ctx = ctx, 214*d4726bddSHONG Yifan attr = ctx.attr, 215*d4726bddSHONG Yifan toolchain = toolchain, 216*d4726bddSHONG Yifan crate_info_dict = dict( 217*d4726bddSHONG Yifan name = crate_name, 218*d4726bddSHONG Yifan type = "rlib", 219*d4726bddSHONG Yifan root = lib_rs, 220*d4726bddSHONG Yifan srcs = depset(srcs), 221*d4726bddSHONG Yifan deps = compile_action_deps, 222*d4726bddSHONG Yifan proc_macro_deps = depset([]), 223*d4726bddSHONG Yifan aliases = {}, 224*d4726bddSHONG Yifan output = rust_lib, 225*d4726bddSHONG Yifan metadata = rust_metadata, 226*d4726bddSHONG Yifan edition = proto_toolchain.edition, 227*d4726bddSHONG Yifan rustc_env = {}, 228*d4726bddSHONG Yifan is_test = False, 229*d4726bddSHONG Yifan compile_data = depset([target.files for target in getattr(ctx.attr, "compile_data", [])]), 230*d4726bddSHONG Yifan compile_data_targets = depset(getattr(ctx.attr, "compile_data", [])), 231*d4726bddSHONG Yifan wrapped_crate_type = None, 232*d4726bddSHONG Yifan owner = ctx.label, 233*d4726bddSHONG Yifan ), 234*d4726bddSHONG Yifan output_hash = output_hash, 235*d4726bddSHONG Yifan ) 236*d4726bddSHONG Yifan providers.append(OutputGroupInfo(rust_generated_srcs = srcs)) 237*d4726bddSHONG Yifan return providers 238*d4726bddSHONG Yifan 239*d4726bddSHONG Yifandef _rust_protogrpc_library_impl(ctx, is_grpc): 240*d4726bddSHONG Yifan """Implementation of the rust_(proto|grpc)_library. 241*d4726bddSHONG Yifan 242*d4726bddSHONG Yifan Args: 243*d4726bddSHONG Yifan ctx (ctx): The current rule's context object 244*d4726bddSHONG Yifan is_grpc (bool): True if the current rule is a `gRPC` rule. 245*d4726bddSHONG Yifan 246*d4726bddSHONG Yifan Returns: 247*d4726bddSHONG Yifan list: A list of providers, see `_rust_proto_compile` 248*d4726bddSHONG Yifan """ 249*d4726bddSHONG Yifan proto = _expand_provider(ctx.attr.deps, ProtoInfo) 250*d4726bddSHONG Yifan transitive_sources = [ 251*d4726bddSHONG Yifan f[RustProtoInfo].transitive_proto_sources 252*d4726bddSHONG Yifan for f in ctx.attr.deps 253*d4726bddSHONG Yifan if RustProtoInfo in f 254*d4726bddSHONG Yifan ] 255*d4726bddSHONG Yifan 256*d4726bddSHONG Yifan toolchain = find_toolchain(ctx) 257*d4726bddSHONG Yifan crate_name = compute_crate_name(ctx.workspace_name, ctx.label, toolchain, ctx.attr.crate_name) 258*d4726bddSHONG Yifan 259*d4726bddSHONG Yifan return _rust_proto_compile( 260*d4726bddSHONG Yifan protos = depset(transitive = transitive_sources), 261*d4726bddSHONG Yifan descriptor_sets = depset(transitive = [p.transitive_descriptor_sets for p in proto]), 262*d4726bddSHONG Yifan imports = depset(transitive = [p.transitive_imports for p in proto]), 263*d4726bddSHONG Yifan crate_name = crate_name, 264*d4726bddSHONG Yifan ctx = ctx, 265*d4726bddSHONG Yifan is_grpc = is_grpc, 266*d4726bddSHONG Yifan compile_deps = ctx.attr.rust_deps, 267*d4726bddSHONG Yifan toolchain = toolchain, 268*d4726bddSHONG Yifan ) 269*d4726bddSHONG Yifan 270*d4726bddSHONG Yifandef _rust_proto_library_impl(ctx): 271*d4726bddSHONG Yifan """The implementation of the `rust_proto_library` rule 272*d4726bddSHONG Yifan 273*d4726bddSHONG Yifan Args: 274*d4726bddSHONG Yifan ctx (ctx): The rule's context object. 275*d4726bddSHONG Yifan 276*d4726bddSHONG Yifan Returns: 277*d4726bddSHONG Yifan list: A list of providers, see `_rust_protogrpc_library_impl` 278*d4726bddSHONG Yifan """ 279*d4726bddSHONG Yifan return _rust_protogrpc_library_impl(ctx, False) 280*d4726bddSHONG Yifan 281*d4726bddSHONG Yifanrust_proto_library = rule( 282*d4726bddSHONG Yifan implementation = _rust_proto_library_impl, 283*d4726bddSHONG Yifan attrs = { 284*d4726bddSHONG Yifan "crate_name": attr.string( 285*d4726bddSHONG Yifan doc = """\ 286*d4726bddSHONG Yifan Crate name to use for this target. 287*d4726bddSHONG Yifan 288*d4726bddSHONG Yifan This must be a valid Rust identifier, i.e. it may contain only alphanumeric characters and underscores. 289*d4726bddSHONG Yifan Defaults to the target name, with any hyphens replaced by underscores. 290*d4726bddSHONG Yifan """, 291*d4726bddSHONG Yifan ), 292*d4726bddSHONG Yifan "deps": attr.label_list( 293*d4726bddSHONG Yifan doc = ( 294*d4726bddSHONG Yifan "List of proto_library dependencies that will be built. " + 295*d4726bddSHONG Yifan "One crate for each proto_library will be created with the corresponding stubs." 296*d4726bddSHONG Yifan ), 297*d4726bddSHONG Yifan mandatory = True, 298*d4726bddSHONG Yifan providers = [ProtoInfo], 299*d4726bddSHONG Yifan aspects = [_rust_proto_aspect], 300*d4726bddSHONG Yifan ), 301*d4726bddSHONG Yifan "rust_deps": attr.label_list( 302*d4726bddSHONG Yifan doc = "The crates the generated library depends on.", 303*d4726bddSHONG Yifan ), 304*d4726bddSHONG Yifan "rustc_flags": attr.string_list( 305*d4726bddSHONG Yifan doc = """\ 306*d4726bddSHONG Yifan List of compiler flags passed to `rustc`. 307*d4726bddSHONG Yifan 308*d4726bddSHONG Yifan These strings are subject to Make variable expansion for predefined 309*d4726bddSHONG Yifan source/output path variables like `$location`, `$execpath`, and 310*d4726bddSHONG Yifan `$rootpath`. This expansion is useful if you wish to pass a generated 311*d4726bddSHONG Yifan file of arguments to rustc: `@$(location //package:target)`. 312*d4726bddSHONG Yifan """, 313*d4726bddSHONG Yifan ), 314*d4726bddSHONG Yifan "_cc_toolchain": attr.label( 315*d4726bddSHONG Yifan default = Label("@bazel_tools//tools/cpp:current_cc_toolchain"), 316*d4726bddSHONG Yifan ), 317*d4726bddSHONG Yifan "_optional_output_wrapper": attr.label( 318*d4726bddSHONG Yifan executable = True, 319*d4726bddSHONG Yifan cfg = "exec", 320*d4726bddSHONG Yifan default = Label("//proto/protobuf:optional_output_wrapper"), 321*d4726bddSHONG Yifan ), 322*d4726bddSHONG Yifan "_process_wrapper": attr.label( 323*d4726bddSHONG Yifan default = Label("//util/process_wrapper"), 324*d4726bddSHONG Yifan executable = True, 325*d4726bddSHONG Yifan allow_single_file = True, 326*d4726bddSHONG Yifan cfg = "exec", 327*d4726bddSHONG Yifan ), 328*d4726bddSHONG Yifan }, 329*d4726bddSHONG Yifan fragments = ["cpp"], 330*d4726bddSHONG Yifan toolchains = [ 331*d4726bddSHONG Yifan str(Label("//proto/protobuf:toolchain_type")), 332*d4726bddSHONG Yifan str(Label("//rust:toolchain_type")), 333*d4726bddSHONG Yifan "@bazel_tools//tools/cpp:toolchain_type", 334*d4726bddSHONG Yifan ], 335*d4726bddSHONG Yifan doc = """\ 336*d4726bddSHONG YifanBuilds a Rust library crate from a set of `proto_library`s. 337*d4726bddSHONG Yifan 338*d4726bddSHONG YifanExample: 339*d4726bddSHONG Yifan 340*d4726bddSHONG Yifan```python 341*d4726bddSHONG Yifanload("@rules_rust//proto/protobuf:defs.bzl", "rust_proto_library") 342*d4726bddSHONG Yifan 343*d4726bddSHONG Yifanproto_library( 344*d4726bddSHONG Yifan name = "my_proto", 345*d4726bddSHONG Yifan srcs = ["my.proto"] 346*d4726bddSHONG Yifan) 347*d4726bddSHONG Yifan 348*d4726bddSHONG Yifanrust_proto_library( 349*d4726bddSHONG Yifan name = "rust", 350*d4726bddSHONG Yifan deps = [":my_proto"], 351*d4726bddSHONG Yifan) 352*d4726bddSHONG Yifan 353*d4726bddSHONG Yifanrust_binary( 354*d4726bddSHONG Yifan name = "my_proto_binary", 355*d4726bddSHONG Yifan srcs = ["my_proto_binary.rs"], 356*d4726bddSHONG Yifan deps = [":rust"], 357*d4726bddSHONG Yifan) 358*d4726bddSHONG Yifan``` 359*d4726bddSHONG Yifan""", 360*d4726bddSHONG Yifan) 361*d4726bddSHONG Yifan 362*d4726bddSHONG Yifandef _rust_grpc_library_impl(ctx): 363*d4726bddSHONG Yifan """The implementation of the `rust_grpc_library` rule 364*d4726bddSHONG Yifan 365*d4726bddSHONG Yifan Args: 366*d4726bddSHONG Yifan ctx (ctx): The rule's context object 367*d4726bddSHONG Yifan 368*d4726bddSHONG Yifan Returns: 369*d4726bddSHONG Yifan list: A list of providers. See `_rust_protogrpc_library_impl` 370*d4726bddSHONG Yifan """ 371*d4726bddSHONG Yifan return _rust_protogrpc_library_impl(ctx, True) 372*d4726bddSHONG Yifan 373*d4726bddSHONG Yifanrust_grpc_library = rule( 374*d4726bddSHONG Yifan implementation = _rust_grpc_library_impl, 375*d4726bddSHONG Yifan attrs = { 376*d4726bddSHONG Yifan "crate_name": attr.string( 377*d4726bddSHONG Yifan doc = """\ 378*d4726bddSHONG Yifan Crate name to use for this target. 379*d4726bddSHONG Yifan 380*d4726bddSHONG Yifan This must be a valid Rust identifier, i.e. it may contain only alphanumeric characters and underscores. 381*d4726bddSHONG Yifan Defaults to the target name, with any hyphens replaced by underscores. 382*d4726bddSHONG Yifan """, 383*d4726bddSHONG Yifan ), 384*d4726bddSHONG Yifan "deps": attr.label_list( 385*d4726bddSHONG Yifan doc = ( 386*d4726bddSHONG Yifan "List of proto_library dependencies that will be built. " + 387*d4726bddSHONG Yifan "One crate for each proto_library will be created with the corresponding gRPC stubs." 388*d4726bddSHONG Yifan ), 389*d4726bddSHONG Yifan mandatory = True, 390*d4726bddSHONG Yifan providers = [ProtoInfo], 391*d4726bddSHONG Yifan aspects = [_rust_proto_aspect], 392*d4726bddSHONG Yifan ), 393*d4726bddSHONG Yifan "rust_deps": attr.label_list( 394*d4726bddSHONG Yifan doc = "The crates the generated library depends on.", 395*d4726bddSHONG Yifan ), 396*d4726bddSHONG Yifan "rustc_flags": attr.string_list( 397*d4726bddSHONG Yifan doc = """\ 398*d4726bddSHONG Yifan List of compiler flags passed to `rustc`. 399*d4726bddSHONG Yifan 400*d4726bddSHONG Yifan These strings are subject to Make variable expansion for predefined 401*d4726bddSHONG Yifan source/output path variables like `$location`, `$execpath`, and 402*d4726bddSHONG Yifan `$rootpath`. This expansion is useful if you wish to pass a generated 403*d4726bddSHONG Yifan file of arguments to rustc: `@$(location //package:target)`. 404*d4726bddSHONG Yifan """, 405*d4726bddSHONG Yifan ), 406*d4726bddSHONG Yifan "_cc_toolchain": attr.label( 407*d4726bddSHONG Yifan default = "@bazel_tools//tools/cpp:current_cc_toolchain", 408*d4726bddSHONG Yifan ), 409*d4726bddSHONG Yifan "_optional_output_wrapper": attr.label( 410*d4726bddSHONG Yifan executable = True, 411*d4726bddSHONG Yifan cfg = "exec", 412*d4726bddSHONG Yifan default = Label("//proto/protobuf:optional_output_wrapper"), 413*d4726bddSHONG Yifan ), 414*d4726bddSHONG Yifan "_process_wrapper": attr.label( 415*d4726bddSHONG Yifan default = Label("//util/process_wrapper"), 416*d4726bddSHONG Yifan executable = True, 417*d4726bddSHONG Yifan allow_single_file = True, 418*d4726bddSHONG Yifan cfg = "exec", 419*d4726bddSHONG Yifan ), 420*d4726bddSHONG Yifan }, 421*d4726bddSHONG Yifan fragments = ["cpp"], 422*d4726bddSHONG Yifan toolchains = [ 423*d4726bddSHONG Yifan str(Label("//proto/protobuf:toolchain_type")), 424*d4726bddSHONG Yifan str(Label("//rust:toolchain_type")), 425*d4726bddSHONG Yifan "@bazel_tools//tools/cpp:toolchain_type", 426*d4726bddSHONG Yifan ], 427*d4726bddSHONG Yifan doc = """\ 428*d4726bddSHONG YifanBuilds a Rust library crate from a set of `proto_library`s suitable for gRPC. 429*d4726bddSHONG Yifan 430*d4726bddSHONG YifanExample: 431*d4726bddSHONG Yifan 432*d4726bddSHONG Yifan```python 433*d4726bddSHONG Yifanload("@rules_rust//proto/protobuf:defs.bzl", "rust_grpc_library") 434*d4726bddSHONG Yifan 435*d4726bddSHONG Yifanproto_library( 436*d4726bddSHONG Yifan name = "my_proto", 437*d4726bddSHONG Yifan srcs = ["my.proto"] 438*d4726bddSHONG Yifan) 439*d4726bddSHONG Yifan 440*d4726bddSHONG Yifanrust_grpc_library( 441*d4726bddSHONG Yifan name = "rust", 442*d4726bddSHONG Yifan deps = [":my_proto"], 443*d4726bddSHONG Yifan) 444*d4726bddSHONG Yifan 445*d4726bddSHONG Yifanrust_binary( 446*d4726bddSHONG Yifan name = "my_service", 447*d4726bddSHONG Yifan srcs = ["my_service.rs"], 448*d4726bddSHONG Yifan deps = [":rust"], 449*d4726bddSHONG Yifan) 450*d4726bddSHONG Yifan``` 451*d4726bddSHONG Yifan""", 452*d4726bddSHONG Yifan) 453