Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit f7ad0cf

Browse files
authoredJun 17, 2025··
Support Starlark rules_android (#1333)
* Support Starlark rules_android * Revert * Formatting * Add missing _lcov_merger attr * More clean up * More clean up and fixes * More cleanup * More cleanup * More cleanup * More cleanup and fixes * More * Fixes * More fixes * More fixes * Fixes
1 parent cb8b7be commit f7ad0cf

File tree

16 files changed

+592
-175
lines changed

16 files changed

+592
-175
lines changed
 

‎examples/android/MODULE.bazel

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ bazel_dep(name = "rules_java", version = "8.9.0")
77
bazel_dep(name = "rules_kotlin", version = "1.9.5")
88
bazel_dep(name = "rules_jvm_external", version = "6.6")
99

10+
android_sdk_repository_extension = use_extension("@rules_android//rules/android_sdk_repository:rule.bzl", "android_sdk_repository_extension")
11+
use_repo(android_sdk_repository_extension, "androidsdk")
12+
13+
register_toolchains("@androidsdk//:sdk-toolchain", "@androidsdk//:all")
14+
1015
maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")
1116
maven.install(
1217
name = "maven_rules_kotlin_example",

‎examples/android/libKtAndroid/src/test/java/examples/android/lib/BUILD.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ load("@rules_kotlin//kotlin:android.bzl", "kt_android_local_test")
33
kt_android_local_test(
44
name = "SomeTest",
55
srcs = ["SomeTest.kt"],
6-
associates = ["//libKtAndroid:my_kt_kt"],
6+
associates = ["//libKtAndroid:my_kt"],
77
custom_package = "examples.android.lib",
88
jvm_flags = [
99
"-Djava.security.manager=allow",

‎kotlin/android.bzl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
load(
2-
"//kotlin/internal/jvm:android.bzl",
2+
"//kotlin/internal/jvm:kt_android_library.bzl",
33
_kt_android_library = "kt_android_library",
4+
)
5+
load(
6+
"//kotlin/internal/jvm:kt_android_local_test.bzl",
47
_kt_android_local_test = "kt_android_local_test",
58
)
69

‎kotlin/internal/jvm/android.bzl

Lines changed: 4 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -11,123 +11,8 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14-
load(
15-
"@rules_android//android:rules.bzl",
16-
_android_library = "android_library",
17-
_android_local_test = "android_local_test",
18-
)
19-
load(
20-
"//kotlin/internal/jvm:jvm.bzl",
21-
_kt_jvm_library = "kt_jvm_library",
22-
)
14+
load(":kt_android_library.bzl", _kt_android_library = "kt_android_library")
15+
load(":kt_android_local_test_impl.bzl", _kt_android_local_test = "kt_android_local_test")
2316

24-
_ANDROID_SDK_JAR = "%s" % Label("//third_party:android_sdk")
25-
26-
def _kt_android_artifact(
27-
name,
28-
srcs = [],
29-
deps = [],
30-
resources = [],
31-
plugins = [],
32-
associates = [],
33-
module_name = "",
34-
kotlinc_opts = None,
35-
javac_opts = None,
36-
enable_data_binding = False,
37-
tags = [],
38-
exec_properties = None,
39-
**kwargs):
40-
"""Delegates Android related build attributes to the native rules but uses the Kotlin builder to compile Java and
41-
Kotlin srcs. Returns a sequence of labels that a wrapping macro should export.
42-
"""
43-
base_name = name + "_base"
44-
kt_name = name + "_kt"
45-
46-
# TODO(bazelbuild/rules_kotlin/issues/273): This should be retrieved from a provider.
47-
base_deps = [_ANDROID_SDK_JAR] + deps
48-
49-
_android_library(
50-
name = base_name,
51-
visibility = ["//visibility:private"],
52-
exports = base_deps,
53-
deps = deps if enable_data_binding else [],
54-
enable_data_binding = enable_data_binding,
55-
tags = tags,
56-
exec_properties = exec_properties,
57-
**kwargs
58-
)
59-
_kt_jvm_library(
60-
name = kt_name,
61-
srcs = srcs,
62-
deps = [base_name] + base_deps,
63-
resources = resources,
64-
plugins = plugins,
65-
associates = associates,
66-
module_name = module_name,
67-
testonly = kwargs.get("testonly", default = False),
68-
visibility = ["//visibility:public"],
69-
kotlinc_opts = kotlinc_opts,
70-
javac_opts = javac_opts,
71-
tags = tags,
72-
exec_properties = exec_properties,
73-
)
74-
return [base_name, kt_name]
75-
76-
def kt_android_library(name, exports = [], visibility = None, exec_properties = None, **kwargs):
77-
"""Creates an Android sandwich library.
78-
79-
`srcs`, `deps`, `plugins` are routed to `kt_jvm_library` the other android
80-
related attributes are handled by the native `android_library` rule.
81-
"""
82-
83-
_android_library(
84-
name = name,
85-
exports = exports + _kt_android_artifact(name, exec_properties = exec_properties, **kwargs),
86-
visibility = visibility,
87-
tags = kwargs.get("tags", default = None),
88-
testonly = kwargs.get("testonly", default = 0),
89-
exec_properties = exec_properties,
90-
)
91-
92-
def kt_android_local_test(
93-
name,
94-
jvm_flags = None,
95-
manifest = None,
96-
manifest_values = None,
97-
test_class = None,
98-
size = None,
99-
data = None,
100-
timeout = None,
101-
flaky = False,
102-
shard_count = None,
103-
visibility = None,
104-
testonly = True,
105-
exec_properties = None,
106-
nocompress_extensions = None,
107-
**kwargs):
108-
"""Creates a testable Android sandwich library.
109-
110-
`srcs`, `deps`, `plugins`, `associates` are routed to `kt_jvm_library` the other android
111-
related attributes are handled by the native `android_library` rule while the test attributes
112-
are picked out and handled by the `android_local_test` rule.
113-
"""
114-
115-
_android_local_test(
116-
name = name,
117-
deps = kwargs.get("deps", []) + _kt_android_artifact(name = name, testonly = testonly, exec_properties = exec_properties, **kwargs),
118-
jvm_flags = jvm_flags,
119-
test_class = test_class,
120-
visibility = visibility,
121-
size = size,
122-
data = data,
123-
timeout = timeout,
124-
flaky = flaky,
125-
shard_count = shard_count,
126-
custom_package = kwargs.get("custom_package", default = None),
127-
manifest = manifest,
128-
manifest_values = manifest_values,
129-
tags = kwargs.get("tags", default = None),
130-
testonly = testonly,
131-
exec_properties = exec_properties,
132-
nocompress_extensions = nocompress_extensions,
133-
)
17+
kt_android_library = _kt_android_library
18+
kt_android_local_test = _kt_android_local_test

‎kotlin/internal/jvm/compile.bzl

Lines changed: 69 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ def _fold_jars_action(ctx, rule_kind, toolchains, output_jar, input_jars, action
272272
toolchain = _TOOLCHAIN_TYPE,
273273
)
274274

275-
def _resourcejar_args_action(ctx):
275+
def _resourcejar_args_action(ctx, extra_resources = {}):
276276
res_cmd = []
277277
for f in ctx.files.resources:
278278
target_path = _adjust_resources_path(f.short_path, ctx.attr.resource_strip_prefix)
@@ -283,20 +283,31 @@ def _resourcejar_args_action(ctx):
283283
f_path = f.path,
284284
)
285285
res_cmd.extend([line])
286+
287+
for key, value in extra_resources.items():
288+
target_path = _adjust_resources_path(value.short_path, ctx.label.package)
289+
if target_path[0] == "/":
290+
target_path = target_path[1:]
291+
line = "{target_path}={res_path}\n".format(
292+
res_path = value.path,
293+
target_path = key,
294+
)
295+
res_cmd.extend([line])
296+
286297
zipper_args_file = ctx.actions.declare_file("%s_resources_zipper_args" % ctx.label.name)
287298
ctx.actions.write(zipper_args_file, "".join(res_cmd))
288299
return zipper_args_file
289300

290-
def _build_resourcejar_action(ctx):
301+
def _build_resourcejar_action(ctx, extra_resources = {}):
291302
"""sets up an action to build a resource jar for the target being compiled.
292303
Returns:
293304
The file resource jar file.
294305
"""
295306
resources_jar_output = ctx.actions.declare_file(ctx.label.name + "-resources.jar")
296-
zipper_args = _resourcejar_args_action(ctx)
307+
zipper_args = _resourcejar_args_action(ctx, extra_resources)
297308
ctx.actions.run_shell(
298309
mnemonic = "KotlinZipResourceJar",
299-
inputs = ctx.files.resources + [zipper_args],
310+
inputs = ctx.files.resources + extra_resources.values() + [zipper_args],
300311
tools = [ctx.executable._zipper],
301312
outputs = [resources_jar_output],
302313
command = "{zipper} c {resources_jar_output} @{path}".format(
@@ -570,27 +581,57 @@ def _run_kt_builder_action(
570581

571582
# MAIN ACTIONS #########################################################################################################
572583

573-
def kt_jvm_produce_jar_actions(ctx, rule_kind):
584+
def _kt_jvm_produce_jar_actions(ctx, rule_kind, extra_resources = {}):
585+
"""Setup The actions to compile a jar and if any resources or resource_jars were provided to merge these in with the
586+
compilation output.
587+
588+
Returns:
589+
see `kt_jvm_compile_action`.
590+
"""
591+
deps = getattr(ctx.attr, "deps", [])
592+
associates = getattr(ctx.attr, "associates", [])
593+
_fail_if_invalid_associate_deps(associates, deps)
594+
compile_deps = _jvm_deps_utils.jvm_deps(
595+
ctx,
596+
toolchains = _compiler_toolchains(ctx),
597+
associate_deps = associates,
598+
deps = deps,
599+
exports = getattr(ctx.attr, "exports", []),
600+
runtime_deps = getattr(ctx.attr, "runtime_deps", []),
601+
)
602+
603+
outputs = struct(
604+
jar = ctx.outputs.jar,
605+
srcjar = ctx.outputs.srcjar,
606+
)
607+
608+
# Setup the compile action.
609+
return _kt_jvm_produce_output_jar_actions(
610+
ctx,
611+
rule_kind = rule_kind,
612+
compile_deps = compile_deps,
613+
outputs = outputs,
614+
extra_resources = extra_resources,
615+
)
616+
617+
def _kt_jvm_produce_output_jar_actions(
618+
ctx,
619+
rule_kind,
620+
compile_deps,
621+
outputs,
622+
extra_resources = {}):
574623
"""This macro sets up a compile action for a Kotlin jar.
575624
576625
Args:
577626
ctx: Invoking rule ctx, used for attr, actions, and label.
578627
rule_kind: The rule kind --e.g., `kt_jvm_library`.
628+
compile_deps: The rule kind --e.g., `kt_jvm_library`.
579629
Returns:
580630
A struct containing the providers JavaInfo (`java`) and `kt` (KtJvmInfo). This struct is not intended to be
581631
used as a legacy provider -- rather the caller should transform the result.
582632
"""
583633
toolchains = _compiler_toolchains(ctx)
584634
srcs = _partitioned_srcs(ctx.files.srcs)
585-
_fail_if_invalid_associate_deps(ctx.attr.associates, ctx.attr.deps)
586-
compile_deps = _jvm_deps_utils.jvm_deps(
587-
ctx,
588-
toolchains = toolchains,
589-
associate_deps = ctx.attr.associates,
590-
deps = ctx.attr.deps,
591-
exports = getattr(ctx.attr, "exports", []),
592-
runtime_deps = getattr(ctx.attr, "runtime_deps", []),
593-
)
594635

595636
annotation_processors = _plugin_mappers.targets_to_annotation_processors(ctx.attr.plugins + ctx.attr.deps)
596637
ksp_annotation_processors = _plugin_mappers.targets_to_ksp_annotation_processors(ctx.attr.plugins + ctx.attr.deps)
@@ -627,12 +668,12 @@ def kt_jvm_produce_jar_actions(ctx, rule_kind):
627668
annotation_processing = outputs_struct.annotation_processing
628669

629670
# If this rule has any resources declared setup a zipper action to turn them into a jar.
630-
if len(ctx.files.resources) > 0:
631-
output_jars.append(_build_resourcejar_action(ctx))
671+
if len(ctx.files.resources) + len(extra_resources) > 0:
672+
output_jars.append(_build_resourcejar_action(ctx, extra_resources))
632673
output_jars.extend(ctx.files.resource_jars)
633674

634675
# Merge outputs into final runtime jar.
635-
output_jar = ctx.actions.declare_file(ctx.label.name + ".jar")
676+
output_jar = outputs.jar
636677
_fold_jars_action(
637678
ctx,
638679
rule_kind = rule_kind,
@@ -644,7 +685,7 @@ def kt_jvm_produce_jar_actions(ctx, rule_kind):
644685

645686
source_jar = java_common.pack_sources(
646687
ctx.actions,
647-
output_source_jar = ctx.outputs.srcjar,
688+
output_source_jar = outputs.srcjar,
648689
sources = srcs.kt + srcs.java,
649690
source_jars = srcs.src_jars + generated_src_jars,
650691
java_toolchain = toolchains.java,
@@ -928,14 +969,15 @@ def _create_annotation_processing(annotation_processors, ap_class_jar, ap_source
928969
)
929970
return None
930971

931-
def export_only_providers(ctx, actions, attr, outputs):
972+
def _export_only_providers(ctx, actions, attr, outputs):
932973
"""_export_only_providers creates a series of forwarding providers without compilation overhead.
933974
934975
Args:
935976
ctx: kt_compiler_ctx
936977
actions: invoking rule actions,
937978
attr: kt_compiler_attributes,
938979
outputs: kt_compiler_outputs
980+
939981
Returns:
940982
kt_compiler_result
941983
"""
@@ -987,3 +1029,11 @@ def export_only_providers(ctx, actions, attr, outputs):
9871029
extensions = ["kt", "java"],
9881030
),
9891031
)
1032+
1033+
compile = struct(
1034+
compiler_toolchains = _compiler_toolchains,
1035+
verify_associates_not_duplicated_in_deps = _fail_if_invalid_associate_deps,
1036+
export_only_providers = _export_only_providers,
1037+
kt_jvm_produce_output_jar_actions = _kt_jvm_produce_output_jar_actions,
1038+
kt_jvm_produce_jar_actions = _kt_jvm_produce_jar_actions,
1039+
)

‎kotlin/internal/jvm/impl.bzl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ load(
2424
)
2525
load(
2626
"//kotlin/internal/jvm:compile.bzl",
27-
"export_only_providers",
28-
_kt_jvm_produce_jar_actions = "kt_jvm_produce_jar_actions",
27+
_compile = "compile",
2928
)
3029
load(
3130
"//kotlin/internal/utils:utils.bzl",
@@ -41,6 +40,7 @@ def _make_providers(ctx, providers, runfiles_targets, transitive_files = depset(
4140
files = [ctx.outputs.jar]
4241
if providers.java.outputs.jdeps:
4342
files.append(providers.java.outputs.jdeps)
43+
4444
return [
4545
providers.java,
4646
providers.kt,
@@ -224,7 +224,7 @@ def kt_jvm_library_impl(ctx):
224224
)
225225
return _make_providers(
226226
ctx,
227-
_kt_jvm_produce_jar_actions(ctx, "kt_jvm_library") if ctx.attr.srcs or ctx.attr.resources else export_only_providers(
227+
_compile.kt_jvm_produce_jar_actions(ctx, "kt_jvm_library") if ctx.attr.srcs or ctx.attr.resources else _compile.export_only_providers(
228228
ctx = ctx,
229229
actions = ctx.actions,
230230
outputs = ctx.outputs,
@@ -234,7 +234,7 @@ def kt_jvm_library_impl(ctx):
234234
)
235235

236236
def kt_jvm_binary_impl(ctx):
237-
providers = _kt_jvm_produce_jar_actions(ctx, "kt_jvm_binary")
237+
providers = _compile.kt_jvm_produce_jar_actions(ctx, "kt_jvm_binary")
238238
jvm_flags = []
239239
if hasattr(ctx.fragments.java, "default_jvm_opts"):
240240
jvm_flags = ctx.fragments.java.default_jvm_opts
@@ -269,7 +269,7 @@ _SPLIT_STRINGS = [
269269
]
270270

271271
def kt_jvm_junit_test_impl(ctx):
272-
providers = _kt_jvm_produce_jar_actions(ctx, "kt_jvm_test")
272+
providers = _compile.kt_jvm_produce_jar_actions(ctx, "kt_jvm_test")
273273
runtime_jars = depset(ctx.files._bazel_test_runner, transitive = [providers.java.transitive_runtime_jars])
274274

275275
coverage_runfiles = []

‎kotlin/internal/jvm/jvm.bzl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ _common_attr = utils.add_dicts(
249249
providers = [_JavacOptions],
250250
mandatory = False,
251251
),
252+
"_use_auto_exec_groups": attr.bool(default = False),
252253
},
253254
)
254255

@@ -659,3 +660,8 @@ kt_plugin_cfg = rule(
659660
),
660661
},
661662
)
663+
664+
attrs = struct(
665+
lib_common_attr = _lib_common_attr,
666+
runnable_common_attr = _runnable_common_attr,
667+
)

‎kotlin/internal/jvm/jvm_deps.bzl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ load("//kotlin/internal/utils:sets.bzl", _sets = "sets")
2121
def _java_info(target):
2222
return target[JavaInfo] if JavaInfo in target else None
2323

24-
def _jvm_deps(ctx, toolchains, associate_deps, deps, exports = [], runtime_deps = []):
24+
def _jvm_deps(ctx, toolchains, associate_deps, deps = [], deps_java_infos = [], exports = [], runtime_deps = []):
2525
"""Encapsulates jvm dependency metadata."""
26-
dep_infos = [_java_info(d) for d in deps] + [toolchains.kt.jvm_stdlibs]
26+
dep_infos = deps_java_infos + [_java_info(d) for d in deps] + [toolchains.kt.jvm_stdlibs]
2727

2828
associates = _associate_utils.get_associates(ctx, toolchains = toolchains, associates = associate_deps)
2929

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Copyright 2018 The Bazel Authors. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
load(
15+
"@rules_android//rules/android_library:attrs.bzl",
16+
_BASE_ATTRS = "ATTRS",
17+
)
18+
load(
19+
"@rules_android//rules/android_library:rule.bzl",
20+
_make_rule = "make_rule",
21+
)
22+
load(
23+
"//kotlin/internal:defs.bzl",
24+
_KtJvmInfo = "KtJvmInfo",
25+
_TOOLCHAIN_TYPE = "TOOLCHAIN_TYPE",
26+
)
27+
load(
28+
"//kotlin/internal/jvm:jvm.bzl",
29+
_attrs = "attrs",
30+
)
31+
load(
32+
"//kotlin/internal/jvm:kt_android_library_impl.bzl",
33+
_kt_android_library_impl = "kt_android_library_impl",
34+
)
35+
load(
36+
"//kotlin/internal/utils:utils.bzl",
37+
_utils = "utils",
38+
)
39+
40+
_ATTRS = _utils.add_dicts(_BASE_ATTRS, _attrs.lib_common_attr, {
41+
# Pass or override any attributes needed here
42+
})
43+
44+
kt_android_library = _make_rule(
45+
implementation = _kt_android_library_impl,
46+
attrs = _ATTRS,
47+
additional_toolchains = [
48+
_TOOLCHAIN_TYPE,
49+
],
50+
additional_providers = [
51+
_KtJvmInfo,
52+
],
53+
)
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
# Copyright 2018 The Bazel Authors. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
load(
15+
"@rules_android//providers:providers.bzl",
16+
_AndroidLibraryResourceClassJarProvider = "AndroidLibraryResourceClassJarProvider",
17+
)
18+
load(
19+
"@rules_android//rules:java.bzl",
20+
_java = "java",
21+
)
22+
load(
23+
"@rules_android//rules:processing_pipeline.bzl",
24+
_ProviderInfo = "ProviderInfo",
25+
_processing_pipeline = "processing_pipeline",
26+
)
27+
load(
28+
"@rules_android//rules:utils.bzl",
29+
_get_android_sdk = "get_android_sdk",
30+
_utils = "utils",
31+
)
32+
load(
33+
"@rules_android//rules/android_library:impl.bzl",
34+
_BASE_PROCESSORS = "PROCESSORS",
35+
_finalize = "finalize",
36+
)
37+
load(
38+
"@rules_java//java:defs.bzl",
39+
"JavaInfo",
40+
)
41+
load(
42+
"//kotlin/internal/jvm:compile.bzl",
43+
_compile = "compile",
44+
)
45+
load(
46+
"//kotlin/internal/jvm:jvm_deps.bzl",
47+
_jvm_deps_utils = "jvm_deps_utils",
48+
)
49+
50+
def _process_jvm(ctx, resources_ctx, **_unused_sub_ctxs):
51+
"""Custom JvmProcessor that handles Kotlin compilation
52+
"""
53+
r_java = resources_ctx.r_java
54+
outputs = struct(jar = ctx.outputs.lib_jar, srcjar = ctx.outputs.lib_src_jar, deploy_jar = None)
55+
providers = _kt_android_produce_jar_actions(ctx, "kt_android_library", outputs, r_java)
56+
57+
return _ProviderInfo(
58+
name = "jvm_ctx",
59+
value = struct(
60+
java_info = providers.java,
61+
kt_info = providers.kt,
62+
providers = [
63+
providers.kt,
64+
providers.java,
65+
],
66+
),
67+
)
68+
69+
PROCESSORS = _processing_pipeline.replace(
70+
_BASE_PROCESSORS,
71+
JvmProcessor = _process_jvm,
72+
)
73+
74+
_PROCESSING_PIPELINE = _processing_pipeline.make_processing_pipeline(
75+
processors = PROCESSORS,
76+
finalize = _finalize,
77+
)
78+
79+
def kt_android_library_impl(ctx):
80+
"""The rule implementation.
81+
82+
Args:
83+
ctx: The context.
84+
85+
Returns:
86+
A list of providers.
87+
"""
88+
java_package = _java.resolve_package_from_label(ctx.label, ctx.attr.custom_package)
89+
return _processing_pipeline.run(ctx, java_package, _PROCESSING_PIPELINE)
90+
91+
def _get_android_resource_class_jars(targets):
92+
android_compile_dependencies = []
93+
94+
# Collect R.class jar files from direct dependencies
95+
for d in targets:
96+
if _AndroidLibraryResourceClassJarProvider in d:
97+
jars = d[_AndroidLibraryResourceClassJarProvider].jars
98+
if jars:
99+
android_compile_dependencies.extend([
100+
JavaInfo(output_jar = jar, compile_jar = jar, neverlink = True)
101+
for jar in _utils.list_or_depset_to_list(jars)
102+
])
103+
104+
return android_compile_dependencies
105+
106+
def _kt_android_produce_jar_actions(
107+
ctx,
108+
rule_kind,
109+
outputs,
110+
rClass = None,
111+
extra_resources = {}):
112+
"""Setup The actions to compile a jar and if any resources or resource_jars were provided to merge these in with the
113+
compilation output.
114+
"""
115+
deps = getattr(ctx.attr, "deps", [])
116+
associates = getattr(ctx.attr, "associates", [])
117+
exports = getattr(ctx.attr, "exports", [])
118+
runtime_deps = getattr(ctx.attr, "runtime_deps", [])
119+
_compile.verify_associates_not_duplicated_in_deps(deps = deps, associate_deps = associates)
120+
121+
# Collect the android compile dependencies
122+
android_java_infos = [
123+
JavaInfo(
124+
output_jar = _get_android_sdk(ctx).android_jar,
125+
compile_jar = _get_android_sdk(ctx).android_jar,
126+
neverlink = True,
127+
),
128+
]
129+
if rClass:
130+
android_java_infos.append(rClass)
131+
android_java_infos.extend(_get_android_resource_class_jars(deps + associates + runtime_deps))
132+
133+
compile_deps = _jvm_deps_utils.jvm_deps(
134+
ctx,
135+
toolchains = _compile.compiler_toolchains(ctx),
136+
associate_deps = associates,
137+
deps = deps,
138+
deps_java_infos = android_java_infos,
139+
exports = exports,
140+
runtime_deps = runtime_deps,
141+
)
142+
143+
# Setup the compile action.
144+
return _compile.kt_jvm_produce_output_jar_actions(
145+
ctx,
146+
rule_kind = rule_kind,
147+
compile_deps = compile_deps,
148+
outputs = outputs,
149+
extra_resources = extra_resources,
150+
) if ctx.attr.srcs else _compile.compile.export_only_providers(
151+
ctx = ctx,
152+
actions = ctx.actions,
153+
outputs = outputs,
154+
attr = ctx.attr,
155+
)
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Copyright 2018 The Bazel Authors. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
load(
15+
"@rules_android//rules/android_local_test:attrs.bzl",
16+
_BASE_ATTRS = "ATTRS",
17+
)
18+
load(
19+
"@rules_android//rules/android_local_test:rule.bzl",
20+
_make_rule = "make_rule",
21+
)
22+
load(
23+
"//kotlin/internal:defs.bzl",
24+
_JAVA_RUNTIME_TOOLCHAIN_TYPE = "JAVA_RUNTIME_TOOLCHAIN_TYPE",
25+
_TOOLCHAIN_TYPE = "TOOLCHAIN_TYPE",
26+
)
27+
load(
28+
"//kotlin/internal/jvm:jvm.bzl",
29+
_attrs = "attrs",
30+
)
31+
load(
32+
"//kotlin/internal/jvm:kt_android_local_test_impl.bzl",
33+
_kt_android_local_test_impl = "kt_android_local_test_impl",
34+
)
35+
load(
36+
"//kotlin/internal/utils:utils.bzl",
37+
_utils = "utils",
38+
)
39+
40+
_ATTRS = _utils.add_dicts(_BASE_ATTRS, _attrs.runnable_common_attr, {
41+
"main_class": attr.string(
42+
default = "com.google.testing.junit.runner.BazelTestRunner",
43+
),
44+
"jacocorunner": attr.label(
45+
default = Label("@bazel_tools//tools/jdk:JacocoCoverage"),
46+
),
47+
"_lcov_merger": attr.label(
48+
cfg = "exec",
49+
default = configuration_field(
50+
fragment = "coverage",
51+
name = "output_generator",
52+
),
53+
),
54+
})
55+
56+
kt_android_local_test = _make_rule(
57+
implementation = _kt_android_local_test_impl,
58+
attrs = _ATTRS,
59+
additional_toolchains = [
60+
_TOOLCHAIN_TYPE,
61+
_JAVA_RUNTIME_TOOLCHAIN_TYPE,
62+
],
63+
)
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
# Copyright 2018 The Bazel Authors. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
load(
15+
"@bazel_skylib//rules:common_settings.bzl",
16+
_BuildSettingInfo = "BuildSettingInfo",
17+
)
18+
load(
19+
"@rules_android//providers:providers.bzl",
20+
_AndroidFilteredJdepsInfo = "AndroidFilteredJdepsInfo",
21+
)
22+
load(
23+
"@rules_android//rules:attrs.bzl",
24+
_attrs = "attrs",
25+
)
26+
load(
27+
"@rules_android//rules:java.bzl",
28+
_java = "java",
29+
)
30+
load(
31+
"@rules_android//rules:processing_pipeline.bzl",
32+
_ProviderInfo = "ProviderInfo",
33+
_processing_pipeline = "processing_pipeline",
34+
)
35+
load(
36+
"@rules_android//rules:resources.bzl",
37+
_resources = "resources",
38+
)
39+
load(
40+
"@rules_android//rules:utils.bzl",
41+
_compilation_mode = "compilation_mode",
42+
_get_android_sdk = "get_android_sdk",
43+
_get_android_toolchain = "get_android_toolchain",
44+
_utils = "utils",
45+
)
46+
load(
47+
"@rules_android//rules/android_local_test:impl.bzl",
48+
_BASE_PROCESSORS = "PROCESSORS",
49+
_filter_jdeps = "filter_jdeps",
50+
_finalize = "finalize",
51+
)
52+
load(
53+
"@rules_java//java:defs.bzl",
54+
"JavaInfo",
55+
"java_common",
56+
)
57+
load(
58+
"//kotlin/internal:defs.bzl",
59+
_JAVA_RUNTIME_TOOLCHAIN_TYPE = "JAVA_RUNTIME_TOOLCHAIN_TYPE",
60+
_TOOLCHAIN_TYPE = "TOOLCHAIN_TYPE",
61+
)
62+
load(
63+
"//kotlin/internal/jvm:compile.bzl",
64+
_compile = "compile",
65+
)
66+
load(
67+
"//kotlin/internal/jvm:jvm_deps.bzl",
68+
_jvm_deps_utils = "jvm_deps_utils",
69+
)
70+
71+
_JACOCOCO_CLASS = "com.google.testing.coverage.JacocoCoverageRunner"
72+
73+
def _process_resources(ctx, java_package, manifest_ctx, **_unused_sub_ctxs):
74+
# Note: This needs to be kept in sync with.
75+
# The main difference between this and the upstream macro is that both ctx.attr.associates and ctx.attr.deps needs to
76+
# be passed to `_resources.package(` in order for ALL of the resource references to get merged into a single R
77+
# class file.
78+
# https://github.com/bazelbuild/rules_android/blob/e98ee9eb79c9398a9866d073a43ecd5e97aaf896/rules/android_local_test/impl.bzl#L94-L122
79+
resources_ctx = _resources.package(
80+
ctx,
81+
# This entire section is being overridden so that we can pass the associates into the deps section.
82+
# Without this tests won't be able to reference resources of the associate targets
83+
deps = ctx.attr.associates + ctx.attr.deps,
84+
manifest = manifest_ctx.processed_manifest,
85+
manifest_values = manifest_ctx.processed_manifest_values,
86+
manifest_merge_order = ctx.attr._manifest_merge_order[_BuildSettingInfo].value,
87+
resource_files = ctx.files.resource_files,
88+
assets = ctx.files.assets,
89+
assets_dir = ctx.attr.assets_dir,
90+
resource_configs = ctx.attr.resource_configuration_filters,
91+
densities = ctx.attr.densities,
92+
nocompress_extensions = ctx.attr.nocompress_extensions,
93+
compilation_mode = _compilation_mode.get(ctx),
94+
java_package = java_package,
95+
shrink_resources = _attrs.tristate.no,
96+
build_java_with_final_resources = True,
97+
aapt = _get_android_toolchain(ctx).aapt2.files_to_run,
98+
android_jar = _get_android_sdk(ctx).android_jar,
99+
busybox = _get_android_toolchain(ctx).android_resources_busybox.files_to_run,
100+
host_javabase = ctx.attr._host_javabase,
101+
# TODO(b/140582167): Throwing on resource conflict need to be rolled
102+
# out to android_local_test.
103+
should_throw_on_conflict = False,
104+
)
105+
106+
return _ProviderInfo(
107+
name = "resources_ctx",
108+
value = resources_ctx,
109+
)
110+
111+
def _process_jvm(ctx, resources_ctx, **_unused_sub_ctxs):
112+
"""Custom JvmProcessor that handles Kotlin compilation
113+
"""
114+
_compile.verify_associates_not_duplicated_in_deps(deps = getattr(ctx.attr, "deps", []), associate_deps = getattr(ctx.attr, "associates", []))
115+
116+
outputs = struct(jar = ctx.outputs.jar, srcjar = ctx.actions.declare_file(ctx.label.name + "-src.jar"))
117+
118+
deps = (
119+
[_get_android_toolchain(ctx).testsupport] +
120+
getattr(ctx.attr, "associates", []) +
121+
getattr(ctx.attr, "deps", [])
122+
)
123+
124+
if ctx.configuration.coverage_enabled:
125+
deps.append(ctx.toolchains[_TOOLCHAIN_TYPE].jacocorunner)
126+
java_start_class = _JACOCOCO_CLASS
127+
coverage_start_class = ctx.attr.main_class
128+
else:
129+
java_start_class = ctx.attr.main_class
130+
coverage_start_class = None
131+
132+
# Setup the compile action.
133+
providers = _compile.kt_jvm_produce_output_jar_actions(
134+
ctx,
135+
rule_kind = "kt_android_local_test",
136+
compile_deps = _jvm_deps_utils.jvm_deps(
137+
ctx,
138+
toolchains = _compile.compiler_toolchains(ctx),
139+
deps = deps,
140+
deps_java_infos = (
141+
([resources_ctx.r_java] if resources_ctx.r_java else []) +
142+
[
143+
JavaInfo(
144+
output_jar = _get_android_sdk(ctx).android_jar,
145+
compile_jar = _get_android_sdk(ctx).android_jar,
146+
# The android_jar must not be compiled into the test, it
147+
# will bloat the Jar with no benefit.
148+
neverlink = True,
149+
),
150+
]
151+
),
152+
associate_deps = getattr(ctx.attr, "associates", []),
153+
runtime_deps = getattr(ctx.attr, "runtime_deps", []),
154+
),
155+
outputs = outputs,
156+
)
157+
158+
java_info = providers.java
159+
if getattr(java_common, "add_constraints", None):
160+
java_info = java_common.add_constraints(java_info, constraints = ["android"])
161+
162+
# Create test run action
163+
providers = [providers.kt, java_info]
164+
runfiles = []
165+
166+
# Create a filtered jdeps with no resources jar. See b/129011477 for more context.
167+
if java_info.outputs.jdeps != None:
168+
filtered_jdeps = ctx.actions.declare_file(ctx.label.name + ".filtered.jdeps")
169+
_filter_jdeps(ctx, java_info.outputs.jdeps, filtered_jdeps, _utils.only(resources_ctx.r_java.compile_jars.to_list()))
170+
providers.append(_AndroidFilteredJdepsInfo(jdeps = filtered_jdeps))
171+
runfiles.append(filtered_jdeps)
172+
173+
# Append the security manager override
174+
jvm_flags = []
175+
java_runtime = ctx.toolchains[_JAVA_RUNTIME_TOOLCHAIN_TYPE].java_runtime
176+
if java_runtime.version >= 17:
177+
jvm_flags.append("-Djava.security.manager=allow")
178+
179+
return _ProviderInfo(
180+
name = "jvm_ctx",
181+
value = struct(
182+
java_info = java_info,
183+
providers = providers,
184+
deps = deps,
185+
java_start_class = java_start_class,
186+
coverage_start_class = coverage_start_class,
187+
android_properties_file = ctx.file.robolectric_properties_file.short_path,
188+
additional_jvm_flags = jvm_flags,
189+
),
190+
runfiles = ctx.runfiles(files = runfiles),
191+
)
192+
193+
PROCESSORS = _processing_pipeline.replace(
194+
_BASE_PROCESSORS,
195+
ResourceProcessor = _process_resources,
196+
JvmProcessor = _process_jvm,
197+
)
198+
199+
_PROCESSING_PIPELINE = _processing_pipeline.make_processing_pipeline(
200+
processors = PROCESSORS,
201+
finalize = _finalize,
202+
)
203+
204+
def kt_android_local_test_impl(ctx):
205+
"""The rule implementation.
206+
207+
Args:
208+
ctx: The context.
209+
210+
Returns:
211+
A list of providers.
212+
"""
213+
java_package = _java.resolve_package_from_label(ctx.label, ctx.attr.custom_package)
214+
return _processing_pipeline.run(ctx, java_package, _PROCESSING_PIPELINE)

‎src/main/kotlin/io/bazel/kotlin/builder/tasks/KotlinBuilder.kt

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,9 @@ class KotlinBuilder
101101
try {
102102
@Suppress("WHEN_ENUM_CAN_BE_NULL_IN_JAVA")
103103
when (compileContext.info.platform) {
104-
Platform.JVM -> executeJvmTask(compileContext, taskContext.directory, argMap)
104+
Platform.JVM,
105+
Platform.ANDROID,
106+
-> executeJvmTask(compileContext, taskContext.directory, argMap)
105107
Platform.UNRECOGNIZED -> throw IllegalStateException(
106108
"unrecognized platform: ${compileContext.info}",
107109
)
@@ -140,16 +142,11 @@ class KotlinBuilder
140142
addAllDebug(argMap.mandatory(KotlinBuilderFlags.DEBUG))
141143

142144
label = argMap.mandatorySingle(KotlinBuilderFlags.TARGET_LABEL)
143-
argMap.mandatorySingle(KotlinBuilderFlags.RULE_KIND).split("_").also {
144-
check(it.size == 3 && it[0] == "kt") { "invalid rule kind $it" }
145-
platform =
146-
checkNotNull(Platform.valueOf(it[1].uppercase())) {
147-
"unrecognized platform ${it[1]}"
148-
}
149-
ruleKind =
150-
checkNotNull(RuleKind.valueOf(it[2].uppercase())) {
151-
"unrecognized rule kind ${it[2]}"
152-
}
145+
argMap.mandatorySingle(KotlinBuilderFlags.RULE_KIND).also {
146+
val splitRuleKind = it.split("_")
147+
require(splitRuleKind[0] == "kt") { "Invalid rule kind $it" }
148+
platform = Platform.valueOf(splitRuleKind[1].uppercase())
149+
ruleKind = RuleKind.valueOf(splitRuleKind.last().uppercase())
153150
}
154151
moduleName =
155152
argMap.mandatorySingle(KotlinBuilderFlags.MODULE_NAME).also {

‎src/main/protobuf/kotlin_model.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ enum RuleKind {
5454

5555
enum Platform {
5656
JVM = 0;
57+
ANDROID = 1;
5758
}
5859

5960
// Common info about a Kotlin compilation task, this message is shared by all compilation tasks.

‎third_party/BUILD

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
2-
load("@rules_java//java:defs.bzl", "java_binary", "java_import", "java_library", "java_plugin")
2+
load("@rules_java//java:defs.bzl", "java_binary", "java_library", "java_plugin")
33
load("//src/main/starlark/release:packager.bzl", "release_archive")
44

55
# Copyright 2018 The Bazel Authors. All rights reserved.
@@ -74,14 +74,6 @@ java_binary(
7474
runtime_deps = ["@kotlin_rules_maven//:org_pantsbuild_jarjar"],
7575
)
7676

77-
# TODO(bazelbuild/rules_kotlin/issues/273): Remove android_sdk import.
78-
java_import(
79-
name = "android_sdk",
80-
jars = ["@rules_android//tools/android:android_jar"],
81-
neverlink = 1,
82-
visibility = ["//visibility:public"],
83-
)
84-
8577
bzl_library(
8678
name = "bzl",
8779
srcs = [

‎third_party/BUILD.release.bazel

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
# limitations under the License.
1414

1515
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
16-
load("@rules_java//java:defs.bzl", "java_binary", "java_import")
16+
load("@rules_java//java:defs.bzl", "java_binary")
1717

1818
exports_files([
1919
"empty.jar",
@@ -28,13 +28,6 @@ java_binary(
2828
runtime_deps = [":jarjar.jar"],
2929
)
3030

31-
java_import(
32-
name = "android_sdk",
33-
jars = ["@rules_android//tools/android:android_jar"],
34-
neverlink = True,
35-
visibility = ["//visibility:public"],
36-
)
37-
3831
bzl_library(
3932
name = "bzl",
4033
srcs = [

0 commit comments

Comments
 (0)
Please sign in to comment.