blob: be2ff5f087a45ec51b1752caf102175a5de95d7e [file] [log] [blame]
Adam Cozzette501ecec2023-09-26 14:36:20 -07001"""Macros that implement bootstrapping for the upb code generator."""
2
Mike Kruskal8c0485c2024-03-08 10:13:42 -08003load(
4 "//bazel:upb_minitable_proto_library.bzl",
5 "upb_minitable_proto_library",
6)
Protobuf Team Bot83ec4102024-03-26 18:50:37 -07007load(
8 "//bazel:upb_proto_library.bzl",
9 "upb_proto_library",
10)
11load(
12 "//upb/cmake:build_defs.bzl",
13 "staleness_test",
14)
15
Adam Cozzette501ecec2023-09-26 14:36:20 -070016_stages = ["_stage0", "_stage1", ""]
17_protoc = "//:protoc"
Adam Cozzette501ecec2023-09-26 14:36:20 -070018
Adam Cozzette501ecec2023-09-26 14:36:20 -070019_is_google3 = False
20_extra_proto_path = "-I$$(dirname $(location @com_google_protobuf//:descriptor_proto_srcs))/../.. "
Adam Cozzette501ecec2023-09-26 14:36:20 -070021
Joshua Habermanbc394d22024-08-21 17:04:54 -070022# This visibility is used automatically for anything used by the bootstrapping process.
23_bootstrap_visibility = [
24 "//upb_generator:__subpackages__",
25 "//upb/reflection:__pkg__",
Joshua Habermanbc394d22024-08-21 17:04:54 -070026 "//upb:__pkg__", # For the amalgamations.
27 "//python/dist:__pkg__", # For the Python source package.
Joshua Habermanbc394d22024-08-21 17:04:54 -070028]
Adam Cozzette501ecec2023-09-26 14:36:20 -070029
Joshua Habermanbc394d22024-08-21 17:04:54 -070030def _stage_visibility(stage, visibility):
31 return visibility if stage == "" else _bootstrap_visibility
32
33def _upbc(generator, stage):
34 if generator == "upb":
Joshua Habermanddb863c2024-08-23 14:43:45 -070035 return "//upb_generator/c:protoc-gen-upb" + _stages[stage]
Joshua Habermanbc394d22024-08-21 17:04:54 -070036 else:
37 return "//upb_generator/minitable:protoc-gen-upb_minitable" + _stages[stage]
38
39def 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 Cozzette501ecec2023-09-26 14:36:20 -070055 for stage in _stages:
Adam Cozzette501ecec2023-09-26 14:36:20 -070056 native.cc_library(
57 name = name + stage,
58 deps = deps + [dep + stage for dep in bootstrap_deps],
Joshua Habermanbc394d22024-08-21 17:04:54 -070059 visibility = _stage_visibility(stage, visibility),
Adam Cozzette501ecec2023-09-26 14:36:20 -070060 **kwargs
61 )
62
Joshua Habermanbc394d22024-08-21 17:04:54 -070063def 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 Cozzette501ecec2023-09-26 14:36:20 -070079 for stage in _stages:
80 native.cc_binary(
81 name = name + stage,
82 deps = deps + [dep + stage for dep in bootstrap_deps],
Joshua Habermanbc394d22024-08-21 17:04:54 -070083 visibility = _stage_visibility(stage, visibility),
Adam Cozzette501ecec2023-09-26 14:36:20 -070084 **kwargs
85 )
86
Joshua Habermaneab1fa22024-08-19 13:29:22 -070087def _generated_file(proto, stage, generator, suffix):
88 stripped = proto[:-len(".proto")]
89 return "{}/{}.{}.{}".format(stage, stripped, generator, suffix)
Adam Cozzette501ecec2023-09-26 14:36:20 -070090
Joshua Habermaneab1fa22024-08-19 13:29:22 -070091def _generated_files(protos, stage, generator, suffix):
92 return [_generated_file(proto, stage, generator, suffix) for proto in protos]
Adam Cozzette501ecec2023-09-26 14:36:20 -070093
Joshua Habermaneab1fa22024-08-19 13:29:22 -070094def _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 Cozzette501ecec2023-09-26 14:36:20 -070098 return ret
99
Joshua Habermaneab1fa22024-08-19 13:29:22 -0700100def _stage0_proto_staleness_test(name, src_files, src_rules, strip_prefix):
Adam Cozzette501ecec2023-09-26 14:36:20 -0700101 native.genrule(
102 name = name + "_generate_bootstrap",
103 srcs = src_rules,
Joshua Habermaneab1fa22024-08-19 13:29:22 -0700104 outs = ["bootstrap_generated_sources/" + f for f in _generated_hdrs_and_srcs(src_files, "stage0", "upb")],
Adam Cozzette501ecec2023-09-26 14:36:20 -0700105 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 Habermaneab1fa22024-08-19 13:29:22 -0700110 "--upb_out=bootstrap_stage=0:$(@D)/bootstrap_generated_sources/stage0 " +
Adam Cozzette501ecec2023-09-26 14:36:20 -0700111 " ".join(src_files),
112 )
113
114 staleness_test(
Mike Kruskal58312a62024-03-07 17:36:42 -0800115 name = name + "_stage0_staleness_test",
Joshua Habermaneab1fa22024-08-19 13:29:22 -0700116 outs = _generated_hdrs_and_srcs(src_files, "stage0", "upb"),
Adam Cozzette501ecec2023-09-26 14:36:20 -0700117 generated_pattern = "bootstrap_generated_sources/%s",
Joshua Habermaneab1fa22024-08-19 13:29:22 -0700118 target_files = native.glob(["stage0/**"]),
Adam Cozzette501ecec2023-09-26 14:36:20 -0700119 # 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 Habermaneab1fa22024-08-19 13:29:22 -0700126def _generate_stage1_proto(name, src_files, src_rules, generator, kwargs):
Adam Cozzette501ecec2023-09-26 14:36:20 -0700127 native.genrule(
128 name = "gen_{}_{}_stage1".format(name, generator),
129 srcs = src_rules,
Joshua Habermaneab1fa22024-08-19 13:29:22 -0700130 outs = _generated_hdrs_and_srcs(src_files, "stage1", generator),
Adam Cozzette501ecec2023-09-26 14:36:20 -0700131 cmd = "$(location " + _protoc + ") " +
132 "--plugin=protoc-gen-" + generator +
133 "=$(location " + _upbc(generator, 0) + ") " + _extra_proto_path +
Joshua Habermaneab1fa22024-08-19 13:29:22 -0700134 "--" + generator + "_out=bootstrap_stage=1:$(RULEDIR)/stage1 " +
Adam Cozzette501ecec2023-09-26 14:36:20 -0700135 " ".join(src_files),
Joshua Habermanbc394d22024-08-21 17:04:54 -0700136 visibility = _bootstrap_visibility,
Adam Cozzette501ecec2023-09-26 14:36:20 -0700137 tools = [
138 _protoc,
139 _upbc(generator, 0),
140 ],
141 **kwargs
142 )
143
Joshua Habermaneab1fa22024-08-19 13:29:22 -0700144def _cmake_staleness_test(name, src_files, proto_lib_deps, **kwargs):
Mike Kruskal8c0485c2024-03-08 10:13:42 -0800145 upb_minitable_proto_library(
146 name = name + "_minitable",
147 deps = proto_lib_deps,
148 **kwargs
Mike Kruskal58312a62024-03-07 17:36:42 -0800149 )
150
Mike Kruskal8c0485c2024-03-08 10:13:42 -0800151 # Copy the final gencode for staleness comparison
Joshua Habermaneab1fa22024-08-19 13:29:22 -0700152 files = _generated_hdrs_and_srcs(src_files, "cmake", "upb") + \
153 _generated_hdrs_and_srcs(src_files, "cmake", "upb_minitable")
Mike Kruskal8c0485c2024-03-08 10:13:42 -0800154 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 Habermaneab1fa22024-08-19 13:29:22 -0700160 srcs = [name + "_upb_proto", name + "_minitable"],
Joshua Habermand5bd5b92024-06-13 10:06:47 -0700161 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 Kruskal8c0485c2024-03-08 10:13:42 -0800169 )
170
Mike Kruskal58312a62024-03-07 17:36:42 -0800171 # Keep bazel gencode in sync with our checked-in sources needed for cmake builds.
172 staleness_test(
173 name = name + "_staleness_test",
Mike Kruskal8c0485c2024-03-08 10:13:42 -0800174 outs = files,
Mike Kruskal58312a62024-03-07 17:36:42 -0800175 generated_pattern = "generated_sources/%s",
176 tags = ["manual"],
177 )
178
Adam Cozzette501ecec2023-09-26 14:36:20 -0700179def bootstrap_upb_proto_library(
180 name,
Joshua Habermaneab1fa22024-08-19 13:29:22 -0700181 bootstrap_hdr,
Adam Cozzette501ecec2023-09-26 14:36:20 -0700182 google3_src_files,
183 google3_src_rules,
184 oss_src_files,
185 oss_src_rules,
186 oss_strip_prefix,
187 proto_lib_deps,
Adam Cozzette501ecec2023-09-26 14:36:20 -0700188 deps = [],
189 **kwargs):
190 """A version of upb_proto_library() that is augmented to allow for bootstrapping the compiler.
191
Joshua Habermanbc394d22024-08-21 17:04:54 -0700192 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 Cozzette501ecec2023-09-26 14:36:20 -0700196 Args:
197 name: Name of this rule. This name will resolve to a upb_proto_library().
Joshua Habermanbc394d22024-08-21 17:04:54 -0700198 bootstrap_hdr: The forwarding header that exposes the generated code, taking into account
199 the current stage.
Adam Cozzette501ecec2023-09-26 14:36:20 -0700200 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 Cozzette501ecec2023-09-26 14:36:20 -0700208 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 Habermaneab1fa22024-08-19 13:29:22 -0700212 _stage0_proto_staleness_test(name, oss_src_files, oss_src_rules, oss_strip_prefix)
Adam Cozzette501ecec2023-09-26 14:36:20 -0700213
214 # stage0 uses checked-in protos, and has no MiniTable.
215 native.cc_library(
216 name = name + "_stage0",
Joshua Habermaneab1fa22024-08-19 13:29:22 -0700217 srcs = _generated_hdrs_and_srcs(oss_src_files, "stage0", "upb"),
218 hdrs = [bootstrap_hdr],
Joshua Habermanbc394d22024-08-21 17:04:54 -0700219 visibility = _bootstrap_visibility,
Joshua Habermaneab1fa22024-08-19 13:29:22 -0700220 defines = ["UPB_BOOTSTRAP_STAGE=0"],
Adam Cozzette501ecec2023-09-26 14:36:20 -0700221 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 Habermaneab1fa22024-08-19 13:29:22 -0700232 _generate_stage1_proto(name, src_files, src_rules, "upb", kwargs)
233 _generate_stage1_proto(name, src_files, src_rules, "upb_minitable", kwargs)
Adam Cozzette501ecec2023-09-26 14:36:20 -0700234
235 native.cc_library(
236 name = name + "_minitable_stage1",
Joshua Habermaneab1fa22024-08-19 13:29:22 -0700237 srcs = _generated_files(src_files, "stage1", "upb_minitable", "c"),
238 hdrs = _generated_files(src_files, "stage1", "upb_minitable", "h"),
Joshua Habermanbc394d22024-08-21 17:04:54 -0700239 visibility = _bootstrap_visibility,
Joshua Habermaneab1fa22024-08-19 13:29:22 -0700240 defines = ["UPB_BOOTSTRAP_STAGE=1"],
Adam Cozzette501ecec2023-09-26 14:36:20 -0700241 deps = [
242 "//upb:generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me",
Joshua Habermaneab1fa22024-08-19 13:29:22 -0700243 ] + [dep + "_minitable_stage1" for dep in deps],
Adam Cozzette501ecec2023-09-26 14:36:20 -0700244 **kwargs
245 )
246 native.cc_library(
247 name = name + "_stage1",
Joshua Habermaneab1fa22024-08-19 13:29:22 -0700248 srcs = _generated_files(src_files, "stage1", "upb", "h"),
249 hdrs = [bootstrap_hdr],
Joshua Habermanbc394d22024-08-21 17:04:54 -0700250 visibility = _bootstrap_visibility,
Joshua Habermaneab1fa22024-08-19 13:29:22 -0700251 defines = ["UPB_BOOTSTRAP_STAGE=1"],
Adam Cozzette501ecec2023-09-26 14:36:20 -0700252 deps = [
253 "//upb:generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me",
254 ":" + name + "_minitable_stage1",
Joshua Habermaneab1fa22024-08-19 13:29:22 -0700255 ] + [dep + "_minitable_stage1" for dep in deps],
Adam Cozzette501ecec2023-09-26 14:36:20 -0700256 **kwargs
257 )
258
259 # The final protos are generated via normal upb_proto_library().
260 upb_proto_library(
Joshua Habermaneab1fa22024-08-19 13:29:22 -0700261 name = name + "_upb_proto",
Adam Cozzette501ecec2023-09-26 14:36:20 -0700262 deps = proto_lib_deps,
Joshua Habermaneab1fa22024-08-19 13:29:22 -0700263 **kwargs
264 )
265 native.cc_library(
266 name = name,
267 hdrs = [bootstrap_hdr],
268 deps = [name + "_upb_proto"],
Joshua Habermanbc394d22024-08-21 17:04:54 -0700269 visibility = _bootstrap_visibility,
Adam Cozzette501ecec2023-09-26 14:36:20 -0700270 **kwargs
271 )
Mike Kruskal58312a62024-03-07 17:36:42 -0800272
Joshua Habermaneab1fa22024-08-19 13:29:22 -0700273 _cmake_staleness_test(name, src_files, proto_lib_deps, **kwargs)