Skip to content

Commit 427e1c9

Browse files
committed
Clean up cross-compilation.md, rm deprecated attr
Includes a full editing pass over `docs/cross-compilation.md` and removes the `incompatible_use_toolchain_transition` attribute, which has been deprecated since before Bazel 6.5.0. - https://bazel.build/versions/6.4.0/rules/lib/globals?hl=en#rule The "Cross-build support tiers" could use extra review by someone more knowledgable about that aspect of `rules_scala`. Prompted by a suggestion by @gergelyfabian in bazel-contrib#1703 to update a single line, but turned into a complete overhaul.
1 parent 85519d0 commit 427e1c9

17 files changed

+168
-76
lines changed

docs/cross-compilation.md

+168-55
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,78 @@
11
# Cross compilation support
22

3-
Read *Quick start* for an information on how to use cross compilation.
4-
The remaining sections contain more detailed information, useful especially for toolchain & rule developers.
3+
Read [*Quick start*](#quick-start) for information on how to use cross
4+
compilation. The remaining sections contain more detailed information, useful
5+
especially for toolchain and rule developers.
56

67
## Quick start
78

8-
`scala_config` repository rule accepts two parameters related to Scala version:
9+
The `scala_config` module extension (or`WORKSPACE` macro) creates the
10+
`@io_bazel_rules_scala_config` repository. It accepts two parameters that
11+
specify the the Scala versions supported within the project:
912

10-
- `scala_version` – a single, default version;
11-
- `scala_versions` – a list of versions to make available for use.
13+
- `scala_version` – a single default version
14+
- `scala_versions` – a list of versions supported or required by the project
1215

13-
The first one, `scala_version`, will be used as a default, but it can be overridden for specific targets for any version from the `scala_versions`.
16+
__`MODULE.bazel`__
17+
18+
```py
19+
# MODULE.bazel
20+
scala_config = use_extension(
21+
"@rules_scala//scala/extensions:config.bzl",
22+
"scala_config",
23+
)
24+
25+
scala_config.settings(
26+
scala_version = "2.13.15",
27+
# No need to include `scala_version` in `scala_versions`.
28+
scala_versions = [
29+
"2.11.12",
30+
"2.12.20",
31+
"3.1.3",
32+
"3.2.2",
33+
"3.3.5",
34+
],
35+
)
36+
```
37+
38+
__`WORKSPACE` (Legacy support)__
39+
40+
```py
41+
load("@rules_scala//:scala_config.bzl", "scala_config")
42+
43+
scala_config(
44+
scala_version = "3.1.3",
45+
# You _must_ include `scala_version` in `scala_versions`.
46+
scala_versions = [
47+
"2.11.12",
48+
"2.12.20",
49+
"2.13.15",
50+
"3.1.3",
51+
"3.2.2",
52+
"3.3.5",
53+
],
54+
)
55+
```
56+
57+
58+
59+
The first parameter, `scala_version`, defines the default version of Scala to
60+
use when building the project. Values from `scala_versions` can override the
61+
default in one of two ways:
62+
63+
- The `--repo_env=SCALA_VERSION=...` command line flag overrides the default for
64+
the entire build.
65+
- The `scala_version` build rule attribute overrides the Scala version used for
66+
a specific target and its dependencies.
1467

1568
Multiple rules, such as:
1669

17-
- [scala_library](/scala/private/rules/scala_library.bzl)
18-
- [scala_binary](/scala/private/rules/scala_binary.bzl)
19-
- [scala_repl](/scala/private/rules/scala_repl.bzl)
20-
- [scala_test](/scala/private/rules/scala_test.bzl)
70+
- [scala_library](../scala/private/rules/scala_library.bzl)
71+
- [scala_binary](../scala/private/rules/scala_binary.bzl)
72+
- [scala_repl](../scala/private/rules/scala_repl.bzl)
73+
- [scala_test](../scala/private/rules/scala_test.bzl)
2174

22-
support such override via the `scala_version` attribute, e.g.:
75+
support `scala_version` overrides, e.g.:
2376

2477
```py
2578
scala_library(
@@ -30,56 +83,69 @@ scala_library(
3083
)
3184
```
3285

33-
For this library and all its dependencies 2.12.18 compiler will be used, unless explicitly overridden again in another target.
86+
The above `scala_library` and all its dependencies will use the Scala 2.12.18
87+
compiler, unless explicitly overridden by another target that depends on this
88+
one.
3489

3590
## Version configuration
3691

37-
`scala_config` creates the repository `@io_bazel_rules_scala_config`.
38-
File created there, `config.bzl`, consists of many variables. In particular:
92+
The `scala_config` module extension (or `WORKSPACE` macro) creates the
93+
`@io_bazel_rules_scala_config` repository. Its generated `config.bzl` file
94+
contains several variables, including:
3995

40-
- `SCALA_VERSION` – representing the default Scala version, e.g. `"3.3.1"`;
41-
- `SCALA_VERSIONS` – representing all configured Scala versions, e.g. `["2.12.18", "3.3.1"]`.
96+
- `SCALA_VERSION` – representing the default Scala version, e.g., `"3.3.1"`
97+
- `SCALA_VERSIONS` – representing all configured Scala versions, e.g.,
98+
`["2.12.18", "3.3.1"]`
4299

43100
## Build settings
44101

45-
Configured `SCALA_VERSIONS` correspond to allowed values of [build setting](https://bazel.build/extending/config#user-defined-build-setting).
102+
Each element of `SCALA_VERSIONS` corresponds to an allowed [build
103+
setting](https://bazel.build/extending/config#user-defined-build-settings)
104+
value.
46105

47106
### `scala_version`
48107

49-
`@io_bazel_rules_scala_config` in its root package defines the following build setting:
108+
The root package of `@io_bazel_rules_scala_config` defines the following build
109+
setting (specifically, a ['string_setting()' from '@bazel_skylib'](
110+
https://github.com/bazelbuild/bazel-skylib/blob/1.7.1/docs/common_settings_doc.md#string_setting)):
50111

51112
```py
52113
string_setting(
53114
name = "scala_version",
54115
build_setting_default = "3.3.1",
55-
values = ["3.3.1"],
116+
values = ["2.12.18", "3.3.1"],
56117
visibility = ["//visibility:public"],
57118
)
58-
...
59119
```
60120

61-
This build setting can be subject of change by [transitions](https://bazel.build/extending/config#user-defined-transitions) (within allowed `values`).
121+
This defines values allowed by the custom [user-defined
122+
transition](https://bazel.build/extending/config#user-defined-transitions)
123+
described in the [Requesting a specific version for a custom
124+
'rule'](#custom-rule) section below.
62125

63126
### Config settings
64127

65-
Then for each Scala version we have a [config setting](https://bazel.build/extending/config#build-settings-and-select):
128+
For each Scala version in the above `string_setting()`, we have a [config
129+
setting]( https://bazel.build/extending/config#build-settings-and-select):
66130

67131
```py
68132
config_setting(
69133
name = "scala_version_3_3_1",
70134
flag_values = {":scala_version": "3.3.1"},
71135
)
72-
...
73136
```
74137

75-
The `name` of `config_setting` corresponds to `"scala_version" + version_suffix(scala_version)`.
76-
One may use this config setting in `select()` e.g. to provide dependencies relevant to a currently used Scala version.
138+
The `name` of the `config_setting` corresponds to `"scala_version" +
139+
version_suffix(scala_version)`. One may use this config setting in `select()`
140+
(e.g., to provide dependencies relevant to a currently used Scala version).
77141

78142
## Version-dependent behavior
79143

80-
Don't rely on `SCALA_VERSION` as it represents the default Scala version, not necessarily the one that is currently requested.
144+
Don't rely on `SCALA_VERSION` as it represents the default Scala version, not
145+
necessarily the one that is currently requested.
81146

82-
If you need to customize the behavior for specific Scala version, there are two scenarios.
147+
There are two scenarios for customizing behavior based on a specific Scala
148+
version.
83149

84150
### From toolchain
85151

@@ -94,13 +160,11 @@ def _rule_impl(ctx):
94160

95161
### From config setting
96162

97-
In BUILD files, you need to use the config settings with `select()`.
98-
Majority of use cases is covered by the `select_for_scala_version` utility macro.
99-
If more flexibility is needed, you can always write the select manually.
100-
101-
#### With select macro
163+
In `BUILD` files, you need to use the config settings with `select()`. The
164+
majority of use cases are covered by the `select_for_scala_version()` utility
165+
macro. If more flexibility is needed, you can always write the select manually.
102166

103-
See example usage of the `select_for_scala_version`:
167+
#### Using the `select_for_scala_version()` macro
104168

105169
```py
106170
load(
@@ -128,11 +192,10 @@ scala_library(
128192
)
129193
```
130194

131-
See complete documentation in the [scala_cross_version_select.bzl](/scala/scala_cross_version_select.bzl) file
132-
133-
#### Manually
195+
See the complete documentation in the [scala_cross_version_select.bzl](
196+
../scala/scala_cross_version_select.bzl) file
134197

135-
An example usage of `select()` to provide custom dependency for specific Scala version:
198+
#### Using a manually crafted `select()`
136199

137200
```py
138201
deps = select({
@@ -141,7 +204,8 @@ deps = select({
141204
})
142205
```
143206

144-
For more complex logic, you can extract it to a `.bzl` file:
207+
For more complex logic, define a macro taking a `scala_version` argument in a
208+
`.bzl` file:
145209

146210
```py
147211
def srcs(scala_version):
@@ -150,28 +214,32 @@ def srcs(scala_version):
150214
...
151215
```
152216

153-
and then in the `BUILD` file:
217+
and then `load()` the macro in a `BUILD` file:
154218

155219
```py
156-
load("....bzl", "srcs")
220+
load(":my_macros.bzl", "srcs")
157221
load("@io_bazel_rules_scala_config//:config.bzl", "SCALA_VERSIONS")
158222
load("@rules_scala//:scala_cross_version.bzl", "version_suffix")
159223

224+
_SCALA_VERSION_SETTING_PREFIX = "@io_bazel_rules_scala_config//:scala_version"
225+
160226
scala_library(
161227
...
162228
srcs = select({
163-
"@io_bazel_rules_scala_config//:scala_version" + version_suffix(v): srcs(v)
229+
SCALA_VERSION_SETTING_PREFIX + version_suffix(v): srcs(v)
164230
for v in SCALA_VERSIONS
165231
}),
166232
...
167233
)
168234
```
169235

170-
## Requesting specific version
171-
172-
To use other than default version of Scala, you need to change the current `@io_bazel_rules_scala_config//:scala_version` build setting.
236+
## <a id="custom-rule"></a>Requesting a specific version for a custom `rule`
173237

174-
Simple transition, setting the Scala version to one found in `scala_version` attribute:
238+
To enable a `rule` to use a version of Scala other than the default, first
239+
assign the desired alternative versions to the `scala_versions` configuration
240+
parameter. `scala_version_transition` from [`scala/scala_cross_version.bzl`](
241+
../scala/scala_cross_version.bzl) then selects one of the `scala_versions` so
242+
configured.
175243

176244
```py
177245
def _scala_version_transition_impl(settings, attr):
@@ -187,7 +255,11 @@ scala_version_transition = transition(
187255
)
188256
```
189257

190-
To use it in a rule, use the `scala_version_transition` as `cfg` and use `toolchain_transition_attr` in `attrs`:
258+
In your own [`rule`](https://bazel.build/rules/lib/globals/bzl#rule) definition,
259+
assign the `scala_version_transition` to the `cfg` attribute and include the
260+
`toolchain_transition_attr` elements in `attrs`. For an example, see
261+
`make_scala_library()` from [`scala/private/rules/scala_library.bzl`](
262+
../scala/private/rules/scala_library.bzl):
191263

192264
```py
193265
load(
@@ -196,27 +268,62 @@ load(
196268
"toolchain_transition_attr",
197269
)
198270

271+
...
272+
199273
_scala_library_attrs.update(toolchain_transition_attr)
200274

201275
def make_scala_library(*extras):
202276
return rule(
203277
attrs = _dicts.add(
204-
...
205-
toolchain_transition_attr,
278+
_scala_library_attrs,
206279
...
207280
),
208281
...
209282
cfg = scala_version_transition,
210-
incompatible_use_toolchain_transition = True,
211283
...
212284
)
213285
```
214286

287+
Now your `rule` can take a `scala_version` parameter to ensure it builds with a
288+
specific Scala version. See [test_cross_build/version_specific/BUILD](
289+
../test_cross_build/version_specific/BUILD) for examples of this, such as:
290+
291+
```py
292+
scala_library(
293+
name = "since_3_3",
294+
srcs = ["since_3_3.scala"],
295+
scala_version = "3.3.5",
296+
)
297+
298+
scala_library(
299+
name = "before_3_3",
300+
srcs = ["before_3_3.scala"],
301+
scala_version = "3.2.2",
302+
)
303+
304+
# What's new in 3.2
305+
scala_library(
306+
name = "since_3_2",
307+
srcs = ["since_3_2.scala"],
308+
scala_version = "3.2.2",
309+
)
310+
311+
scala_library(
312+
name = "before_3_2",
313+
srcs = ["before_3_2.scala"],
314+
scala_version = "3.1.3",
315+
)
316+
```
317+
215318
## Toolchains
216319

217-
Standard [toolchain resolution](https://bazel.build/extending/toolchains#toolchain-resolution) procedure determines which toolchain to use for Scala targets.
320+
The standard [toolchain resolution](
321+
https://bazel.build/extending/toolchains#toolchain-resolution)
322+
procedure determines which toolchain to use for Scala targets.
218323

219-
Toolchain should declare its compatibility with Scala version by using `target_settings` attribute of the `toolchain` rule:
324+
Each toolchain should declare its compatibility with a specific Scala version by
325+
using the `target_settings` attribute of the [`toolchain`](
326+
https://bazel.build/reference/be/platforms-and-toolchains#toolchain) rule:
220327

221328
```py
222329
toolchain(
@@ -229,15 +336,21 @@ toolchain(
229336
### Cross-build support tiers
230337

231338
`rules_scala` consists of many toolchains implementing various toolchain types.
232-
Their support level for cross-build setup varies.
339+
Their support level for cross-build setups varies.
233340

234341
We can distinguish following tiers:
235342

236-
- No `target_settings` set – not migrated, will work on the default `SCALA_VERSION`; undefined behavior on other versions.
343+
- No `target_settings` set – not migrated, will work on the default
344+
`SCALA_VERSION`; undefined behavior on other versions.
237345
- (all toolchains not mentioned elsewhere)
238-
- `target_settings` set to the `SCALA_VERSION` – not fully migrated; will work only on the default `SCALA_VERSION` and will fail the toolchain resolution on other versions.
346+
347+
- `target_settings` set to the `SCALA_VERSION` – not fully migrated; will work
348+
only on the default `SCALA_VERSION` and will fail the toolchain resolution
349+
on other versions.
239350
- (no development in progress)
240-
- Multiple toolchain instances with `target_settings` corresponding to each of `SCALA_VERSIONS` – fully migrated; will work in cross-build setup.
351+
352+
- Multiple toolchain instances with `target_settings` corresponding to each of
353+
`SCALA_VERSIONS` – fully migrated; will work in cross-build setup.
241354
- [the main Scala toolchain](/scala/BUILD)
242355
- [Scalafmt](/scala/scalafmt/BUILD)
243356
- [Scalatest](/testing/testing.bzl)

docs/toolchain_development.md

-2
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@ To define toolchain deps with deps exporting, the following steps need to be tak
105105
),
106106
},
107107
toolchains = ["//my_rules/toolchain:my_toolchain_type"],
108-
incompatible_use_toolchain_transition = True,
109108
)
110109
```
111110

@@ -170,6 +169,5 @@ Intended to be used when defining toolchain deps exporting rules. Eg.:
170169
),
171170
},
172171
toolchains = ["//my_rules/toolchain:my_toolchain_type"],
173-
incompatible_use_toolchain_transition = True,
174172
)
175173
```

jmh/toolchain/toolchain.bzl

-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ export_toolchain_deps = rule(
5252
),
5353
},
5454
toolchains = [_toolchain_type],
55-
incompatible_use_toolchain_transition = True,
5655
)
5756

5857
def setup_jmh_toolchain(name):

scala/plusone.bzl

-1
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,4 @@ collect_plus_one_deps_aspect = aspect(
2727
implementation = _collect_plus_one_deps_aspect_impl,
2828
attr_aspects = ["deps", "exports"],
2929
toolchains = [Label("//scala:toolchain_type")],
30-
incompatible_use_toolchain_transition = True,
3130
)

0 commit comments

Comments
 (0)