1
1
# Cross compilation support
2
2
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.
5
6
6
7
## Quick start
7
8
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:
9
12
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
12
15
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.
14
67
15
68
Multiple rules, such as:
16
69
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)
21
74
22
- support such override via the ` scala_version ` attribute , e.g.:
75
+ support ` scala_version ` overrides , e.g.:
23
76
24
77
``` py
25
78
scala_library(
@@ -30,56 +83,69 @@ scala_library(
30
83
)
31
84
```
32
85
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.
34
89
35
90
## Version configuration
36
91
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:
39
95
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"] `
42
99
43
100
## Build settings
44
101
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.
46
105
47
106
### ` scala_version `
48
107
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 )):
50
111
51
112
``` py
52
113
string_setting(
53
114
name = " scala_version" ,
54
115
build_setting_default = " 3.3.1" ,
55
- values = [" 3.3.1" ],
116
+ values = [" 2.12.18 " , " 3.3.1" ],
56
117
visibility = [" //visibility:public" ],
57
118
)
58
- ...
59
119
```
60
120
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.
62
125
63
126
### Config settings
64
127
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 ) :
66
130
67
131
``` py
68
132
config_setting(
69
133
name = " scala_version_3_3_1" ,
70
134
flag_values = {" :scala_version" : " 3.3.1" },
71
135
)
72
- ...
73
136
```
74
137
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).
77
141
78
142
## Version-dependent behavior
79
143
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.
81
146
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.
83
149
84
150
### From toolchain
85
151
@@ -94,13 +160,11 @@ def _rule_impl(ctx):
94
160
95
161
### From config setting
96
162
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.
102
166
103
- See example usage of the ` select_for_scala_version ` :
167
+ #### Using the ` select_for_scala_version() ` macro
104
168
105
169
``` py
106
170
load(
@@ -128,11 +192,10 @@ scala_library(
128
192
)
129
193
```
130
194
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
134
197
135
- An example usage of ` select() ` to provide custom dependency for specific Scala version:
198
+ #### Using a manually crafted ` select() `
136
199
137
200
``` py
138
201
deps = select({
@@ -141,7 +204,8 @@ deps = select({
141
204
})
142
205
```
143
206
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:
145
209
146
210
``` py
147
211
def srcs (scala_version ):
@@ -150,28 +214,32 @@ def srcs(scala_version):
150
214
...
151
215
```
152
216
153
- and then in the ` BUILD ` file:
217
+ and then ` load() ` the macro in a ` BUILD ` file:
154
218
155
219
``` py
156
- load(" ... .bzl" , " srcs" )
220
+ load(" :my_macros .bzl" , " srcs" )
157
221
load(" @io_bazel_rules_scala_config//:config.bzl" , " SCALA_VERSIONS" )
158
222
load(" @rules_scala//:scala_cross_version.bzl" , " version_suffix" )
159
223
224
+ _SCALA_VERSION_SETTING_PREFIX = " @io_bazel_rules_scala_config//:scala_version"
225
+
160
226
scala_library(
161
227
...
162
228
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)
164
230
for v in SCALA_VERSIONS
165
231
}),
166
232
...
167
233
)
168
234
```
169
235
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 `
173
237
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.
175
243
176
244
``` py
177
245
def _scala_version_transition_impl (settings , attr ):
@@ -187,7 +255,11 @@ scala_version_transition = transition(
187
255
)
188
256
```
189
257
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):
191
263
192
264
``` py
193
265
load(
@@ -196,27 +268,62 @@ load(
196
268
" toolchain_transition_attr" ,
197
269
)
198
270
271
+ ...
272
+
199
273
_scala_library_attrs.update(toolchain_transition_attr)
200
274
201
275
def make_scala_library (* extras ):
202
276
return rule(
203
277
attrs = _dicts.add(
204
- ...
205
- toolchain_transition_attr,
278
+ _scala_library_attrs,
206
279
...
207
280
),
208
281
...
209
282
cfg = scala_version_transition,
210
- incompatible_use_toolchain_transition = True ,
211
283
...
212
284
)
213
285
```
214
286
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
+
215
318
## Toolchains
216
319
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.
218
323
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:
220
327
221
328
``` py
222
329
toolchain(
@@ -229,15 +336,21 @@ toolchain(
229
336
### Cross-build support tiers
230
337
231
338
` 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.
233
340
234
341
We can distinguish following tiers:
235
342
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.
237
345
- (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.
239
350
- (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.
241
354
- [ the main Scala toolchain] ( /scala/BUILD )
242
355
- [ Scalafmt] ( /scala/scalafmt/BUILD )
243
356
- [ Scalatest] ( /testing/testing.bzl )
0 commit comments