Skip to content

Commit 101494c

Browse files
committed
Separate protocol compiler toolchain into new repo
This is probably for the best, as it enables users to use earlier protobuf versions by not loading `//protoc:toolchains.bzl`. Leaving it wired into `scala/toolchains_repo.bzl` would've required users to patch it and to remove `protoc/BUILD`. Prompted by: bazel-contrib#1710 (comment)
1 parent 959ae48 commit 101494c

File tree

21 files changed

+182
-69
lines changed

21 files changed

+182
-69
lines changed

README.md

+48-30
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ host_platform_repo(name = "host_platform")
7676

7777
# This is optional, but still safe to include even when not using
7878
# `--incompatible_enable_proto_toolchain_resolution`. Requires calling
79-
# `scala_toolchains()`.
79+
# `scala_protoc_toolchains()` as seen below.
8080
register_toolchains("@rules_scala//protoc:all")
8181

8282
load("@rules_java//java:rules_java_deps.bzl", "rules_java_dependencies")
@@ -125,6 +125,13 @@ load("@rules_proto//proto:toolchains.bzl", "rules_proto_toolchains")
125125

126126
rules_proto_toolchains()
127127

128+
# Include this after loading `platforms` and `com_google_protobuf` to enable the
129+
# `//protoc` precompiled protocol compiler toolchains. See the "Using a
130+
# precompiled protocol compiler" section below.
131+
load("@rules_scala//protoc:toolchains.bzl", "scala_protoc_toolchains")
132+
133+
scala_protoc_toolchains()
134+
128135
load("@rules_scala//:scala_config.bzl", "scala_config")
129136

130137
# Stores the selected Scala version and other configuration parameters.
@@ -226,13 +233,37 @@ other toolchain registrations. It's safe to include even when not using
226233
register_toolchains("@rules_scala//protoc:all")
227234
```
228235

229-
Note that you _must_ call `scala_toolchains()` in `WORKSPACE`, even if all other
230-
toolchains are disabled (i.e., if using `scala_toolchains(scala = False)`). This
231-
isn't necessary under Bzlmod.
236+
#### Using `scala_protoc` in `MODULE.bazel`
237+
238+
The `scala_protoc` extension instantiates the protocol compiler toolchain
239+
binaries under Bzlmod:
240+
241+
```py
242+
# MODULE.bazel
243+
244+
scala_protoc = use_extension(
245+
"@rules_scala//scala/extensions:protoc.bzl",
246+
"scala_protoc",
247+
)
248+
```
249+
250+
#### Calling `scala_protoc_toolchains()` in `WORKSPACE`
251+
252+
The `scala_protoc_toolchains` macro instantiates the protocol compiler toolchain
253+
binaries under `WORKSPACE`:
254+
255+
```py
256+
# WORKSPACE
257+
258+
# Include this after loading `platforms` and `com_google_protobuf`.
259+
load("@rules_scala//protoc:toolchains.bzl", "scala_protoc_toolchains")
260+
261+
scala_protoc_toolchains()
262+
```
232263

233264
#### Specifying additional `protoc` platforms
234265

235-
Use the `protoc_platforms` parameter to specify additional [platforms][] if the
266+
Use the `platforms` parameter to specify additional [platforms][] if the
236267
execution platform may differ from the host platform, as when building with
237268
remote execution. Valid values come from the file name suffixes of
238269
[protocolbuffers/protobuf releases][]. It's also safe to explicitly include the
@@ -249,12 +280,8 @@ the remote execution platform is Linux running on an x86 processor.
249280
```py
250281
# MODULE.bazel
251282

