1load("@bazel_skylib//lib:versions.bzl", "versions") 2load("@rules_cc//cc:defs.bzl", "objc_library") 3load("@rules_python//python:defs.bzl", "py_library") 4load("//bazel/common:proto_info.bzl", "ProtoInfo") 5 6def _GetPath(ctx, path): 7 if ctx.label.workspace_root: 8 return ctx.label.workspace_root + "/" + path 9 else: 10 return path 11 12def _IsNewExternal(ctx): 13 # Bazel 0.4.4 and older have genfiles paths that look like: 14 # bazel-out/local-fastbuild/genfiles/external/repo/foo 15 # After the exec root rearrangement, they look like: 16 # ../repo/bazel-out/local-fastbuild/genfiles/foo 17 return ctx.label.workspace_root.startswith("../") 18 19def _GenDir(ctx): 20 if _IsNewExternal(ctx): 21 # We are using the fact that Bazel 0.4.4+ provides repository-relative paths 22 # for ctx.genfiles_dir. 23 return ctx.genfiles_dir.path + ( 24 "/" + ctx.attr.includes[0] if ctx.attr.includes and ctx.attr.includes[0] else "" 25 ) 26 27 # This means that we're either in the old version OR the new version in the local repo. 28 # Either way, appending the source path to the genfiles dir works. 29 return ctx.var["GENDIR"] + "/" + _SourceDir(ctx) 30 31def _SourceDir(ctx): 32 if not ctx.attr.includes: 33 return ctx.label.workspace_root 34 if not ctx.attr.includes[0]: 35 return _GetPath(ctx, ctx.label.package) 36 if not ctx.label.package: 37 return _GetPath(ctx, ctx.attr.includes[0]) 38 return _GetPath(ctx, ctx.label.package + "/" + ctx.attr.includes[0]) 39 40def _ObjcBase(srcs): 41 return [ 42 "".join([token.capitalize() for token in src[:-len(".proto")].split("_")]) 43 for src in srcs 44 ] 45 46def _ObjcHdrs(srcs): 47 return [src + ".pbobjc.h" for src in _ObjcBase(srcs)] 48 49def _ObjcSrcs(srcs): 50 return [src + ".pbobjc.m" for src in _ObjcBase(srcs)] 51 52def _ObjcOuts(srcs, out_type): 53 if out_type == "hdrs": 54 return _ObjcHdrs(srcs) 55 if out_type == "srcs": 56 return _ObjcSrcs(srcs) 57 return _ObjcHdrs(srcs) + _ObjcSrcs(srcs) 58 59def _PyOuts(srcs, use_grpc_plugin = False): 60 ret = [s[:-len(".proto")] + "_pb2.py" for s in srcs] 61 if use_grpc_plugin: 62 ret += [s[:-len(".proto")] + "_pb2_grpc.py" for s in srcs] 63 return ret 64 65def _RubyOuts(srcs): 66 return [s[:-len(".proto")] + "_pb.rb" for s in srcs] 67 68def _CsharpOuts(srcs): 69 return [ 70 "".join([token.capitalize() for token in src[:-len(".proto")].split("_")]) + ".cs" 71 for src in srcs 72 ] 73 74ProtoGenInfo = provider( 75 fields = ["srcs", "import_flags", "deps"], 76) 77 78def _proto_gen_impl(ctx): 79 """General implementation for generating protos""" 80 srcs = ctx.files.srcs 81 langs = ctx.attr.langs or [] 82 out_type = ctx.attr.out_type 83 enable_editions = ctx.attr.enable_editions 84 deps = depset(direct = ctx.files.srcs) 85 source_dir = _SourceDir(ctx) 86 gen_dir = _GenDir(ctx).rstrip("/") 87 import_flags = [] 88 89 if source_dir: 90 has_sources = any([src.is_source for src in srcs]) 91 if has_sources: 92 import_flags += ["-I" + source_dir] 93 else: 94 import_flags += ["-I."] 95 96 has_generated = any([not src.is_source for src in srcs]) 97 if has_generated: 98 import_flags += ["-I" + gen_dir] 99 100 if ctx.attr.includes: 101 for include in ctx.attr.includes: 102 import_flags += ["-I" + _GetPath(ctx, include)] 103 104 import_flags = depset(direct = import_flags) 105 106 for dep in ctx.attr.deps: 107 dep_proto = dep[ProtoGenInfo] 108 if type(dep_proto.import_flags) == "list": 109 import_flags = depset( 110 transitive = [import_flags], 111 direct = dep_proto.import_flags, 112 ) 113 else: 114 import_flags = depset( 115 transitive = [import_flags, dep_proto.import_flags], 116 ) 117 if type(dep_proto.deps) == "list": 118 deps = depset(transitive = [deps], direct = dep_proto.deps) 119 else: 120 deps = depset(transitive = [deps, dep_proto.deps]) 121 122 if not langs and not ctx.executable.plugin: 123 return [ 124 ProtoGenInfo( 125 srcs = srcs, 126 import_flags = import_flags, 127 deps = deps, 128 ), 129 ] 130 131 generated_files = [] 132 for src in srcs: 133 args = [] 134 if enable_editions: 135 args.append("--experimental_editions") 136 137 in_gen_dir = src.root.path == gen_dir 138 if in_gen_dir: 139 import_flags_real = [] 140 for f in import_flags.to_list(): 141 path = f.replace("-I", "") 142 import_flags_real.append("-I$(realpath -s %s)" % path) 143 144 use_grpc_plugin = (ctx.attr.plugin_language == "grpc" and ctx.attr.plugin) 145 path_tpl = "$(realpath %s)" if in_gen_dir else "%s" 146 147 outs = [] 148 for lang in langs: 149 if lang == "csharp": 150 outs.extend(_CsharpOuts([src.basename])) 151 elif lang == "objc": 152 outs.extend(_ObjcOuts([src.basename], out_type = out_type)) 153 elif lang == "python": 154 outs.extend(_PyOuts([src.basename], use_grpc_plugin = use_grpc_plugin)) 155 elif lang == "ruby": 156 outs.extend(_RubyOuts([src.basename])) 157 158 # Otherwise, rely on user-supplied outs. 159 args += [("--%s_out=" + path_tpl) % (lang, gen_dir)] 160 161 if ctx.attr.outs: 162 outs.extend(ctx.attr.outs) 163 outs = [ctx.actions.declare_file(out, sibling = src) for out in outs] 164 generated_files.extend(outs) 165 166 inputs = [src] + deps.to_list() 167 tools = [ctx.executable.protoc] 168 if ctx.executable.plugin: 169 plugin = ctx.executable.plugin 170 lang = ctx.attr.plugin_language 171 if not lang and plugin.basename.startswith("protoc-gen-"): 172 lang = plugin.basename[len("protoc-gen-"):] 173 if not lang: 174 fail("cannot infer the target language of plugin", "plugin_language") 175 176 outdir = "." if in_gen_dir else gen_dir 177 178 if ctx.attr.plugin_options: 179 outdir = ",".join(ctx.attr.plugin_options) + ":" + outdir 180 args += [("--plugin=protoc-gen-%s=" + path_tpl) % (lang, plugin.path)] 181 args += ["--%s_out=%s" % (lang, outdir)] 182 tools.append(plugin) 183 184 if not in_gen_dir: 185 ctx.actions.run( 186 inputs = inputs, 187 tools = tools, 188 outputs = outs, 189 arguments = args + import_flags.to_list() + [src.path], 190 executable = ctx.executable.protoc, 191 mnemonic = "ProtoCompile", 192 use_default_shell_env = True, 193 ) 194 else: 195 for out in outs: 196 orig_command = " ".join( 197 ["$(realpath %s)" % ctx.executable.protoc.path] + args + 198 import_flags_real + [src.basename], 199 ) 200 command = ";".join([ 201 'CMD="%s"' % orig_command, 202 "cd %s" % src.dirname, 203 "${CMD}", 204 "cd -", 205 ]) 206 generated_out = "/".join([gen_dir, out.basename]) 207 if generated_out != out.path: 208 command += ";mv %s %s" % (generated_out, out.path) 209 ctx.actions.run_shell( 210 inputs = inputs, 211 outputs = [out], 212 command = command, 213 mnemonic = "ProtoCompile", 214 tools = tools, 215 use_default_shell_env = True, 216 ) 217 218 return [ 219 ProtoGenInfo( 220 srcs = srcs, 221 import_flags = import_flags, 222 deps = deps, 223 ), 224 DefaultInfo(files = depset(generated_files)), 225 ] 226 227"""Generates codes from Protocol Buffers definitions. 228 229This rule helps you to implement Skylark macros specific to the target 230language. You should prefer more specific `cc_proto_library `, 231`py_proto_library` and others unless you are adding such wrapper macros. 232 233Args: 234 srcs: Protocol Buffers definition files (.proto) to run the protocol compiler 235 against. 236 deps: a list of dependency labels; must be other proto libraries. 237 enable_editions: if true, sets the --experimental_editions flag. 238 includes: a list of include paths to .proto files. 239 protoc: the label of the protocol compiler to generate the sources. 240 plugin: the label of the protocol compiler plugin to be passed to the protocol 241 compiler. 242 plugin_language: the language of the generated sources 243 plugin_options: a list of options to be passed to the plugin 244 langs: generates sources in addition to the ones from the plugin for each 245 specified language. 246 outs: a list of labels of the expected outputs from the protocol compiler. 247 out_type: only generated a single type of source file for languages that have 248 split sources (e.g. *.h and *.cc in C++) 249""" 250_proto_gen = rule( 251 attrs = { 252 "srcs": attr.label_list(allow_files = True), 253 "deps": attr.label_list(providers = [ProtoGenInfo]), 254 "enable_editions": attr.bool(), 255 "includes": attr.string_list(), 256 "protoc": attr.label( 257 cfg = "exec", 258 executable = True, 259 allow_single_file = True, 260 mandatory = True, 261 ), 262 "plugin": attr.label( 263 cfg = "exec", 264 allow_files = True, 265 executable = True, 266 ), 267 "plugin_language": attr.string(), 268 "plugin_options": attr.string_list(), 269 "langs": attr.string_list(), 270 "outs": attr.string_list(), 271 "out_type": attr.string( 272 default = "all", 273 ), 274 }, 275 implementation = _proto_gen_impl, 276) 277 278def _internal_gen_well_known_protos_java_impl(ctx): 279 args = ctx.actions.args() 280 281 deps = [d[ProtoInfo] for d in ctx.attr.deps] 282 283 srcjar = ctx.actions.declare_file("{}.srcjar".format(ctx.attr.name)) 284 if ctx.attr.javalite: 285 java_out = "lite:%s" % srcjar.path 286 else: 287 java_out = srcjar 288 289 args.add("--java_out", java_out) 290 291 descriptors = depset( 292 transitive = [dep.transitive_descriptor_sets for dep in deps], 293 ) 294 args.add_joined( 295 "--descriptor_set_in", 296 descriptors, 297 join_with = ctx.configuration.host_path_separator, 298 ) 299 300 for dep in deps: 301 if "." == dep.proto_source_root: 302 args.add_all([src.path for src in dep.direct_sources]) 303 else: 304 source_root = dep.proto_source_root 305 offset = len(source_root) + 1 # + '/'. 306 args.add_all([src.path[offset:] for src in dep.direct_sources]) 307 308 ctx.actions.run( 309 executable = ctx.executable._protoc, 310 inputs = descriptors, 311 outputs = [srcjar], 312 arguments = [args], 313 mnemonic = "ProtoCompile", 314 use_default_shell_env = True, 315 ) 316 317 return [ 318 DefaultInfo( 319 files = depset([srcjar]), 320 ), 321 ] 322 323internal_gen_well_known_protos_java = rule( 324 implementation = _internal_gen_well_known_protos_java_impl, 325 attrs = { 326 "deps": attr.label_list( 327 mandatory = True, 328 providers = [ProtoInfo], 329 ), 330 "javalite": attr.bool( 331 default = False, 332 ), 333 "_protoc": attr.label( 334 executable = True, 335 cfg = "exec", 336 default = "//:protoc", 337 ), 338 }, 339) 340 341def _internal_gen_kt_protos(ctx): 342 args = ctx.actions.args() 343 344 deps = [d[ProtoInfo] for d in ctx.attr.deps] 345 346 srcjar = ctx.actions.declare_file("{}.srcjar".format(ctx.attr.name)) 347 if ctx.attr.lite: 348 out = "lite:%s" % srcjar.path 349 else: 350 out = srcjar 351 352 args.add("--kotlin_out", out) 353 354 descriptors = depset( 355 transitive = [dep.transitive_descriptor_sets for dep in deps], 356 ) 357 args.add_joined( 358 "--descriptor_set_in", 359 descriptors, 360 join_with = ctx.configuration.host_path_separator, 361 ) 362 363 for dep in deps: 364 if "." == dep.proto_source_root: 365 args.add_all([src.path for src in dep.direct_sources]) 366 else: 367 source_root = dep.proto_source_root 368 offset = len(source_root) + 1 # + '/'. 369 args.add_all([src.path[offset:] for src in dep.direct_sources]) 370 371 ctx.actions.run( 372 executable = ctx.executable._protoc, 373 inputs = descriptors, 374 outputs = [srcjar], 375 arguments = [args], 376 mnemonic = "ProtoCompile", 377 use_default_shell_env = True, 378 ) 379 380 return [ 381 DefaultInfo( 382 files = depset([srcjar]), 383 ), 384 ] 385 386internal_gen_kt_protos = rule( 387 implementation = _internal_gen_kt_protos, 388 attrs = { 389 "deps": attr.label_list( 390 mandatory = True, 391 providers = [ProtoInfo], 392 ), 393 "lite": attr.bool( 394 default = False, 395 ), 396 "_protoc": attr.label( 397 executable = True, 398 cfg = "exec", 399 default = "//:protoc", 400 ), 401 }, 402) 403 404def internal_objc_proto_library( 405 name, 406 srcs = [], 407 deps = [], 408 outs = [], 409 proto_deps = [], 410 includes = ["."], 411 default_runtime = Label("//:protobuf_objc"), 412 protoc = Label("//:protoc"), 413 testonly = None, 414 visibility = ["//visibility:public"], 415 **kwargs): 416 """Bazel rule to create a Objective-C protobuf library from proto sources 417 418 NOTE: the rule is only an internal workaround to generate protos. The 419 interface may change and the rule may be removed when bazel has introduced 420 the native rule. 421 422 Args: 423 name: the name of the objc_proto_library. 424 srcs: the .proto files to compile. 425 deps: a list of dependency labels; must be objc_proto_library. 426 outs: a list of expected output files. 427 proto_deps: a list of proto file dependencies that don't have a 428 objc_proto_library rule. 429 includes: a string indicating the include path of the .proto files. 430 default_runtime: the Objective-C Protobuf runtime 431 protoc: the label of the protocol compiler to generate the sources. 432 testonly: common rule attribute (see: 433 https://bazel.build/reference/be/common-definitions#common-attributes) 434 visibility: the visibility of the generated files. 435 **kwargs: other keyword arguments that are passed to py_library. 436 437 """ 438 full_deps = [d + "_genproto" for d in deps] 439 440 if proto_deps: 441 _proto_gen( 442 name = name + "_deps_genproto", 443 testonly = testonly, 444 srcs = proto_deps, 445 protoc = protoc, 446 includes = includes, 447 ) 448 full_deps.append(":%s_deps_genproto" % name) 449 450 # Note: we need to run the protoc build twice to get separate targets for 451 # the generated header and the source files. 452 _proto_gen( 453 name = name + "_genproto_hdrs", 454 srcs = srcs, 455 deps = full_deps, 456 langs = ["objc"], 457 out_type = "hdrs", 458 includes = includes, 459 protoc = protoc, 460 testonly = testonly, 461 visibility = visibility, 462 tags = ["manual"], 463 ) 464 465 _proto_gen( 466 name = name + "_genproto", 467 srcs = srcs, 468 deps = full_deps, 469 langs = ["objc"], 470 out_type = "srcs", 471 includes = includes, 472 protoc = protoc, 473 testonly = testonly, 474 visibility = visibility, 475 tags = ["manual"], 476 ) 477 478 objc_library( 479 name = name, 480 hdrs = [name + "_genproto_hdrs"], 481 non_arc_srcs = [name + "_genproto"], 482 deps = [default_runtime], 483 includes = includes, 484 testonly = testonly, 485 visibility = visibility, 486 # Don't auto-expand these targets until target_compatible_with 487 # works. See https://github.com/bazelbuild/bazel/issues/12897. 488 tags = ["manual"], 489 target_compatible_with = ["@platforms//os:osx"], 490 **kwargs 491 ) 492 493def internal_ruby_proto_library( 494 name, 495 ruby_library, 496 srcs = [], 497 deps = [], 498 includes = ["."], 499 default_runtime = "@com_google_protobuf//ruby:protobuf", 500 protoc = "@com_google_protobuf//:protoc", 501 testonly = None, 502 visibility = ["//visibility:public"], 503 **kwargs): 504 """Bazel rule to create a Ruby protobuf library from proto source files 505 506 NOTE: the rule is only an internal workaround to generate protos. The 507 interface may change and the rule may be removed when bazel has introduced 508 the native rule. 509 510 Args: 511 name: the name of the ruby_proto_library. 512 ruby_library: the ruby library rules to use. 513 srcs: the .proto files to compile. 514 deps: a list of dependency labels; must be a internal_ruby_proto_library. 515 includes: a string indicating the include path of the .proto files. 516 default_runtime: the RubyProtobuf runtime 517 protoc: the label of the protocol compiler to generate the sources. 518 testonly: common rule attribute (see: 519 https://bazel.build/reference/be/common-definitions#common-attributes) 520 visibility: the visibility of the generated files. 521 **kwargs: other keyword arguments that are passed to ruby_library. 522 523 """ 524 525 # Note: we need to run the protoc build twice to get separate targets for 526 # the generated header and the source files. 527 _proto_gen( 528 name = name + "_genproto", 529 srcs = srcs, 530 deps = [s + "_genproto" for s in deps], 531 langs = ["ruby"], 532 includes = includes, 533 protoc = protoc, 534 testonly = testonly, 535 visibility = visibility, 536 tags = ["manual"], 537 ) 538 539 deps = [] 540 if default_runtime: 541 deps.append(default_runtime) 542 ruby_library( 543 name = name, 544 srcs = [name + "_genproto"], 545 deps = deps, 546 testonly = testonly, 547 visibility = visibility, 548 includes = includes, 549 **kwargs 550 ) 551 552# When canonical labels are in use, use additional "@" prefix 553_canonical_label_prefix = "@" if str(Label("//:protoc")).startswith("@@") else "" 554 555def _to_label(label_str): 556 """Converts a string to a label using the repository of the calling thread""" 557 if type(label_str) == type(Label("//:foo")): 558 return label_str 559 return Label(_canonical_label_prefix + native.repository_name() + "//" + native.package_name() + ":foo").relative(label_str) 560 561def internal_py_proto_library( 562 name, 563 srcs = [], 564 deps = [], 565 py_libs = [], 566 py_extra_srcs = [], 567 include = None, 568 default_runtime = Label("//:protobuf_python"), 569 protoc = Label("//:protoc"), 570 use_grpc_plugin = False, 571 testonly = None, 572 **kargs): 573 """Bazel rule to create a Python protobuf library from proto source files 574 575 NOTE: the rule is only an internal workaround to generate protos. The 576 interface may change and the rule may be removed when bazel has introduced 577 the native rule. 578 579 Args: 580 name: the name of the py_proto_library. 581 srcs: the .proto files of the py_proto_library. 582 deps: a list of dependency labels; must be py_proto_library. 583 py_libs: a list of other py_library targets depended by the generated 584 py_library. 585 py_extra_srcs: extra source files that will be added to the output 586 py_library. This attribute is used for internal bootstrapping. 587 include: a string indicating the include path of the .proto files. 588 default_runtime: the implicitly default runtime which will be depended on by 589 the generated py_library target. 590 protoc: the label of the protocol compiler to generate the sources. 591 use_grpc_plugin: a flag to indicate whether to call the Python C++ plugin 592 when processing the proto files. 593 testonly: common rule attribute (see: 594 https://bazel.build/reference/be/common-definitions#common-attributes) 595 **kargs: other keyword arguments that are passed to py_library. 596 597 """ 598 includes = [] 599 if include != None: 600 includes = [include] 601 602 grpc_python_plugin = None 603 if use_grpc_plugin: 604 grpc_python_plugin = "//external:grpc_python_plugin" 605 # Note: Generated grpc code depends on Python grpc module. This dependency 606 # is not explicitly listed in py_libs. Instead, host system is assumed to 607 # have grpc installed. 608 609 _proto_gen( 610 name = name + "_genproto", 611 testonly = testonly, 612 srcs = srcs, 613 deps = [s + "_genproto" for s in deps], 614 includes = includes, 615 protoc = protoc, 616 langs = ["python"], 617 visibility = ["//visibility:public"], 618 plugin = grpc_python_plugin, 619 plugin_language = "grpc", 620 ) 621 622 if default_runtime: 623 # Resolve non-local labels 624 labels = [_to_label(lib) for lib in py_libs + deps] 625 if not _to_label(default_runtime) in labels: 626 py_libs = py_libs + [default_runtime] 627 628 py_library( 629 name = name, 630 testonly = testonly, 631 srcs = [name + "_genproto"] + py_extra_srcs, 632 deps = py_libs + deps, 633 imports = includes, 634 **kargs 635 ) 636 637def py_proto_library( 638 *args, 639 **kwargs): 640 """Deprecated alias for use before Bazel 5.3. 641 642 Args: 643 *args: the name of the py_proto_library. 644 **kwargs: other keyword arguments that are passed to py_library. 645 646 Deprecated: 647 This is provided for backwards compatibility only. Bazel 5.3 will 648 introduce support for py_proto_library, which should be used instead. 649 """ 650 print("The py_proto_library macro is deprecated and will be removed in the " 651 + "30.x release. switch to the rule defined by rules_python or the one " 652 + "in bazel/py_proto_library.bzl.") 653 internal_py_proto_library(*args, **kwargs) 654 655def _source_proto_library( 656 name, 657 srcs = [], 658 deps = [], 659 proto_deps = [], 660 outs = [], 661 lang = None, 662 includes = ["."], 663 protoc = Label("//:protoc"), 664 testonly = None, 665 visibility = ["//visibility:public"], 666 enable_editions = False, 667 **kwargs): 668 """Bazel rule to create generated protobuf code from proto source files for 669 languages not well supported by Bazel yet. This will output the generated 670 code as-is without any compilation. This is most useful for interpreted 671 languages that don't require it. 672 673 NOTE: the rule is only an internal workaround to generate protos. The 674 interface may change and the rule may be removed when bazel has introduced 675 the native rule. 676 677 Args: 678 name: the name of the unsupported_proto_library. 679 srcs: the .proto files to compile. Note, that for languages where out 680 needs to be provided, only a single source file is allowed. 681 deps: a list of dependency labels; must be unsupported_proto_library. 682 proto_deps: a list of proto file dependencies that don't have a 683 unsupported_proto_library rule. 684 lang: the language to (optionally) generate code for. 685 outs: a list of expected output files. This is only required for 686 languages where we can't predict the outputs. 687 includes: strings indicating the include path of the .proto files. 688 protoc: the label of the protocol compiler to generate the sources. 689 testonly: common rule attribute (see: 690 https://bazel.build/reference/be/common-definitions#common-attributes) 691 visibility: the visibility of the generated files. 692 **kwargs: other keyword arguments that are passed to py_library. 693 694 """ 695 if outs and len(srcs) != 1: 696 fail("Custom outputs only allowed for single proto targets.") 697 698 langs = [] 699 if lang != None: 700 langs = [lang] 701 702 full_deps = [d + "_genproto" for d in deps] 703 704 if proto_deps: 705 _proto_gen( 706 name = name + "_deps_genproto", 707 testonly = testonly, 708 srcs = proto_deps, 709 protoc = protoc, 710 includes = includes, 711 enable_editions = enable_editions, 712 ) 713 full_deps.append(":%s_deps_genproto" % name) 714 715 _proto_gen( 716 name = name + "_genproto", 717 srcs = srcs, 718 deps = full_deps, 719 langs = langs, 720 outs = outs, 721 includes = includes, 722 protoc = protoc, 723 testonly = testonly, 724 visibility = visibility, 725 enable_editions = enable_editions, 726 ) 727 728 native.filegroup( 729 name = name, 730 srcs = [":%s_genproto" % name], 731 testonly = testonly, 732 visibility = visibility, 733 **kwargs 734 ) 735 736def internal_csharp_proto_library(**kwargs): 737 """Bazel rule to create a C# protobuf library from proto source files 738 739 NOTE: the rule is only an internal workaround to generate protos. The 740 interface may change and the rule may be removed when bazel has introduced 741 the native rule. 742 743 Args: 744 **kwargs: arguments that are passed to unsupported_proto_library. 745 746 """ 747 748 _source_proto_library( 749 lang = "csharp", 750 **kwargs 751 ) 752 753def internal_php_proto_library(**kwargs): 754 """Bazel rule to create a PHP protobuf library from proto source files 755 756 NOTE: the rule is only an internal workaround to generate protos. The 757 interface may change and the rule may be removed when bazel has introduced 758 the native rule. 759 760 Args: 761 **kwargs: arguments that are passed to unsupported_proto_library. 762 763 """ 764 if not kwargs.get("outs"): 765 fail("Unable to predict the outputs for php_proto_library. Please specify them via `outs`.") 766 767 _source_proto_library( 768 lang = "php", 769 **kwargs 770 ) 771 772def check_protobuf_required_bazel_version(): 773 """For WORKSPACE files, to check the installed version of bazel. 774 775 This ensures bazel supports our approach to proto_library() depending on a 776 copied filegroup. (Fixed in bazel 0.5.4) 777 """ 778 versions.check(minimum_bazel_version = "0.5.4") 779