Vendor dependencies

Let's see how I like this workflow.
This commit is contained in:
John Doty 2022-12-19 08:27:18 -08:00
parent 34d1830413
commit 9c435dc440
7500 changed files with 1665121 additions and 99 deletions

View file

@ -0,0 +1,87 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under both the MIT license found in the
# LICENSE-MIT file in the root directory of this source tree and the Apache
# License, Version 2.0 found in the LICENSE-APACHE file in the root directory
# of this source tree.
load("@prelude//android:configuration.bzl", "is_building_android_binary_attr")
load("@prelude//java:dex_toolchain.bzl", "DexToolchainInfo")
load("@prelude//java:java.bzl", "dex_min_sdk_version", "is_build_only_native_code", "select_dex_toolchain", "select_java_test_toolchain")
load(
"@prelude//java:java_toolchain.bzl",
"JavaPlatformInfo",
"JavaTestToolchainInfo",
"JavaToolchainInfo",
)
load(
"@prelude//kotlin:kotlin_toolchain.bzl",
"KotlinToolchainInfo",
)
load(":kotlin_library.bzl", "kotlin_library_impl")
load(":kotlin_test.bzl", "kotlin_test_impl")
def _select_java_toolchain():
# FIXME: prelude// should be standalone (not refer to fbsource//)
return "fbsource//xplat/buck2/platform/java:java"
def _select_kotlin_toolchain():
# FIXME: prelude// should be standalone (not refer to fbsource//)
return "fbsource//xplat/buck2/platform/kotlin:kotlin"
implemented_rules = {
"kotlin_library": kotlin_library_impl,
"kotlin_test": kotlin_test_impl,
}
extra_attributes = {
"kotlin_library": {
"javac": attrs.option(attrs.one_of(attrs.dep(), attrs.source()), default = None),
"resources_root": attrs.option(attrs.string(), default = None),
"_build_only_native_code": attrs.default_only(attrs.bool(default = is_build_only_native_code())),
"_dex_min_sdk_version": attrs.option(attrs.int(), default = dex_min_sdk_version()),
"_dex_toolchain": attrs.option(attrs.exec_dep(
providers = [
DexToolchainInfo,
],
), default = select_dex_toolchain()),
"_is_building_android_binary": is_building_android_binary_attr(),
"_java_toolchain": attrs.exec_dep(
default = _select_java_toolchain(),
providers = [
JavaPlatformInfo,
JavaToolchainInfo,
],
),
"_kotlin_toolchain": attrs.exec_dep(
default = _select_kotlin_toolchain(),
providers = [
KotlinToolchainInfo,
],
),
},
"kotlin_test": {
"javac": attrs.option(attrs.one_of(attrs.dep(), attrs.source()), default = None),
"resources_root": attrs.option(attrs.string(), default = None),
"_is_building_android_binary": attrs.default_only(attrs.bool(default = False)),
"_java_test_toolchain": attrs.exec_dep(
default = select_java_test_toolchain(),
providers = [
JavaTestToolchainInfo,
],
),
"_java_toolchain": attrs.exec_dep(
default = _select_java_toolchain(),
providers = [
JavaPlatformInfo,
JavaToolchainInfo,
],
),
"_kotlin_toolchain": attrs.exec_dep(
default = _select_kotlin_toolchain(),
providers = [
KotlinToolchainInfo,
],
),
},
}

View file

