-
Notifications
You must be signed in to change notification settings - Fork 207
/
jvm.bzl
349 lines (314 loc) · 12.1 KB
/
jvm.bzl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
# Copyright 2018 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Kotlin Rules
### Setup
Add the following snippet to your `WORKSPACE` file:
```bzl
git_repository(
name = "io_bazel_rules_kotlin",
remote = "https://github.com/bazelbuild/rules_kotlin.git",
commit = "<COMMIT_HASH>",
)
load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kotlin_repositories", "kt_register_toolchains")
kotlin_repositories(kotlin_release_version = "1.2.21")
kt_register_toolchains()
```
To enable persistent worker support, add the following to the appropriate `bazelrc` file:
```
build --strategy=KotlinCompile=worker
test --strategy=KotlinCompile=worker
```
### Standard Libraries
The Kotlin libraries that are bundled in a kotlin release should be used with the rules, the mandatory standard libraries are added implicetly. After enabling
the repository the following Kotlin Libraries are also made available from the workspace `com_github_jetbrains_kotlin`:
* `kotlin-test`,
* `kotlin-reflect`.
So if you needed to add reflect as a dep use the following label `@com_github_jetbrains_kotlin//:kotlin-reflect`.
### Mixed Mode compilation
The JVM rules can compile both Java and Kotlin sources. The Java compiler wrapper is not optimized or persistent and does not have the features found in the
native java rules. This mode is usefull for migrating a package to Kotlin over time.
### Annotation Processing
Annotation processing works just as it does in Java, plugins are declared via a [`java_plugin`](https://docs.bazel.build/versions/master/be/java.html#java_plugin)
and may also be inherited from a `java_library` via the `exported_plugins` attribute. Annotation work in mixed-mode compilation and the Kotlin compiler take
care of processing both aspects.
An example which can be found under `//examples/dagger`:
```bzl
java_plugin(
name = "dagger_plugin",
deps = [
"@dagger_compiler//jar",
"@guava//jar",
"@dagger_producers//jar",
"@dagger//jar",
"@javax_inject//jar"
],
processor_class = "dagger.internal.codegen.ComponentProcessor"
)
java_library(
name = "dagger_lib",
exports = [
"@javax_inject//jar",
"@dagger//jar",
],
exported_plugins = ["dagger_plugin"]
)
kt_jvm_binary(
name = "dagger",
srcs = glob(["src/**"]),
main_class = "coffee.CoffeeApp",
deps = [":dagger_lib"],
)
```
"""
load(
"//kotlin/internal:defs.bzl",
_KtJvmInfo = "KtJvmInfo",
_TOOLCHAIN_TYPE = "TOOLCHAIN_TYPE",
)
load(
"//kotlin/internal/jvm:plugins.bzl",
_kt_jvm_plugin_aspect = "kt_jvm_plugin_aspect",
)
load(
"//kotlin/internal:defs.bzl",
_KT_COMPILER_REPO = "KT_COMPILER_REPO",
)
load(
"//kotlin/internal/jvm:impl.bzl",
_kt_jvm_binary_impl = "kt_jvm_binary_impl",
_kt_jvm_import_impl = "kt_jvm_import_impl",
_kt_jvm_junit_test_impl = "kt_jvm_junit_test_impl",
_kt_jvm_library_impl = "kt_jvm_library_impl",
)
_implicit_deps = {
"_singlejar": attr.label(
executable = True,
cfg = "host",
default = Label("@bazel_tools//tools/jdk:singlejar"),
allow_files = True,
),
"_zipper": attr.label(
executable = True,
cfg = "host",
default = Label("@bazel_tools//tools/zip:zipper"),
allow_files = True,
),
"_java_runtime": attr.label(
default = Label("@bazel_tools//tools/jdk:current_java_runtime"),
),
"_java_stub_template": attr.label(
cfg = "host",
default = Label("@kt_java_stub_template//file"),
),
"_toolchain": attr.label(
doc = """The Kotlin JVM Runtime. it's only purpose is to enable the Android native rules to discover the Kotlin
runtime for dexing""",
default = Label("@" + _KT_COMPILER_REPO + "//:kotlin-runtime"),
cfg = "target",
),
}
_common_attr = _implicit_deps + {
"srcs": attr.label_list(
doc = """The list of source files that are processed to create the target, this can contain both Java and Kotlin
files. Java analysis occurs first so Kotlin classes may depend on Java classes in the same compilation unit.""",
default = [],
allow_files = [".srcjar", ".kt", ".java"],
),
"deps": attr.label_list(
doc = """A list of dependencies of this rule.See general comments about `deps` at
[Attributes common to all build rules](https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes).""",
aspects = [_kt_jvm_plugin_aspect],
providers = [
[JavaInfo],
],
allow_files = False,
),
"runtime_deps": attr.label_list(
doc = """Libraries to make available to the final binary or test at runtime only. Like ordinary deps, these will
appear on the runtime classpath, but unlike them, not on the compile-time classpath.""",
default = [],
allow_files = False,
),
"resources": attr.label_list(
doc = """A list of files that should be include in a Java jar.""",
default = [],
allow_files = True,
),
"resource_strip_prefix": attr.string(
doc = """The path prefix to strip from Java resources, files residing under common prefix such as
`src/main/resources` or `src/test/resources` will have stripping applied by convention.""",
default = "",
),
"resource_jars": attr.label_list(
doc = """Set of archives containing Java resources. If specified, the contents of these jars are merged into
the output jar.""",
default = [],
),
"data": attr.label_list(
doc = """The list of files needed by this rule at runtime. See general comments about `data` at
[Attributes common to all build rules](https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes).""",
allow_files = True,
cfg = "data",
),
"plugins": attr.label_list(
default = [],
aspects = [_kt_jvm_plugin_aspect],
),
"module_name": attr.string(
doc = """The name of the module, if not provided the module name is derived from the label. --e.g.,
`//some/package/path:label_name` is translated to
`some_package_path-label_name`.""",
mandatory = False,
),
}
_lib_common_attr = _common_attr + {
"exports": attr.label_list(
doc = """Exported libraries.
Deps listed here will be made available to other rules, as if the parents explicitly depended on
these deps. This is not true for regular (non-exported) deps.""",
default = [],
providers = [JavaInfo],
),
"neverlink": attr.bool(
doc = """If true only use this library for compilation and not at runtime.""",
default = False,
),
}
_runnable_common_attr = _common_attr + {
"jvm_flags": attr.string_list(
doc = """A list of flags to embed in the wrapper script generated for running this binary. Note: does not yet
support make variable substitution.""",
default = [],
),
}
_common_outputs = dict(
jar = "%{name}.jar",
jdeps = "%{name}.jdeps",
# The params file, declared here so that validate it can be validated for testing.
# jar_2_params = "%{name}.jar-2.params",
srcjar = "%{name}-sources.jar",
)
kt_jvm_library = rule(
doc = """This rule compiles and links Kotlin and Java sources into a .jar file.""",
attrs = _lib_common_attr,
outputs = _common_outputs,
toolchains = [_TOOLCHAIN_TYPE],
implementation = _kt_jvm_library_impl,
provides = [JavaInfo, _KtJvmInfo],
)
kt_jvm_binary = rule(
doc = """Builds a Java archive ("jar file"), plus a wrapper shell script with the same name as the rule. The wrapper
shell script uses a classpath that includes, among other things, a jar file for each library on which the binary
depends.
**Note:** This rule does not have all of the features found in [`java_binary`](https://docs.bazel.build/versions/master/be/java.html#java_binary).
It is appropriate for building workspace utilities. `java_binary` should be preferred for release artefacts.
""",
attrs = dict(_runnable_common_attr.items() + {
"main_class": attr.string(
doc = """Name of class with main() method to use as entry point.""",
mandatory = True,
),
}.items()),
executable = True,
outputs = _common_outputs,
toolchains = [_TOOLCHAIN_TYPE],
implementation = _kt_jvm_binary_impl,
)
kt_jvm_test = rule(
doc = """Setup a simple kotlin_test.
**Notes:**
* The kotlin test library is not added implicitly, it is available with the label
`@com_github_jetbrains_kotlin//:kotlin-test`.
""",
attrs = _runnable_common_attr + {
"_bazel_test_runner": attr.label(
default = Label("@bazel_tools//tools/jdk:TestRunner_deploy.jar"),
allow_files = True,
),
"friends": attr.label_list(
doc = """A single Kotlin dep which allows the test code access to internal members. Currently uses the output
jar of the module -- i.e., exported deps won't be included.""",
default = [],
providers = [JavaInfo, _KtJvmInfo],
),
"test_class": attr.string(
doc = "The Java class to be loaded by the test runner.",
default = "",
),
"main_class": attr.string(default = "com.google.testing.junit.runner.BazelTestRunner"),
},
executable = True,
outputs = _common_outputs,
test = True,
toolchains = [_TOOLCHAIN_TYPE],
implementation = _kt_jvm_junit_test_impl,
)
kt_jvm_import = rule(
doc = """Import Kotlin jars.
## examples
```bzl
# Old style usage -- reference file groups, do not used this.
kt_jvm_import(
name = "kodein",
jars = [
"@com_github_salomonbrys_kodein_kodein//jar:file",
"@com_github_salomonbrys_kodein_kodein_core//jar:file"
]
)
# This style will pull in the transitive runtime dependencies of the targets as well.
kt_jvm_import(
name = "kodein",
jars = [
"@com_github_salomonbrys_kodein_kodein//jar",
"@com_github_salomonbrys_kodein_kodein_core//jar"
]
)
# Import a single kotlin jar.
kt_jvm_import(
name = "kotlin-runtime",
jars = ["lib/kotlin-runtime.jar"],
srcjar = "lib/kotlin-runtime-sources.jar"
)
```
""",
attrs = {
"jars": attr.label_list(
doc = """The jars listed here are equavalent to an export attribute. The label should be either to a single
class jar, or multiple filegroup labels. When the labels is a file_provider it should follow the conventions
used in repositories generated by the maven_jar rule --i.e., the rule expects a file_provider with a single
class jar and a single source jar. a source jar is recognized by the suffix `-sources.jar`.""",
allow_files = True,
mandatory = True,
cfg = "target",
),
"srcjar": attr.label(
doc = """The sources for the class jar. This should generally be provided especially when importing a single
jar.""",
allow_single_file = True,
cfg = "target",
),
"runtime_deps": attr.label_list(
doc = """Additional runtime deps.""",
default = [],
mandatory = False,
providers = [JavaInfo],
),
"neverlink": attr.bool(
doc = """If true only use this library for compilation and not at runtime.""",
default = False,
),
},
implementation = _kt_jvm_import_impl,
provides = [JavaInfo, _KtJvmInfo],
)