• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Protobuf Rust runtime packages.
2
3load("@bazel_skylib//rules:common_settings.bzl", "string_flag")
4load("@rules_pkg//pkg:mappings.bzl", "pkg_filegroup", "pkg_files", "strip_prefix")
5load("@rules_pkg//pkg:zip.bzl", "pkg_zip")
6load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
7load("//bazel/toolchains:proto_lang_toolchain.bzl", "proto_lang_toolchain")
8
9licenses(["notice"])
10
11package_group(
12    name = "protobuf_internal",
13    packages = [
14        "//rust/...",
15        "//src/google/protobuf/...",
16    ],
17)
18
19# The current Rust Protobuf runtime for the build. Depending on the value of
20# `:rust_proto_library_kernel` build setting it forwards to the cpp or upb kernels. This is the
21# target that users are expected to depend on.
22#
23# Rust gencode (via `rust_upb_proto_library` and `rust_cc_proto_library`) doesn't depend on this
24# target, instead, it depends on the kernel-specific libraries directly. The reason is that we need
25# to be able to use both kernels in the same build. That allows us to have one TAP config for both
26# kernels, and to run tests using a single Blaze invocation.
27#
28# WARNING: It's critical that users do not end up using Rust Protobufs with multiple kernels in
29# their binaries. Currently this is achieved by using bzl visibility on kernel-specific rules.
30# TODO: Hide the kernel-specific targets once we can restrict a target visibility to a
31# rule.
32rust_library(
33    name = "protobuf",
34    srcs = ["protobuf.rs"],
35    rustc_flags = select({
36        ":use_upb_kernel": ["--cfg=upb_kernel"],
37        "//conditions:default": ["--cfg=cpp_kernel"],
38    }),
39    visibility = ["//visibility:public"],
40    deps = select({
41        ":use_upb_kernel": [":protobuf_upb"],
42        "//conditions:default": [":protobuf_cpp"],
43    }),
44)
45
46# This list contains kernel-agnostic logic and simple kernel-specific logic controlled by
47# `#[cfg(...)]` attributes. That forces us to compile these files twice, once for each kernel. As a
48# result these files are included in both `:protobuf_upb` and `:protobuf_cpp`.
49# This is in principle identical to how we compile regular Rust source files twice
50# (once for production, and once for unit testing).
51#
52# shared.rs is the root of the crate and has public items re-exported in protobuf.rs for user use.
53PROTOBUF_SHARED = [
54    # go/keep-sorted start
55    "codegen_traits.rs",
56    "cord.rs",
57    "enum.rs",
58    "internal.rs",
59    "map.rs",
60    "optional.rs",
61    "prelude.rs",
62    "primitive.rs",
63    "proto_macro.rs",
64    "proxied.rs",
65    "repeated.rs",
66    "shared.rs",
67    "string.rs",
68    # go/keep-sorted end
69]
70
71# The Rust Protobuf runtime using the upb kernel.
72#
73# `rust_upb_proto_library` implicitly depends on this target. This target cannot depend on
74# `:rust_proto_library_kernel` build setting; it has to be fully functional under any value of that
75# setting.
76rust_library(
77    name = "protobuf_upb",
78    srcs = PROTOBUF_SHARED + ["upb.rs"],
79    crate_root = "shared.rs",
80    proc_macro_deps = [
81        "@crate_index//:paste",
82    ],
83    rustc_flags = [
84        "--cfg=upb_kernel",
85        "--cfg=bzl",
86    ],
87    visibility = [":protobuf_internal"],
88    deps = [
89        ":utf8",
90        "//rust/upb",
91    ],
92)
93
94rust_test(
95    name = "protobuf_upb_test",
96    crate = ":protobuf_upb",
97    rustc_flags = [
98        "--cfg=upb_kernel",
99        "--cfg=bzl",
100    ],
101    deps = [
102        "@crate_index//:googletest",
103    ],
104)
105
106# This provides an identical set of re-exports as `:protobuf` with `:use_upb_kernel` active.
107# This is only used for tests shared between runtimes.
108rust_library(
109    name = "protobuf_upb_export",
110    testonly = True,
111    srcs = ["protobuf.rs"],
112    rustc_flags = ["--cfg=upb_kernel"],
113    visibility = [":protobuf_internal"],
114    deps = [":protobuf_upb"],
115)
116
117# The Rust Protobuf runtime using the cpp kernel.
118#
119# `rust_cpp_proto_library` implicitly depends on this target. This target cannot depend on
120# `:rust_proto_library_kernel` build setting; it has to be fully functional under any value of that
121# setting.
122rust_library(
123    name = "protobuf_cpp",
124    srcs = PROTOBUF_SHARED + ["cpp.rs"],
125    crate_root = "shared.rs",
126    proc_macro_deps = [
127        "@crate_index//:paste",
128    ],
129    rustc_flags = [
130        "--cfg=cpp_kernel",
131        "--cfg=bzl",
132    ],
133    visibility = [":protobuf_internal"],
134    deps = [
135        ":utf8",
136        "//rust/cpp_kernel:cpp_api",
137    ],
138)
139
140rust_test(
141    name = "protobuf_cpp_test",
142    crate = ":protobuf_cpp",
143    rustc_flags = [
144        "--cfg=cpp_kernel",
145        "--cfg=bzl",
146    ],
147    deps = [
148        "@crate_index//:googletest",
149    ],
150)
151
152# This provides an identical set of re-exports as `:protobuf` with `:use_upb_kernel` inactive.
153# This is only used for tests shared between runtimes.
154rust_library(
155    name = "protobuf_cpp_export",
156    testonly = True,
157    srcs = ["protobuf.rs"],
158    rustc_flags = ["--cfg=cpp_kernel"],
159    visibility = [":protobuf_internal"],
160    deps = [":protobuf_cpp"],
161)
162
163alias(
164    name = "protobuf_gtest_matchers",
165    actual = select({
166        ":use_upb_kernel": ":protobuf_gtest_matchers_upb",
167        "//conditions:default": ":protobuf_gtest_matchers_cpp",
168    }),
169    visibility = [
170        "//visibility:public",
171    ],
172)
173
174rust_library(
175    name = "protobuf_gtest_matchers_cpp",
176    testonly = True,
177    srcs = ["gtest_matchers.rs"],
178    aliases = {
179        "//rust:protobuf_cpp": "protobuf",
180    },
181    visibility = [":protobuf_internal"],
182    deps = [
183        ":protobuf_cpp",
184        "@crate_index//:googletest",
185    ],
186)
187
188rust_library(
189    name = "protobuf_gtest_matchers_upb",
190    testonly = True,
191    srcs = ["gtest_matchers.rs"],
192    aliases = {
193        "//rust:protobuf_upb": "protobuf",
194    },
195    visibility = [":protobuf_internal"],
196    deps = [
197        ":protobuf_upb",
198        "@crate_index//:googletest",
199    ],
200)
201
202rust_library(
203    name = "utf8",
204    srcs = ["utf8.rs"],
205)
206
207proto_lang_toolchain(
208    name = "proto_rust_upb_toolchain",
209    command_line = "--rust_out=$(OUT)",
210    progress_message = "Generating Rust proto_library %{label}",
211    runtime = ":protobuf_upb",
212    visibility = ["//visibility:public"],
213)
214
215proto_lang_toolchain(
216    name = "proto_rust_cpp_toolchain",
217    command_line = "--rust_out=$(OUT)",
218    progress_message = "Generating Rust proto_library %{label}",
219    runtime = ":protobuf_cpp",
220    visibility = ["//visibility:public"],
221)
222
223package_group(
224    name = "rust_proto_library_allowed_in_different_package",
225    packages = ["//rust/test"],  # for unittest proto_libraries
226)
227
228# This flag controls what kernel all Rust Protobufs are using in the current build.
229string_flag(
230    name = "rust_proto_library_kernel",
231    build_setting_default = "cpp",
232    values = [
233        "upb",
234        "cpp",
235    ],
236)
237
238config_setting(
239    name = "use_upb_kernel",
240    flag_values = {
241        ":rust_proto_library_kernel": "upb",
242    },
243)
244
245pkg_files(
246    name = "rust_protobuf_src",
247    srcs = glob(
248        [
249            "*",
250        ],
251    ),
252    strip_prefix = strip_prefix.from_root("rust"),
253    visibility = ["//:__pkg__"],
254)
255
256pkg_files(
257    name = "crate_root_files",
258    srcs = glob(["cargo/**/*"]),
259    strip_prefix = strip_prefix.from_root("rust/cargo"),
260    visibility = ["//:__pkg__"],
261)
262
263pkg_filegroup(
264    name = "rust_protobuf_src_dir",
265    srcs = [
266        ":rust_protobuf_src",
267        "//rust/upb:rust_protobuf_upb_src",
268    ],
269    prefix = "src",
270)
271
272pkg_files(
273    name = "amalgamated_upb",
274    srcs = ["//upb:gen_amalgamation"],
275    strip_prefix = strip_prefix.from_root(""),
276)
277
278pkg_filegroup(
279    name = "rust_protobuf_libupb_src",
280    srcs = [
281        ":amalgamated_upb",
282        "//upb/cmake:upb_cmake_dist",
283    ],
284    prefix = "libupb",
285)
286
287pkg_zip(
288    name = "rust_crate",
289    srcs = [
290        ":crate_root_files",
291        ":rust_protobuf_libupb_src",
292        ":rust_protobuf_src_dir",
293        "//:LICENSE",
294    ],
295)
296
297pkg_files(
298    name = "protobuf_codegen_files",
299    srcs = glob(["protobuf_codegen/src/*"]) + ["protobuf_codegen/Cargo.toml"],
300    strip_prefix = strip_prefix.from_root("rust/protobuf_codegen"),
301)
302
303pkg_zip(
304    name = "codegen_crate",
305    srcs = [
306        ":protobuf_codegen_files",
307        "//:LICENSE",
308    ],
309    visibility = ["//rust:__pkg__"],
310)
311
312pkg_files(
313    name = "codegen_example_files",
314    srcs = glob(["protobuf_codegen/example/**/*"]),
315    strip_prefix = strip_prefix.from_root("rust/protobuf_codegen/example"),
316)
317
318pkg_zip(
319    name = "codegen_example",
320    srcs = [
321        ":codegen_example_files",
322        "//:LICENSE",
323    ],
324    visibility = ["//rust:__pkg__"],
325)
326
327sh_binary(
328    name = "cargo_test",
329    srcs = ["cargo_test.sh"],
330    data = [
331        ":codegen_crate",
332        ":codegen_example",
333        ":rust_crate",
334        "//:protoc",
335        "//upb_generator/minitable:protoc-gen-upb_minitable",
336    ],
337    deps = ["@bazel_tools//tools/bash/runfiles"],
338)
339