@ -0,0 +1,383 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under both the MIT license found in the
# LICENSE-MIT file in the root directory of this source tree and the Apache
# License, Version 2.0 found in the LICENSE-APACHE file in the root directory
# of this source tree.
load("@prelude//android:android_providers.bzl", "merge_android_packageable_info")
load(
"@prelude//java:java_library.bzl",
"build_java_library",
"split_on_archives_and_plain_files",
)
load(
"@prelude//java:java_providers.bzl",
"JavaLibraryInfo",
"JavaPackagingDepTSet",
"JavaPackagingInfo",
"JavaProviders",
"create_java_library_providers",
"create_native_providers",
"derive_compiling_deps",
"to_list",
)
load(
"@prelude//java:java_toolchain.bzl",
"AbiGenerationMode",
"JavaToolchainInfo",
)
load("@prelude//java/plugins:java_annotation_processor.bzl", "create_ap_params", "create_ksp_ap_params")
load("@prelude//java/plugins:java_plugin.bzl", "create_plugin_params")
load("@prelude//java/utils:java_utils.bzl", "get_abi_generation_mode", "get_default_info", "get_java_version_attributes", "get_path_separator")
load(
"@prelude//kotlin:kotlin_toolchain.bzl",
"KotlinToolchainInfo",
)
load("@prelude//kotlin:kotlincd_jar_creator.bzl", "create_jar_artifact_kotlincd")
load("@prelude//utils:utils.bzl", "map_idx")
_JAVA_OR_KOTLIN_FILE_EXTENSION = [".java", ".kt"]
def _create_kotlin_sources(
ctx: "context",
srcs: ["artifact"],
deps: ["dependency"],
annotation_processor_params: [["AnnotationProcessorParams"], None],
ksp_annotation_processor_params: ["AnnotationProcessorParams", None],
additional_classpath_entries: ["artifact"]) -> ("artifact", ["artifact", None], ["artifact", None]):
"""
Runs kotlinc on the provided kotlin sources.
"""
kotlin_toolchain = ctx.attrs._kotlin_toolchain[KotlinToolchainInfo]
compile_kotlin_tool = kotlin_toolchain.compile_kotlin[RunInfo]
kotlinc = kotlin_toolchain.kotlinc[RunInfo]
kotlinc_output = ctx.actions.declare_output("kotlinc_classes_output")
compile_kotlin_cmd = cmd_args([
compile_kotlin_tool,
"--kotlinc_output",
kotlinc_output.as_output(),
])
java_toolchain = ctx.attrs._java_toolchain[JavaToolchainInfo]
zip_scrubber_args = ["--zip_scrubber", cmd_args(java_toolchain.zip_scrubber, delimiter = " ")]
compile_kotlin_cmd.add(zip_scrubber_args)
kotlinc_cmd_args = cmd_args([kotlinc])
compiling_classpath = [] + additional_classpath_entries
compiling_deps_tset = derive_compiling_deps(ctx.actions, None, deps + kotlin_toolchain.kotlinc_classpath)
if compiling_deps_tset:
compiling_classpath.extend(
[compiling_dep.abi for compiling_dep in list(compiling_deps_tset.traverse())],
)
classpath_args = cmd_args(
compiling_classpath,
delimiter = get_path_separator(),
)
# write joined classpath string into args file
classpath_args_file, _ = ctx.actions.write(
"kotlinc_classpath",
classpath_args,
allow_args = True,
)
compile_kotlin_cmd.hidden([compiling_classpath])
kotlinc_cmd_args.add(["-classpath"])
kotlinc_cmd_args.add(cmd_args(classpath_args_file, format = "@{}"))
module_name = ctx.label.package.replace("/", ".") + "." + ctx.label.name
kotlinc_cmd_args.add(
[
"-module-name",
module_name,
"-no-stdlib",
"-no-reflect",
] + ctx.attrs.extra_kotlinc_arguments,
)
jvm_target = _get_kotlinc_compatible_target(ctx.attrs.target) if ctx.attrs.target else None
if jvm_target:
kotlinc_cmd_args.add([
"-jvm-target",
jvm_target,
])
kapt_generated_sources_output = None
if annotation_processor_params:
compile_kotlin_cmd.add(["--kapt_annotation_processing_jar", kotlin_toolchain.annotation_processing_jar[JavaLibraryInfo].library_output.full_library])
compile_kotlin_cmd.add(["--kapt_annotation_processors", ",".join([p for ap in annotation_processor_params for p in ap.processors])])
compile_kotlin_cmd.add(["--kapt_annotation_processor_params", ";".join([p for ap in annotation_processor_params for p in ap.params])])
annotation_processor_classpath_tsets = (
filter(None, ([ap.deps for ap in annotation_processor_params])) +
[dep[JavaPackagingInfo].packaging_deps for dep in [kotlin_toolchain.annotation_processing_jar, kotlin_toolchain.kotlin_stdlib]]
)
annotation_processor_classpath = ctx.actions.tset(
JavaPackagingDepTSet,
children = annotation_processor_classpath_tsets,
).project_as_args("full_jar_args")
kapt_classpath_file = ctx.actions.write("kapt_classpath_file", annotation_processor_classpath)
compile_kotlin_cmd.add(["--kapt_classpath_file", kapt_classpath_file])
compile_kotlin_cmd.hidden(annotation_processor_classpath)
sources_output = ctx.actions.declare_output("kapt_sources_output")
compile_kotlin_cmd.add(["--kapt_sources_output", sources_output.as_output()])
classes_output = ctx.actions.declare_output("kapt_classes_output")
compile_kotlin_cmd.add(["--kapt_classes_output", classes_output.as_output()])
stubs = ctx.actions.declare_output("kapt_stubs")
compile_kotlin_cmd.add(["--kapt_stubs", stubs.as_output()])
kapt_generated_sources_output = ctx.actions.declare_output("kapt_generated_sources_output.src.zip")
compile_kotlin_cmd.add(["--kapt_generated_sources_output", kapt_generated_sources_output.as_output()])
compile_kotlin_cmd.add(["--kapt_base64_encoder", cmd_args(kotlin_toolchain.kapt_base64_encoder[RunInfo], delimiter = " ")])
generated_kotlin_output = ctx.actions.declare_output("kapt_generated_kotlin_output")
compile_kotlin_cmd.add(["--kapt_generated_kotlin_output", generated_kotlin_output.as_output()])
if jvm_target:
compile_kotlin_cmd.add(["--kapt_jvm_target", jvm_target])
friend_paths = ctx.attrs.friend_paths
if friend_paths:
concat_friends_paths = cmd_args([friend_path.library_output.abi for friend_path in map_idx(JavaLibraryInfo, friend_paths)], delimiter = ",")
kotlinc_cmd_args.add(cmd_args(["-Xfriend-paths", concat_friends_paths], delimiter = "="))
zipped_sources, plain_sources = split_on_archives_and_plain_files(srcs, _JAVA_OR_KOTLIN_FILE_EXTENSION)
kotlinc_cmd_args.add(plain_sources)
ksp_zipped_sources_output = None
if ksp_annotation_processor_params:
ksp_cmd = cmd_args(compile_kotlin_tool)
ksp_cmd.add(zip_scrubber_args)
if ksp_annotation_processor_params.deps:
ksp_cmd.add(["--ksp_processor_jars"])
ksp_cmd.add(cmd_args(ksp_annotation_processor_params.deps.project_as_args("full_jar_args"), delimiter = ","))
ksp_cmd.add(["--ksp_classpath", classpath_args])
ksp_classes_and_resources_output = ctx.actions.declare_output("ksp_output_dir/ksp_classes_and_resources_output")
ksp_cmd.add(["--ksp_classes_and_resources_output", ksp_classes_and_resources_output.as_output()])
ksp_output = cmd_args(ksp_classes_and_resources_output.as_output()).parent()
ksp_cmd.add(["--ksp_output", ksp_output])
ksp_sources_output = ctx.actions.declare_output("ksp_output_dir/ksp_sources_output")
ksp_cmd.add(["--ksp_sources_output", ksp_sources_output.as_output()])
ksp_zipped_sources_output = ctx.actions.declare_output("ksp_output_dir/ksp_zipped_sources_output.src.zip")
ksp_cmd.add(["--ksp_zipped_sources_output", ksp_zipped_sources_output.as_output()])
ksp_cmd.add(["--ksp_project_base_dir", ctx.label.path])
ksp_kotlinc_cmd_args = cmd_args(kotlinc_cmd_args)
_add_plugins(ctx, ksp_kotlinc_cmd_args, ksp_cmd, is_ksp = True)
ksp_cmd_args_file, _ = ctx.actions.write(
"ksp_kotlinc_cmd",
ksp_kotlinc_cmd_args,
allow_args = True,
)
ksp_cmd.add("--kotlinc_cmd_file")
ksp_cmd.add(ksp_cmd_args_file)
ksp_cmd.hidden(ksp_kotlinc_cmd_args)
ctx.actions.run(ksp_cmd, category = "ksp_kotlinc")
zipped_sources = (zipped_sources or []) + [ksp_zipped_sources_output]
compile_kotlin_cmd.add(["--ksp_generated_classes_and_resources", ksp_classes_and_resources_output])
_add_plugins(ctx, kotlinc_cmd_args, compile_kotlin_cmd, is_ksp = False)
if zipped_sources:
zipped_sources_file = ctx.actions.write("kotlinc_zipped_source_args", zipped_sources)
compile_kotlin_cmd.add(["--zipped_sources_file", zipped_sources_file])
compile_kotlin_cmd.hidden(zipped_sources)
args_file, _ = ctx.actions.write(
"kotlinc_cmd",
kotlinc_cmd_args,
allow_args = True,
)
compile_kotlin_cmd.hidden([plain_sources])
compile_kotlin_cmd.add("--kotlinc_cmd_file")
compile_kotlin_cmd.add(args_file)
compile_kotlin_cmd.hidden(kotlinc_cmd_args)
ctx.actions.run(compile_kotlin_cmd, category = "kotlinc")
return kotlinc_output, kapt_generated_sources_output, ksp_zipped_sources_output
def _is_ksp_plugin(plugin: str.type) -> bool.type:
return "symbol-processing" in plugin
def _add_plugins(
ctx: "context",
kotlinc_cmd_args: "cmd_args",
compile_kotlin_cmd: "cmd_args",
is_ksp: bool.type):
for plugin, plugin_options in ctx.attrs.kotlin_compiler_plugins.items():
if _is_ksp_plugin(str(plugin)) != is_ksp:
continue
kotlinc_cmd_args.add(cmd_args(["-Xplugin", plugin], delimiter = "="))
options = []
for option_key, option_val in plugin_options.items():
# "_codegen_dir_" means buck should provide a dir
if option_val == "__codegen_dir__":
option_val = ctx.actions.declare_output("kotlin_compiler_plugin_dir")
options.append(cmd_args([option_key, option_val.as_output()], delimiter = "="))
compile_kotlin_cmd.add(["--kotlin_compiler_plugin_dir", option_val.as_output()])
else:
options.append(cmd_args([option_key, option_val], delimiter = "="))
if options:
kotlinc_cmd_args.add(["-P", cmd_args(options, delimiter = ",")])
# kotlinc is strict about the target that you can pass, e.g.
# error: unknown JVM target version: 8. Supported versions: 1.6, 1.8, 9, 10, 11, 12
def _get_kotlinc_compatible_target(target: str.type) -> str.type:
return "1.6" if target == "6" else "1.8" if target == "8" else target
def kotlin_library_impl(ctx: "context") -> ["provider"]:
packaging_deps = ctx.attrs.deps + ctx.attrs.exported_deps + ctx.attrs.runtime_deps
if ctx.attrs._build_only_native_code:
shared_library_info, cxx_resource_info = create_native_providers(ctx.actions, ctx.label, packaging_deps)
return [
shared_library_info,
cxx_resource_info,
# Add an unused default output in case this target is used an an attr.source() anywhere.
DefaultInfo(default_outputs = [ctx.actions.write("unused.jar", [])]),
TemplatePlaceholderInfo(keyed_variables = {
"classpath": "unused_but_needed_for_analysis",
}),
]
java_providers = build_kotlin_library(ctx)
return to_list(java_providers) + [
# TODO(T107163344) this shouldn't be in kotlin_library itself, use overlays to remove it.
merge_android_packageable_info(
ctx.label,
ctx.actions,
ctx.attrs.deps + ctx.attrs.exported_deps + ctx.attrs.runtime_deps,
),
]
def build_kotlin_library(
ctx: "context",
additional_classpath_entries: ["artifact"] = [],
bootclasspath_entries: ["artifact"] = []) -> "JavaProviders":
srcs = ctx.attrs.srcs
has_kotlin_srcs = any([src.extension == ".kt" or src.basename.endswith(".src.zip") or src.basename.endswith("-sources.jar") for src in srcs])
if not has_kotlin_srcs:
return build_java_library(
ctx,
ctx.attrs.srcs,
bootclasspath_entries = bootclasspath_entries,
additional_classpath_entries = additional_classpath_entries,
# Match buck1, which always does class ABI generation for Kotlin targets unless explicitly specified.
override_abi_generation_mode = get_abi_generation_mode(ctx.attrs.abi_generation_mode) or AbiGenerationMode("class"),
)
else:
deps_query = getattr(ctx.attrs, "deps_query", []) or []
provided_deps_query = getattr(ctx.attrs, "provided_deps_query", []) or []
deps = (
ctx.attrs.deps +
deps_query +
ctx.attrs.exported_deps +
ctx.attrs.provided_deps +
provided_deps_query +
ctx.attrs.exported_provided_deps
)
annotation_processor_params = create_ap_params(
ctx,
ctx.attrs.plugins,
ctx.attrs.annotation_processors,
ctx.attrs.annotation_processor_params,
ctx.attrs.annotation_processor_deps,
)
ksp_annotation_processor_params = create_ksp_ap_params(ctx, ctx.attrs.plugins)
kotlin_toolchain = ctx.attrs._kotlin_toolchain[KotlinToolchainInfo]
if kotlin_toolchain.kotlinc_protocol == "classic":
kotlinc_classes, kapt_generated_sources, ksp_generated_sources = _create_kotlin_sources(
ctx,
ctx.attrs.srcs,
deps,
annotation_processor_params,
ksp_annotation_processor_params,
# kotlic doesn't support -bootclasspath param, so adding `bootclasspath_entries` into kotlin classpath
additional_classpath_entries + bootclasspath_entries,
)
srcs = [src for src in ctx.attrs.srcs if not src.extension == ".kt"]
if kapt_generated_sources:
srcs.append(kapt_generated_sources)
if ksp_generated_sources:
srcs.append(ksp_generated_sources)
java_lib = build_java_library(
ctx,
srcs,
run_annotation_processors = False,
bootclasspath_entries = bootclasspath_entries,
additional_classpath_entries = [kotlinc_classes] + additional_classpath_entries,
additional_compiled_srcs = kotlinc_classes,
generated_sources = filter(None, [kapt_generated_sources, ksp_generated_sources]),
)
return java_lib
elif kotlin_toolchain.kotlinc_protocol == "kotlincd":
source_level, target_level = get_java_version_attributes(ctx)
outputs = create_jar_artifact_kotlincd(
actions = ctx.actions,
actions_prefix = "",
abi_generation_mode = get_abi_generation_mode(ctx.attrs.abi_generation_mode),
java_toolchain = ctx.attrs._java_toolchain[JavaToolchainInfo],
kotlin_toolchain = kotlin_toolchain,
label = ctx.label,
srcs = srcs,
remove_classes = ctx.attrs.remove_classes,
resources = ctx.attrs.resources,
resources_root = ctx.attrs.resources_root,
ap_params = annotation_processor_params + ([ksp_annotation_processor_params] if ksp_annotation_processor_params else []),
plugin_params = create_plugin_params(ctx, ctx.attrs.plugins),
source_level = source_level,
target_level = target_level,
deps = deps,
required_for_source_only_abi = ctx.attrs.required_for_source_only_abi,
source_only_abi_deps = ctx.attrs.source_only_abi_deps,
extra_arguments = ctx.attrs.extra_arguments,
additional_classpath_entries = additional_classpath_entries,
bootclasspath_entries = bootclasspath_entries,
is_building_android_binary = ctx.attrs._is_building_android_binary,
friend_paths = ctx.attrs.friend_paths,
kotlin_compiler_plugins = ctx.attrs.kotlin_compiler_plugins,
extra_kotlinc_arguments = ctx.attrs.extra_kotlinc_arguments,
)
java_library_info, java_packaging_info, shared_library_info, cxx_resource_info, template_placeholder_info, intellij_info = create_java_library_providers(
ctx,
library_output = outputs.classpath_entry if outputs else None,
declared_deps = ctx.attrs.deps + deps_query,
exported_deps = ctx.attrs.exported_deps,
provided_deps = ctx.attrs.provided_deps + provided_deps_query,
exported_provided_deps = ctx.attrs.exported_provided_deps,
runtime_deps = ctx.attrs.runtime_deps,
needs_desugar = source_level > 7 or target_level > 7,
generated_sources = [outputs.annotation_processor_output] if outputs and outputs.annotation_processor_output else [],
)
default_info = get_default_info(outputs)
return JavaProviders(
java_library_info = java_library_info,
java_library_intellij_info = intellij_info,
java_packaging_info = java_packaging_info,
shared_library_info = shared_library_info,
cxx_resource_info = cxx_resource_info,
template_placeholder_info = template_placeholder_info,
default_info = default_info,
)
else:
fail("unrecognized kotlinc protocol `{}`".format(kotlin_toolchain.kotlinc_protocol))