252-
scala_deps = use_extension(
253-
"@rules_scala//scala/extensions:deps.bzl",
254-
"scala_deps",
255-
)
256-
scala_deps.toolchains(
257-
protoc_platforms = ["linux-x86_64"],
283+
scala_protoc.toolchains(
284+
platforms = ["linux-x86_64"],
258285
)
259286
```
260287

@@ -263,13 +290,8 @@ In `WORKSPACE` you would include:
263290
```py
264291
# WORKSPACE
265292

266-
load(
267-
"@rules_scala//scala:toolchains.bzl",
268-
"scala_toolchains",
269-
)
270-
271-
scala_toolchains(
272-
protoc_platforms = ["linux-x86_64"],
293+
scala_protoc_toolchains(
294+
platforms = ["linux-x86_64"],
273295
)
274296
```
275297

@@ -936,19 +958,15 @@ builds by avoiding `@com_google_protobuf//:protoc` recompilation.
936958

937959
### Minimum of `protobuf` v28
938960

939-
`rules_scala` requires at least `protobuf` v28, which contains the
940-
`bazel/common/proto_common.bzl` required for [protocol compiler
941-
toolchain](#protoc) support. This file appeared in v27, and no `ScalaPB` release
942-
supports `protobuf` v25.6, v26, or v27.
961+
`rules_scala` requires at least `protobuf` v28, and at least v29 for [protocol
962+
compiler toolchain](#protoc) support. No `ScalaPB` release supports `protobuf`
963+
v25.6, v26, or v27.
943964

944965
#### Using earlier `protobuf` versions
945966

946-
If you can't update to `protobuf` v28 or later right now, you will need to patch:
947-
948-
- `scala/toolchains.bzl`: remove `setup_protoc_toolchains()` references
949-
- `protoc/BUILD`: remove entirely
950-
951-
Then build using Bazel 7 and the following maximum versions of key dependencies:
967+
If you can't update to `protobuf` v28 or later right now, build using Bazel 7
968+
and the following maximum versions of key dependencies. This is not officially
969+
supported, but should work for some time.
952970

953971
| Dependency | Max compatible version | Reason |
954972
| :-: | :-: | :- |
@@ -1114,8 +1132,8 @@ flags][protoc-opts] for protocol compiler configuration requirements.
11141132

11151133
#### Using older versions of `protobuf`
11161134

1117-
See [Minimum of protobuf v28](#minimum-of-protobuf-v28) for details on using
1118-
older versions of protobuf.
1135+
See [Using earlier protobuf versions](#using-earlier-protobuf-versions) for
1136+
details on using older versions of protobuf if necessary.
11191137

11201138
### `scala_proto` not supported for Scala 2.11
11211139

WORKSPACE

+5
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ load("@rules_proto//proto:toolchains.bzl", "rules_proto_toolchains")
5656

5757
rules_proto_toolchains()
5858

59+
# Must come after loading `platforms` and `com_google_protobuf`.
60+
load("//protoc:toolchains.bzl", "scala_protoc_toolchains")
61+
62+
scala_protoc_toolchains()
63+
5964
load("//:scala_config.bzl", "scala_config")
6065

6166
scala_config(enable_compiler_dependency_tracking = True)

dt_patches/test_dt_patches/WORKSPACE

+5
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ load("@rules_proto//proto:toolchains.bzl", "rules_proto_toolchains")
6262

6363
rules_proto_toolchains()
6464

65+
# Must come after loading `platforms` and `com_google_protobuf`.
66+
load("@rules_scala//protoc:toolchains.bzl", "scala_protoc_toolchains")
67+
68+
scala_protoc_toolchains()
69+
6570
load("@rules_scala//:scala_config.bzl", "scala_config")
6671

6772
scala_config(enable_compiler_dependency_tracking = True)

dt_patches/test_dt_patches_user_srcjar/WORKSPACE

+5
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ load("@rules_proto//proto:toolchains.bzl", "rules_proto_toolchains")
6262

6363
rules_proto_toolchains()
6464

65+
# Must come after loading `platforms` and `com_google_protobuf`.
66+
load("@rules_scala//protoc:toolchains.bzl", "scala_protoc_toolchains")
67+
68+
scala_protoc_toolchains()
69+
6570
load("@rules_scala//:scala_config.bzl", "scala_config")
6671

6772
scala_config(enable_compiler_dependency_tracking = True)

examples/crossbuild/WORKSPACE

+5
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ load("@rules_proto//proto:toolchains.bzl", "rules_proto_toolchains")
6262

6363
rules_proto_toolchains()
6464

65+
# Must come after loading `platforms` and `com_google_protobuf`.
66+
load("@rules_scala//protoc:toolchains.bzl", "scala_protoc_toolchains")
67+
68+
scala_protoc_toolchains()
69+
6570
load("@rules_scala//:scala_config.bzl", "scala_config")
6671

6772
scala_config(

examples/overridden_artifacts/WORKSPACE

+5
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ load("@rules_proto//proto:toolchains.bzl", "rules_proto_toolchains")
6262

6363
rules_proto_toolchains()
6464

65+
# Must come after loading `platforms` and `com_google_protobuf`.
66+
load("@rules_scala//protoc:toolchains.bzl", "scala_protoc_toolchains")
67+
68+
scala_protoc_toolchains()
69+
6570
load("@rules_scala//:scala_config.bzl", "scala_config")
6671

6772
scala_config(scala_version = "3.3.5")

examples/scala3/WORKSPACE

+5
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ load("@rules_proto//proto:toolchains.bzl", "rules_proto_toolchains")
6262

6363
rules_proto_toolchains()
6464

65+
# Must come after loading `platforms` and `com_google_protobuf`.
66+
load("@rules_scala//protoc:toolchains.bzl", "scala_protoc_toolchains")
67+
68+
scala_protoc_toolchains()
69+
6570
load("@rules_scala//:scala_config.bzl", "scala_config")
6671

6772
scala_config(scala_version = "3.6.4")

examples/semanticdb/WORKSPACE

+5
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ load("@rules_proto//proto:toolchains.bzl", "rules_proto_toolchains")
6262

6363
rules_proto_toolchains()
6464

65+
# Must come after loading `platforms` and `com_google_protobuf`.
66+
load("@rules_scala//protoc:toolchains.bzl", "scala_protoc_toolchains")
67+
68+
scala_protoc_toolchains()
69+
6570
load("@rules_scala//:scala_config.bzl", "scala_config")
6671

6772
scala_config(scala_version = "2.13.16")

examples/testing/multi_frameworks_toolchain/WORKSPACE

+5
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ load("@rules_proto//proto:toolchains.bzl", "rules_proto_toolchains")
6262

6363
rules_proto_toolchains()
6464

65+
# Must come after loading `platforms` and `com_google_protobuf`.
66+
load("@rules_scala//protoc:toolchains.bzl", "scala_protoc_toolchains")
67+
68+
scala_protoc_toolchains()
69+
6570
load("@rules_scala//:scala_config.bzl", "scala_config")
6671

6772
scala_config()

examples/testing/scalatest_repositories/WORKSPACE

+5
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ load("@rules_proto//proto:toolchains.bzl", "rules_proto_toolchains")
6262

6363
rules_proto_toolchains()
6464

65+
# Must come after loading `platforms` and `com_google_protobuf`.
66+
load("@rules_scala//protoc:toolchains.bzl", "scala_protoc_toolchains")
67+
68+
scala_protoc_toolchains()
69+
6570
load("@rules_scala//:scala_config.bzl", "scala_config")
6671

6772
scala_config()

examples/testing/specs2_junit_repositories/WORKSPACE

+5
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ load("@rules_proto//proto:toolchains.bzl", "rules_proto_toolchains")
6262

6363
rules_proto_toolchains()
6464

65+
# Must come after loading `platforms` and `com_google_protobuf`.
66+
load("@rules_scala//protoc:toolchains.bzl", "scala_protoc_toolchains")
67+
68+
scala_protoc_toolchains()
69+
6570
load("@rules_scala//:scala_config.bzl", "scala_config")
6671

6772
scala_config()

protoc/BUILD

+8-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@ load(
66
"@com_google_protobuf//bazel/toolchains:proto_toolchain.bzl",
77
"proto_toolchain",
88
)
9-
load("@rules_scala_toolchains//protoc:platforms.bzl", "PROTOC_PLATFORMS")
9+
load("@rules_scala_protoc_toolchains//:platforms.bzl", "PROTOC_PLATFORMS")
10+
11+
exports_files(
12+
["toolchains.bzl"],
13+
visibility = ["//visibility:public"],
14+
)
1015

1116
toolchain_type(
1217
name = "toolchain_type",
@@ -17,13 +22,14 @@ proto_lang_toolchain(
1722
name = "protoc_scala_toolchain",
1823
command_line = "unused-because-we-pass-protoc-to-scalapb",
1924
toolchain_type = ":toolchain_type",
25+
visibility = ["//visibility:public"],
2026
)
2127

2228
[
2329
proto_toolchain(
2430
name = platform,
2531
exec_compatible_with = specs,
26-
proto_compiler = "@rules_scala_toolchains//protoc:" + platform,
32+
proto_compiler = "@rules_scala_protoc_toolchains//:" + platform,
2733
)
2834
for platform, specs in PROTOC_PLATFORMS.items()
2935
]

protoc/private/protoc_toolchain.bzl

+21-12
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ def _platform_build(platform):
2828
)
2929
return protoc_build
3030

31-
def _download_build(repository_ctx, package, platform, protoc_build):
31+
def _download_build(repository_ctx, platform, protoc_build):
3232
repository_ctx.download_and_extract(
3333
url = PROTOC_DOWNLOAD_URL.format(
3434
platform = platform,
3535
version = PROTOC_VERSION,
3636
),
37-
output = "%s/%s" % (package, platform),
37+
output = platform,
3838
integrity = protoc_build["integrity"][PROTOC_VERSION],
3939
)
4040

@@ -47,40 +47,49 @@ def _emit_platform_entry(platform, protoc_build):
4747
]),
4848
)
4949

50-
def _generate_protoc_platforms(repository_ctx, package, builds):
50+
def _generate_protoc_platforms(repository_ctx, builds):
5151
content = ["PROTOC_PLATFORMS = {"]
5252
content.extend([_emit_platform_entry(p, b) for p, b in builds])
5353
content.append("}\n")
5454

5555
repository_ctx.file(
56-
package + "/platforms.bzl",
56+
"platforms.bzl",
5757
content = "\n".join(content),
5858
executable = False,
5959
)
6060

61-
def setup_protoc_toolchains(repository_ctx, package):
61+
ENABLE_PROTOC_TOOLCHAIN_ATTR = "INCOMPATIBLE_ENABLE_PROTO_TOOLCHAIN_RESOLUTION"
62+
63+
def _scala_protoc_toolchains_impl(repository_ctx):
6264
builds = []
6365
build_file_content = ""
6466

65-
if proto_common.INCOMPATIBLE_ENABLE_PROTO_TOOLCHAIN_RESOLUTION:
67+
if getattr(proto_common, ENABLE_PROTOC_TOOLCHAIN_ATTR, False):
6668
platforms = [_default_platform()]
67-
platforms += repository_ctx.attr.protoc_platforms
69+
platforms += repository_ctx.attr.platforms
6870
builds = {p: _platform_build(p) for p in platforms}.items()
6971
build_file_content = _PROTOC_TOOLCHAIN_BUILD
7072

7173
for platform, build in builds:
72-
_download_build(repository_ctx, package, platform, build)
74+
_download_build(repository_ctx, platform, build)
7375

74-
_generate_protoc_platforms(repository_ctx, package, builds)
76+
_generate_protoc_platforms(repository_ctx, builds)
7577

78+
# Always generate a root package, even if it's empty, to ensure
79+
# `register_toolchains("@rules_scala//protoc:all")` always works.
7680
repository_ctx.file(
77-
package + "/BUILD",
81+
"BUILD",
7882
content = build_file_content,
7983
executable = False,
8084
)
8185

82-
_PROTOC_TOOLCHAIN_BUILD = """
83-
load(":platforms.bzl", "PROTOC_PLATFORMS")
86+
scala_protoc_toolchains = repository_rule(
87+
implementation = _scala_protoc_toolchains_impl,
88+
doc = "Precompiled protocol compiler toolchain binaries",
89+
attrs = {"platforms": attr.string_list()},
90+
)
91+
92+
_PROTOC_TOOLCHAIN_BUILD = """load(":platforms.bzl", "PROTOC_PLATFORMS")
8493
8594
[
8695
alias(

protoc/toolchains.bzl

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
"""Precompiled protocol compiler toolchain repository interface.
2+
3+
```py
4+
# WORKSPACE
5+
6+
# Include this as early in the file as possible.
7+
register_toolchains("@rules_scala//protoc:all")
8+
9+
# Include this after loading `platforms` and `com_google_protobuf`.
10+
load("@rules_scala//protoc:toolchains.bzl", "scala_protoc_toolchains")
11+
12+
scala_protoc_toolchains()
13+
```
14+
"""
15+
16+
load(":private/protoc_toolchain.bzl", _toolchains = "scala_protoc_toolchains")
17+
18+
def scala_protoc_toolchains(platforms = []):
19+
"""Creates a repo of precompiled protocol compiler toolchain binaries.
20+
21+
Used by `//protoc` to implement precompiled protocol compiler toochains.
22+
23+
Args:
24+
platforms: Operating system and architecture identifiers for
25+
precompiled protocol compiler releases, taken from
26+
protocolbuffers/protobuf releases file name suffixes. If
27+
unspecified, will use the identifier matching the `HOST_CONSTRAINTS`
28+
from `@platforms//host:constraints.bzl`. Only takes effect when
29+
`--incompatible_enable_proto_toolchain_resolution` is `True`.
30+
"""
31+
_toolchains(
32+
name = "rules_scala_protoc_toolchains",
33+
platforms = platforms,
34+
)

0 commit comments

Comments
 (0)