1"""Macros that implement bootstrapping for the upb code generator.""" 2 3load( 4 "//bazel:upb_proto_library.bzl", 5 "upb_proto_library", 6) 7load( 8 "//cmake:build_defs.bzl", 9 "staleness_test", 10) 11 12_stages = ["_stage0", "_stage1", ""] 13_protoc = "@com_google_protobuf//:protoc" 14_upbc_base = "//upbc:protoc-gen-upb" 15 16# begin:google_only 17# _is_google3 = True 18# _extra_proto_path = "" 19# end:google_only 20 21# begin:github_only 22_is_google3 = False 23_extra_proto_path = "-Iexternal/com_google_protobuf/src " 24# end:github_only 25 26def _upbc(stage): 27 return _upbc_base + _stages[stage] 28 29def bootstrap_cc_library(name, visibility, deps, bootstrap_deps, **kwargs): 30 for stage in _stages: 31 stage_visibility = visibility if stage == "" else ["//upbc:__pkg__"] 32 native.cc_library( 33 name = name + stage, 34 deps = deps + [dep + stage for dep in bootstrap_deps], 35 visibility = stage_visibility, 36 **kwargs 37 ) 38 39def bootstrap_cc_binary(name, deps, bootstrap_deps, **kwargs): 40 for stage in _stages: 41 native.cc_binary( 42 name = name + stage, 43 deps = deps + [dep + stage for dep in bootstrap_deps], 44 **kwargs 45 ) 46 47def _generated_srcs_for_suffix(prefix, srcs, suffix): 48 return [prefix + "/" + src[:-len(".proto")] + suffix for src in srcs] 49 50def _generated_srcs(prefix, srcs): 51 return _generated_srcs_for_suffix(prefix, srcs, ".upb.h") + _generated_srcs_for_suffix(prefix, srcs, ".upb.c") 52 53def _stage0_proto_staleness_test(name, base_dir, src_files, src_rules, strip_prefix): 54 native.genrule( 55 name = name + "_generate_bootstrap", 56 srcs = src_rules, 57 outs = _generated_srcs("bootstrap_generated_sources/" + base_dir + "stage0", src_files), 58 tools = [_protoc, _upbc(0)], 59 cmd = 60 "$(location " + _protoc + ") " + 61 "-I$(GENDIR)/" + strip_prefix + " " + _extra_proto_path + 62 "--plugin=protoc-gen-upb=$(location " + _upbc(0) + ") " + 63 "--upb_out=bootstrap_upb:$(@D)/bootstrap_generated_sources/" + base_dir + "stage0 " + 64 " ".join(src_files), 65 ) 66 67 staleness_test( 68 name = name + "_staleness_test", 69 outs = _generated_srcs(base_dir + "stage0", src_files), 70 generated_pattern = "bootstrap_generated_sources/%s", 71 target_files = native.glob([base_dir + "stage0/**"]), 72 # To avoid skew problems for descriptor.proto/pluging.proto between 73 # GitHub repos. It's not critical that the checked-in protos are up to 74 # date for every change, they just needs to be complete enough to have 75 # everything needed by the code generator itself. 76 tags = ["manual"], 77 ) 78 79def bootstrap_upb_proto_library( 80 name, 81 base_dir, 82 google3_src_files, 83 google3_src_rules, 84 oss_src_files, 85 oss_src_rules, 86 oss_strip_prefix, 87 proto_lib_deps, 88 visibility, 89 deps = [], 90 **kwargs): 91 """A version of upb_proto_library() that is augmented to allow for bootstrapping the compiler. 92 93 Args: 94 name: Name of this rule. This name will resolve to a upb_proto_library(). 95 base_dir: The directory that all generated files should be placed under. 96 google3_src_files: Google3 filenames of .proto files that should be built by this rule. 97 The names should be relative to the depot base. 98 google3_src_rules: Target names of the Blaze rules that will provide these filenames. 99 oss_src_files: OSS filenames of .proto files that should be built by this rule. 100 oss_src_rules: Target names of the Bazel rules that will provide these filenames. 101 oss_strip_prefix: Prefix that should be stripped from OSS file names. 102 proto_lib_deps: proto_library() rules that we will use to build the protos when we are 103 not bootstrapping. 104 visibility: Visibility list for the final upb_proto_library() rule. Bootstrapping rules 105 will always be hidden, and will not honor the visibility parameter passed here. 106 deps: other bootstrap_upb_proto_library() rules that this one depends on. 107 **kwargs: Other arguments that will be passed through to cc_library(), genrule(), and 108 upb_proto_library(). 109 """ 110 _stage0_proto_staleness_test(name, base_dir, oss_src_files, oss_src_rules, oss_strip_prefix) 111 112 # stage0 uses checked-in protos. 113 native.cc_library( 114 name = name + "_stage0", 115 srcs = _generated_srcs_for_suffix(base_dir + "stage0", oss_src_files, ".upb.c"), 116 hdrs = _generated_srcs_for_suffix(base_dir + "stage0", oss_src_files, ".upb.h"), 117 includes = [base_dir + "stage0"], 118 visibility = ["//upbc:__pkg__"], 119 # This macro signals to the runtime that it must use OSS APIs for descriptor.proto/plugin.proto. 120 defines = ["UPB_BOOTSTRAP_STAGE0"], 121 deps = [ 122 "//:generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me", 123 "//:mini_table", 124 ] + [dep + "_stage0" for dep in deps], 125 **kwargs 126 ) 127 128 src_files = google3_src_files if _is_google3 else oss_src_files 129 src_rules = google3_src_rules if _is_google3 else oss_src_rules 130 131 # Generate stage1 protos using stage0 compiler. 132 native.genrule( 133 name = "gen_" + name + "_stage1", 134 srcs = src_rules, 135 outs = _generated_srcs(base_dir + "stage1", src_files), 136 cmd = "$(location " + _protoc + ") " + 137 "--plugin=protoc-gen-upb=$(location " + _upbc(0) + ") " + _extra_proto_path + 138 "--upb_out=$(@D)/" + base_dir + "stage1 " + 139 " ".join(src_files), 140 visibility = ["//upbc:__pkg__"], 141 tools = [ 142 _protoc, 143 _upbc(0), 144 ], 145 **kwargs 146 ) 147 148 native.cc_library( 149 name = name + "_stage1", 150 srcs = _generated_srcs_for_suffix(base_dir + "stage1", src_files, ".upb.c"), 151 hdrs = _generated_srcs_for_suffix(base_dir + "stage1", src_files, ".upb.h"), 152 includes = [base_dir + "stage1"], 153 visibility = ["//upbc:__pkg__"], 154 deps = [ 155 "//:generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me", 156 ] + [dep + "_stage1" for dep in deps], 157 **kwargs 158 ) 159 160 # The final protos are generated via normal upb_proto_library(). 161 upb_proto_library( 162 name = name, 163 deps = proto_lib_deps, 164 visibility = visibility, 165 **kwargs 166 ) 167