View file

@ -0,0 +1,21 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under both the MIT license found in the
# LICENSE-MIT file in the root directory of this source tree and the Apache
# License, Version 2.0 found in the LICENSE-APACHE file in the root directory
# of this source tree.
load("@prelude//java:java_test.bzl", "build_junit_test")
load("@prelude//kotlin:kotlin_library.bzl", "build_kotlin_library")
load("@prelude//test/inject_test_run_info.bzl", "inject_test_run_info")
def kotlin_test_impl(ctx: "context") -> ["provider"]:
java_providers = build_kotlin_library(ctx, ctx.attrs.srcs)
external_runner_test_info = build_junit_test(ctx, java_providers.java_library_info, java_providers.java_packaging_info)
return inject_test_run_info(ctx, external_runner_test_info) + [
java_providers.java_library_info,
java_providers.java_packaging_info,
java_providers.template_placeholder_info,
java_providers.default_info,
]

View file

@ -0,0 +1,25 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under both the MIT license found in the
# LICENSE-MIT file in the root directory of this source tree and the Apache
# License, Version 2.0 found in the LICENSE-APACHE file in the root directory
# of this source tree.
KotlincProtocol = enum("classic", "kotlincd")
KotlinToolchainInfo = provider(
"Kotlin toolchain info",
fields = [
"annotation_processing_jar",
"compile_kotlin",
"kapt_base64_encoder",
"kotlinc",
"kotlinc_classpath",
"kotlinc_protocol",
"kotlin_stdlib",
"kotlin_home_libraries",
"kosabi_stubs_gen_plugin",
"kosabi_applicability_plugin",
"kosabi_jvm_abi_gen_plugin",
],
)

