Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 1 | """Macros that implement bootstrapping for the upb code generator.""" |
| 2 | |
Mike Kruskal | 8c0485c | 2024-03-08 10:13:42 -0800 | [diff] [blame] | 3 | load( |
| 4 | "//bazel:upb_minitable_proto_library.bzl", |
| 5 | "upb_minitable_proto_library", |
| 6 | ) |
Protobuf Team Bot | 83ec410 | 2024-03-26 18:50:37 -0700 | [diff] [blame] | 7 | load( |
| 8 | "//bazel:upb_proto_library.bzl", |
| 9 | "upb_proto_library", |
| 10 | ) |
| 11 | load( |
| 12 | "//upb/cmake:build_defs.bzl", |
| 13 | "staleness_test", |
| 14 | ) |
| 15 | |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 16 | _stages = ["_stage0", "_stage1", ""] |
| 17 | _protoc = "//:protoc" |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 18 | |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 19 | _is_google3 = False |
| 20 | _extra_proto_path = "-I$$(dirname $(location @com_google_protobuf//:descriptor_proto_srcs))/../.. " |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 21 | |
Joshua Haberman | bc394d2 | 2024-08-21 17:04:54 -0700 | [diff] [blame] | 22 | # This visibility is used automatically for anything used by the bootstrapping process. |
| 23 | _bootstrap_visibility = [ |
| 24 | "//upb_generator:__subpackages__", |
| 25 | "//upb/reflection:__pkg__", |
Joshua Haberman | bc394d2 | 2024-08-21 17:04:54 -0700 | [diff] [blame] | 26 | "//upb:__pkg__", # For the amalgamations. |
| 27 | "//python/dist:__pkg__", # For the Python source package. |
Joshua Haberman | bc394d2 | 2024-08-21 17:04:54 -0700 | [diff] [blame] | 28 | ] |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 29 | |
Joshua Haberman | bc394d2 | 2024-08-21 17:04:54 -0700 | [diff] [blame] | 30 | def _stage_visibility(stage, visibility): |
| 31 | return visibility if stage == "" else _bootstrap_visibility |
| 32 | |
| 33 | def _upbc(generator, stage): |
| 34 | if generator == "upb": |
Joshua Haberman | ddb863c | 2024-08-23 14:43:45 -0700 | [diff] [blame] | 35 | return "//upb_generator/c:protoc-gen-upb" + _stages[stage] |
Joshua Haberman | bc394d2 | 2024-08-21 17:04:54 -0700 | [diff] [blame] | 36 | else: |
| 37 | return "//upb_generator/minitable:protoc-gen-upb_minitable" + _stages[stage] |
| 38 | |
| 39 | def bootstrap_cc_library(name, visibility = [], deps = [], bootstrap_deps = [], **kwargs): |
| 40 | """A version of cc_library() that is augmented to allow for bootstrapping the compiler. |
| 41 | |
| 42 | In addition to the normal cc_library() target, this rule will also generate _stage0 and _stage1 |
| 43 | targets that are used internally for bootstrapping, and will automatically have bootstrap |
| 44 | visibility. However the final target will use the normal visibility, and will behave like a |
| 45 | normal cc_library() target. |
| 46 | |
| 47 | Args: |
| 48 | name: Name of this rule. This name will resolve to a upb_proto_library(). |
| 49 | deps: Normal cc_library() deps. |
| 50 | bootstrap_deps: Special bootstrap_upb_proto_library() or bootstrap_cc_library() deps. |
| 51 | visibility: Visibility of the final target. |
| 52 | **kwargs: Other arguments that will be passed through to cc_library(). |
| 53 | upb_proto_library(). |
| 54 | """ |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 55 | for stage in _stages: |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 56 | native.cc_library( |
| 57 | name = name + stage, |
| 58 | deps = deps + [dep + stage for dep in bootstrap_deps], |
Joshua Haberman | bc394d2 | 2024-08-21 17:04:54 -0700 | [diff] [blame] | 59 | visibility = _stage_visibility(stage, visibility), |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 60 | **kwargs |
| 61 | ) |
| 62 | |
Joshua Haberman | bc394d2 | 2024-08-21 17:04:54 -0700 | [diff] [blame] | 63 | def bootstrap_cc_binary(name, visibility = [], deps = [], bootstrap_deps = [], **kwargs): |
| 64 | """A version of cc_binary() that is augmented to allow for bootstrapping the compiler. |
| 65 | |
| 66 | In addition to the normal cc_binary() target, this rule will also generate _stage0 and _stage1 |
| 67 | targets that are used internally for bootstrapping, and will automatically have bootstrap |
| 68 | visibility. However the final target will use the normal visibility, and will behave like a |
| 69 | normal cc_binary() target. |
| 70 | |
| 71 | Args: |
| 72 | name: Name of this rule. This name will resolve to a upb_proto_library(). |
| 73 | deps: Normal cc_library() deps. |
| 74 | bootstrap_deps: Special bootstrap_upb_proto_library() or bootstrap_cc_library() deps. |
| 75 | visibility: Visibility of the final target. |
| 76 | **kwargs: Other arguments that will be passed through to cc_binary(). |
| 77 | upb_proto_library(). |
| 78 | """ |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 79 | for stage in _stages: |
| 80 | native.cc_binary( |
| 81 | name = name + stage, |
| 82 | deps = deps + [dep + stage for dep in bootstrap_deps], |
Joshua Haberman | bc394d2 | 2024-08-21 17:04:54 -0700 | [diff] [blame] | 83 | visibility = _stage_visibility(stage, visibility), |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 84 | **kwargs |
| 85 | ) |
| 86 | |
Joshua Haberman | eab1fa2 | 2024-08-19 13:29:22 -0700 | [diff] [blame] | 87 | def _generated_file(proto, stage, generator, suffix): |
| 88 | stripped = proto[:-len(".proto")] |
| 89 | return "{}/{}.{}.{}".format(stage, stripped, generator, suffix) |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 90 | |
Joshua Haberman | eab1fa2 | 2024-08-19 13:29:22 -0700 | [diff] [blame] | 91 | def _generated_files(protos, stage, generator, suffix): |
| 92 | return [_generated_file(proto, stage, generator, suffix) for proto in protos] |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 93 | |
Joshua Haberman | eab1fa2 | 2024-08-19 13:29:22 -0700 | [diff] [blame] | 94 | def _generated_hdrs_and_srcs(protos, stage, generator): |
| 95 | ret = _generated_files(protos, stage, generator, "h") |
| 96 | if generator != "upb" or stage == "stage0": |
| 97 | ret += _generated_files(protos, stage, generator, "c") |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 98 | return ret |
| 99 | |
Joshua Haberman | eab1fa2 | 2024-08-19 13:29:22 -0700 | [diff] [blame] | 100 | def _stage0_proto_staleness_test(name, src_files, src_rules, strip_prefix): |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 101 | native.genrule( |
| 102 | name = name + "_generate_bootstrap", |
| 103 | srcs = src_rules, |
Joshua Haberman | eab1fa2 | 2024-08-19 13:29:22 -0700 | [diff] [blame] | 104 | outs = ["bootstrap_generated_sources/" + f for f in _generated_hdrs_and_srcs(src_files, "stage0", "upb")], |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 105 | tools = [_protoc, _upbc("upb", 0)], |
| 106 | cmd = |
| 107 | "$(location " + _protoc + ") " + |
| 108 | "-I$(GENDIR)/" + strip_prefix + " " + _extra_proto_path + |
| 109 | "--plugin=protoc-gen-upb=$(location " + _upbc("upb", 0) + ") " + |
Joshua Haberman | eab1fa2 | 2024-08-19 13:29:22 -0700 | [diff] [blame] | 110 | "--upb_out=bootstrap_stage=0:$(@D)/bootstrap_generated_sources/stage0 " + |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 111 | " ".join(src_files), |
| 112 | ) |
| 113 | |
| 114 | staleness_test( |
Mike Kruskal | 58312a6 | 2024-03-07 17:36:42 -0800 | [diff] [blame] | 115 | name = name + "_stage0_staleness_test", |
Joshua Haberman | eab1fa2 | 2024-08-19 13:29:22 -0700 | [diff] [blame] | 116 | outs = _generated_hdrs_and_srcs(src_files, "stage0", "upb"), |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 117 | generated_pattern = "bootstrap_generated_sources/%s", |
Joshua Haberman | eab1fa2 | 2024-08-19 13:29:22 -0700 | [diff] [blame] | 118 | target_files = native.glob(["stage0/**"]), |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 119 | # To avoid skew problems for descriptor.proto/pluging.proto between |
| 120 | # GitHub repos. It's not critical that the checked-in protos are up to |
| 121 | # date for every change, they just needs to be complete enough to have |
| 122 | # everything needed by the code generator itself. |
| 123 | tags = ["manual"], |
| 124 | ) |
| 125 | |
Joshua Haberman | eab1fa2 | 2024-08-19 13:29:22 -0700 | [diff] [blame] | 126 | def _generate_stage1_proto(name, src_files, src_rules, generator, kwargs): |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 127 | native.genrule( |
| 128 | name = "gen_{}_{}_stage1".format(name, generator), |
| 129 | srcs = src_rules, |
Joshua Haberman | eab1fa2 | 2024-08-19 13:29:22 -0700 | [diff] [blame] | 130 | outs = _generated_hdrs_and_srcs(src_files, "stage1", generator), |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 131 | cmd = "$(location " + _protoc + ") " + |
| 132 | "--plugin=protoc-gen-" + generator + |
| 133 | "=$(location " + _upbc(generator, 0) + ") " + _extra_proto_path + |
Joshua Haberman | eab1fa2 | 2024-08-19 13:29:22 -0700 | [diff] [blame] | 134 | "--" + generator + "_out=bootstrap_stage=1:$(RULEDIR)/stage1 " + |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 135 | " ".join(src_files), |
Joshua Haberman | bc394d2 | 2024-08-21 17:04:54 -0700 | [diff] [blame] | 136 | visibility = _bootstrap_visibility, |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 137 | tools = [ |
| 138 | _protoc, |
| 139 | _upbc(generator, 0), |
| 140 | ], |
| 141 | **kwargs |
| 142 | ) |
| 143 | |
Joshua Haberman | eab1fa2 | 2024-08-19 13:29:22 -0700 | [diff] [blame] | 144 | def _cmake_staleness_test(name, src_files, proto_lib_deps, **kwargs): |
Mike Kruskal | 8c0485c | 2024-03-08 10:13:42 -0800 | [diff] [blame] | 145 | upb_minitable_proto_library( |
| 146 | name = name + "_minitable", |
| 147 | deps = proto_lib_deps, |
| 148 | **kwargs |
Mike Kruskal | 58312a6 | 2024-03-07 17:36:42 -0800 | [diff] [blame] | 149 | ) |
| 150 | |
Mike Kruskal | 8c0485c | 2024-03-08 10:13:42 -0800 | [diff] [blame] | 151 | # Copy the final gencode for staleness comparison |
Joshua Haberman | eab1fa2 | 2024-08-19 13:29:22 -0700 | [diff] [blame] | 152 | files = _generated_hdrs_and_srcs(src_files, "cmake", "upb") + \ |
| 153 | _generated_hdrs_and_srcs(src_files, "cmake", "upb_minitable") |
Mike Kruskal | 8c0485c | 2024-03-08 10:13:42 -0800 | [diff] [blame] | 154 | genrule = 0 |
| 155 | for src in files: |
| 156 | genrule += 1 |
| 157 | native.genrule( |
| 158 | name = name + "_copy_gencode_%d" % genrule, |
| 159 | outs = ["generated_sources/" + src], |
Joshua Haberman | eab1fa2 | 2024-08-19 13:29:22 -0700 | [diff] [blame] | 160 | srcs = [name + "_upb_proto", name + "_minitable"], |
Joshua Haberman | d5bd5b9 | 2024-06-13 10:06:47 -0700 | [diff] [blame] | 161 | cmd = """ |
| 162 | mkdir -p $(@D) |
| 163 | for src in $(SRCS); do |
| 164 | if [[ $$src == *%s ]]; then |
| 165 | cp -f $$src $(@D) || echo 'copy failed!' |
| 166 | fi |
| 167 | done |
| 168 | """ % src[src.rfind("/"):], |
Mike Kruskal | 8c0485c | 2024-03-08 10:13:42 -0800 | [diff] [blame] | 169 | ) |
| 170 | |
Mike Kruskal | 58312a6 | 2024-03-07 17:36:42 -0800 | [diff] [blame] | 171 | # Keep bazel gencode in sync with our checked-in sources needed for cmake builds. |
| 172 | staleness_test( |
| 173 | name = name + "_staleness_test", |
Mike Kruskal | 8c0485c | 2024-03-08 10:13:42 -0800 | [diff] [blame] | 174 | outs = files, |
Mike Kruskal | 58312a6 | 2024-03-07 17:36:42 -0800 | [diff] [blame] | 175 | generated_pattern = "generated_sources/%s", |
| 176 | tags = ["manual"], |
| 177 | ) |
| 178 | |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 179 | def bootstrap_upb_proto_library( |
| 180 | name, |
Joshua Haberman | eab1fa2 | 2024-08-19 13:29:22 -0700 | [diff] [blame] | 181 | bootstrap_hdr, |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 182 | google3_src_files, |
| 183 | google3_src_rules, |
| 184 | oss_src_files, |
| 185 | oss_src_rules, |
| 186 | oss_strip_prefix, |
| 187 | proto_lib_deps, |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 188 | deps = [], |
| 189 | **kwargs): |
| 190 | """A version of upb_proto_library() that is augmented to allow for bootstrapping the compiler. |
| 191 | |
Joshua Haberman | bc394d2 | 2024-08-21 17:04:54 -0700 | [diff] [blame] | 192 | Note that this rule is only intended to be used by bootstrap_cc_library() targets. End users |
| 193 | should use the normal upb_proto_library() targets. As a result, we don't have a visibility |
| 194 | parameter: all targets will automatically have bootstrap visibility. |
| 195 | |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 196 | Args: |
| 197 | name: Name of this rule. This name will resolve to a upb_proto_library(). |
Joshua Haberman | bc394d2 | 2024-08-21 17:04:54 -0700 | [diff] [blame] | 198 | bootstrap_hdr: The forwarding header that exposes the generated code, taking into account |
| 199 | the current stage. |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 200 | google3_src_files: Google3 filenames of .proto files that should be built by this rule. |
| 201 | The names should be relative to the depot base. |
| 202 | google3_src_rules: Target names of the Blaze rules that will provide these filenames. |
| 203 | oss_src_files: OSS filenames of .proto files that should be built by this rule. |
| 204 | oss_src_rules: Target names of the Bazel rules that will provide these filenames. |
| 205 | oss_strip_prefix: Prefix that should be stripped from OSS file names. |
| 206 | proto_lib_deps: proto_library() rules that we will use to build the protos when we are |
| 207 | not bootstrapping. |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 208 | deps: other bootstrap_upb_proto_library() rules that this one depends on. |
| 209 | **kwargs: Other arguments that will be passed through to cc_library(), genrule(), and |
| 210 | upb_proto_library(). |
| 211 | """ |
Joshua Haberman | eab1fa2 | 2024-08-19 13:29:22 -0700 | [diff] [blame] | 212 | _stage0_proto_staleness_test(name, oss_src_files, oss_src_rules, oss_strip_prefix) |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 213 | |
| 214 | # stage0 uses checked-in protos, and has no MiniTable. |
| 215 | native.cc_library( |
| 216 | name = name + "_stage0", |
Joshua Haberman | eab1fa2 | 2024-08-19 13:29:22 -0700 | [diff] [blame] | 217 | srcs = _generated_hdrs_and_srcs(oss_src_files, "stage0", "upb"), |
| 218 | hdrs = [bootstrap_hdr], |
Joshua Haberman | bc394d2 | 2024-08-21 17:04:54 -0700 | [diff] [blame] | 219 | visibility = _bootstrap_visibility, |
Joshua Haberman | eab1fa2 | 2024-08-19 13:29:22 -0700 | [diff] [blame] | 220 | defines = ["UPB_BOOTSTRAP_STAGE=0"], |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 221 | deps = [ |
| 222 | "//upb:generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me", |
| 223 | "//upb:mini_table", |
| 224 | ] + [dep + "_stage0" for dep in deps], |
| 225 | **kwargs |
| 226 | ) |
| 227 | |
| 228 | src_files = google3_src_files if _is_google3 else oss_src_files |
| 229 | src_rules = google3_src_rules if _is_google3 else oss_src_rules |
| 230 | |
| 231 | # Generate stage1 protos (C API and MiniTables) using stage0 compiler. |
Joshua Haberman | eab1fa2 | 2024-08-19 13:29:22 -0700 | [diff] [blame] | 232 | _generate_stage1_proto(name, src_files, src_rules, "upb", kwargs) |
| 233 | _generate_stage1_proto(name, src_files, src_rules, "upb_minitable", kwargs) |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 234 | |
| 235 | native.cc_library( |
| 236 | name = name + "_minitable_stage1", |
Joshua Haberman | eab1fa2 | 2024-08-19 13:29:22 -0700 | [diff] [blame] | 237 | srcs = _generated_files(src_files, "stage1", "upb_minitable", "c"), |
| 238 | hdrs = _generated_files(src_files, "stage1", "upb_minitable", "h"), |
Joshua Haberman | bc394d2 | 2024-08-21 17:04:54 -0700 | [diff] [blame] | 239 | visibility = _bootstrap_visibility, |
Joshua Haberman | eab1fa2 | 2024-08-19 13:29:22 -0700 | [diff] [blame] | 240 | defines = ["UPB_BOOTSTRAP_STAGE=1"], |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 241 | deps = [ |
| 242 | "//upb:generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me", |
Joshua Haberman | eab1fa2 | 2024-08-19 13:29:22 -0700 | [diff] [blame] | 243 | ] + [dep + "_minitable_stage1" for dep in deps], |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 244 | **kwargs |
| 245 | ) |
| 246 | native.cc_library( |
| 247 | name = name + "_stage1", |
Joshua Haberman | eab1fa2 | 2024-08-19 13:29:22 -0700 | [diff] [blame] | 248 | srcs = _generated_files(src_files, "stage1", "upb", "h"), |
| 249 | hdrs = [bootstrap_hdr], |
Joshua Haberman | bc394d2 | 2024-08-21 17:04:54 -0700 | [diff] [blame] | 250 | visibility = _bootstrap_visibility, |
Joshua Haberman | eab1fa2 | 2024-08-19 13:29:22 -0700 | [diff] [blame] | 251 | defines = ["UPB_BOOTSTRAP_STAGE=1"], |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 252 | deps = [ |
| 253 | "//upb:generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me", |
| 254 | ":" + name + "_minitable_stage1", |
Joshua Haberman | eab1fa2 | 2024-08-19 13:29:22 -0700 | [diff] [blame] | 255 | ] + [dep + "_minitable_stage1" for dep in deps], |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 256 | **kwargs |
| 257 | ) |
| 258 | |
| 259 | # The final protos are generated via normal upb_proto_library(). |
| 260 | upb_proto_library( |
Joshua Haberman | eab1fa2 | 2024-08-19 13:29:22 -0700 | [diff] [blame] | 261 | name = name + "_upb_proto", |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 262 | deps = proto_lib_deps, |
Joshua Haberman | eab1fa2 | 2024-08-19 13:29:22 -0700 | [diff] [blame] | 263 | **kwargs |
| 264 | ) |
| 265 | native.cc_library( |
| 266 | name = name, |
| 267 | hdrs = [bootstrap_hdr], |
| 268 | deps = [name + "_upb_proto"], |
Joshua Haberman | bc394d2 | 2024-08-21 17:04:54 -0700 | [diff] [blame] | 269 | visibility = _bootstrap_visibility, |
Adam Cozzette | 501ecec | 2023-09-26 14:36:20 -0700 | [diff] [blame] | 270 | **kwargs |
| 271 | ) |
Mike Kruskal | 58312a6 | 2024-03-07 17:36:42 -0800 | [diff] [blame] | 272 | |
Joshua Haberman | eab1fa2 | 2024-08-19 13:29:22 -0700 | [diff] [blame] | 273 | _cmake_staleness_test(name, src_files, proto_lib_deps, **kwargs) |