View file

@ -0,0 +1,254 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under both the MIT license found in the
# LICENSE-MIT file in the root directory of this source tree and the Apache
# License, Version 2.0 found in the LICENSE-APACHE file in the root directory
# of this source tree.
load(
"@prelude//java:java_providers.bzl",
"JavaLibraryInfo",
"make_compile_outputs",
)
load("@prelude//java:java_resources.bzl", "get_resources_map")
load("@prelude//java:java_toolchain.bzl", "AbiGenerationMode")
load(
"@prelude//jvm:cd_jar_creator_util.bzl",
"OutputPaths",
"TargetType",
"add_output_paths_to_cmd_args",
"base_qualified_name",
"declare_prefixed_output",
"define_output_paths",
"encode_base_jar_command",
"encode_jar_params",
"encode_path",
"generate_abi_jars",
"prepare_final_jar",
)
load("@prelude//utils:utils.bzl", "expect", "map_idx")
def create_jar_artifact_kotlincd(
actions: "actions",
actions_prefix: [str.type, None],
abi_generation_mode: [AbiGenerationMode.type, None],
java_toolchain: "JavaToolchainInfo",
kotlin_toolchain: "KotlinToolchainInfo",
label: "label",
srcs: ["artifact"],
remove_classes: [str.type],
resources: ["artifact"],
resources_root: [str.type, None],
ap_params: ["AnnotationProcessorParams"],
plugin_params: ["PluginParams", None],
source_level: int.type,
target_level: int.type,
deps: ["dependency"],
required_for_source_only_abi: bool.type,
source_only_abi_deps: ["dependency"],
extra_arguments: ["string"],
additional_classpath_entries: ["artifact"],
bootclasspath_entries: ["artifact"],
is_building_android_binary: bool.type,
friend_paths: ["dependency"],
kotlin_compiler_plugins: dict.type,
extra_kotlinc_arguments: [str.type]) -> "JavaCompileOutputs":
resources_map = get_resources_map(
java_toolchain = java_toolchain,
package = label.package,
resources = resources,
resources_root = resources_root,
)
expect(abi_generation_mode != AbiGenerationMode("source"), "abi_generation_mode: source is not supported in kotlincd")
actual_abi_generation_mode = abi_generation_mode or AbiGenerationMode("class") if srcs else AbiGenerationMode("class")
if actions_prefix:
actions_prefix += "_"
output_paths = define_output_paths(actions, actions_prefix)
path_to_class_hashes_out = declare_prefixed_output(actions, actions_prefix, "classes.txt")
def encode_kotlin_extra_params(kotlin_compiler_plugins):
return struct(
extraClassPaths = [encode_path(path) for path in bootclasspath_entries],
standardLibraryClassPath = encode_path(kotlin_toolchain.kotlin_stdlib[JavaLibraryInfo].library_output.full_library),
annotationProcessingClassPath = encode_path(kotlin_toolchain.annotation_processing_jar[JavaLibraryInfo].library_output.full_library),
kotlinCompilerPlugins = {plugin: {"params": plugin_options} if plugin_options else {} for plugin, plugin_options in kotlin_compiler_plugins.items()},
kosabiPluginOptions = struct(
kosabi_stubs_gen_plugin = encode_path(kotlin_toolchain.kosabi_stubs_gen_plugin),
kosabi_applicability_plugin = encode_path(kotlin_toolchain.kosabi_applicability_plugin),
kosabi_jvm_abi_gen_plugin = encode_path(kotlin_toolchain.kosabi_jvm_abi_gen_plugin),
),
friendPaths = [encode_path(friend_path.library_output.abi) for friend_path in map_idx(JavaLibraryInfo, friend_paths)],
kotlinHomeLibraries = [encode_path(target) for target in kotlin_toolchain.kotlin_home_libraries],
jvmTarget = "1.8",
kosabiJvmAbiGenEarlyTerminationMessagePrefix = "exception: java.lang.RuntimeException: Terminating compilation. We're done with ABI.",
shouldUseJvmAbiGen = True,
shouldVerifySourceOnlyAbiConstraints = actual_abi_generation_mode == AbiGenerationMode("source_only"),
shouldGenerateAnnotationProcessingStats = True,
extraKotlincArguments = extra_kotlinc_arguments,
)
def encode_build_target_value_extra_params():
return struct(
basePathForBaseName = encode_path(label.path),
shortNameAndFlavorPostfix = label.name,
shortName = label.name,
cellRelativeBasePath = encode_path(label.path),
buckPaths = struct(
configuredBuckOut = encode_path("buck-out/v2"),
includeTargetConfigHash = True,
),
)
kotlin_extra_params = encode_kotlin_extra_params(kotlin_compiler_plugins)
build_target_value_extra_params = encode_build_target_value_extra_params()
def encode_library_command(
output_paths: OutputPaths.type,
path_to_class_hashes: "artifact") -> struct.type:
target_type = TargetType("library")
base_jar_command = encode_base_jar_command(
target_type,
output_paths,
remove_classes,
label,
actions,
deps,
additional_classpath_entries,
source_only_abi_deps,
bootclasspath_entries,
source_level,
target_level,
actual_abi_generation_mode,
srcs,
resources_map,
ap_params = ap_params,
plugin_params = plugin_params,
extra_arguments = extra_arguments,
track_class_usage = False,
build_target_value_extra_params = build_target_value_extra_params,
)
return struct(
baseCommandParams = struct(
withDownwardApi = True,
hasAnnotationProcessing = True,
),
libraryJarCommand = struct(
kotlinExtraParams = kotlin_extra_params,
baseJarCommand = base_jar_command,
libraryJarBaseCommand = struct(
pathToClasses = encode_path(output_paths.jar.as_output()),
rootOutput = encode_path(output_paths.jar_parent.as_output()),
pathToClassHashes = encode_path(path_to_class_hashes.as_output()),
annotationsPath = encode_path(output_paths.annotations.as_output()),
),
),
)
def encode_abi_command(output_paths: OutputPaths.type, target_type: TargetType.type) -> struct.type:
base_jar_command = encode_base_jar_command(
target_type,
output_paths,
remove_classes,
label,
actions,
deps,
additional_classpath_entries,
source_only_abi_deps,
bootclasspath_entries,
source_level,
target_level,
actual_abi_generation_mode,
srcs,
resources_map,
ap_params,
plugin_params,
extra_arguments,
False,
build_target_value_extra_params,
)
abi_params = encode_jar_params(remove_classes, output_paths)
abi_command = struct(
kotlinExtraParams = kotlin_extra_params,
baseJarCommand = base_jar_command,
abiJarParameters = abi_params,
)
return struct(
baseCommandParams = struct(
withDownwardApi = True,
),
abiJarCommand = abi_command,
)
# buildifier: disable=uninitialized
def define_kotlincd_action(
actions_prefix: str.type,
encoded_command: struct.type,
qualified_name: str.type,
output_paths: OutputPaths.type,
path_to_class_hashes: ["artifact", None]):
proto = declare_prefixed_output(actions, actions_prefix, "jar_command.proto.json")
classpath_jars_tag = actions.artifact_tag()
proto_with_inputs = classpath_jars_tag.tag_inputs(actions.write_json(proto, encoded_command, with_inputs = True))
cmd = cmd_args([
kotlin_toolchain.kotlinc[RunInfo],
"--action-id",
qualified_name,
"--command-file",
proto_with_inputs,
])
cmd = add_output_paths_to_cmd_args(cmd, output_paths, path_to_class_hashes)
event_pipe_out = declare_prefixed_output(actions, actions_prefix, "events.data")
actions.run(
cmd,
env = {
"BUCK_EVENT_PIPE": event_pipe_out.as_output(),
"JAVACD_ABSOLUTE_PATHS_ARE_RELATIVE_TO_CWD": "1",
},
category = "{}kotlincd_jar".format(actions_prefix),
)
command = encode_library_command(output_paths, path_to_class_hashes_out)
define_kotlincd_action(
actions_prefix = actions_prefix,
encoded_command = command,
qualified_name = base_qualified_name(label),
output_paths = output_paths,
path_to_class_hashes = path_to_class_hashes_out,
)
final_jar = prepare_final_jar(
actions = actions,
actions_prefix = actions_prefix,
output = None,
output_paths = output_paths,
additional_compiled_srcs = None,
jar_builder = java_toolchain.jar_builder,
)
# kotlincd does not support source abi
class_abi, _, source_only_abi, classpath_abi = generate_abi_jars(
actions = actions,
actions_prefix = actions_prefix,
label = label,
abi_generation_mode = actual_abi_generation_mode,
additional_compiled_srcs = None,
is_building_android_binary = is_building_android_binary,
class_abi_generator = java_toolchain.class_abi_generator,
final_jar = final_jar,
encode_abi_command = encode_abi_command,
define_javacd_action = define_kotlincd_action,
)
return make_compile_outputs(
full_library = final_jar,
class_abi = class_abi,
source_only_abi = source_only_abi,
classpath_abi = classpath_abi,
required_for_source_only_abi = required_for_source_only_abi,
annotation_processor_output = output_paths.annotations,
)