diff --git a/MODULE.bazel b/MODULE.bazel
index 40af3bee4..3915c7f64 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -28,6 +28,14 @@ use_repo(
"com_github_google_ksp",
"com_github_jetbrains_kotlin",
"com_github_jetbrains_kotlin_git",
+ "com_github_jetbrains_kotlin_native_linux_x86_64",
+ "com_github_jetbrains_kotlin_native_linux_x86_64_git",
+ "com_github_jetbrains_kotlin_native_macos_aarch64",
+ "com_github_jetbrains_kotlin_native_macos_aarch64_git",
+ "com_github_jetbrains_kotlin_native_macos_x86_64",
+ "com_github_jetbrains_kotlin_native_macos_x86_64_git",
+ "com_github_jetbrains_kotlin_native_windows_x86_64",
+ "com_github_jetbrains_kotlin_native_windows_x86_64_git",
"com_github_pinterest_ktlint",
"kotlin_build_tools_impl",
"kotlinx_serialization_core_jvm",
@@ -35,10 +43,12 @@ use_repo(
"kotlinx_serialization_json_jvm",
)
-register_toolchains("//src/main/starlark/core/compile/cli")
+register_toolchains("//src/main/starlark/core/compile/cli:all")
register_toolchains("//kotlin/internal:default_toolchain")
+register_toolchains("//kotlin/internal/native:all")
+
# Development dependencies
# TODO(bencodes) A bunch of these dependencies need to be marked as dev_dependencies but before we can do that
# we need to sort out a few cases around how these rules are consumed in various ways.
diff --git a/MODULE.release.bazel b/MODULE.release.bazel
index 2968296d8..cbef74b74 100644
--- a/MODULE.release.bazel
+++ b/MODULE.release.bazel
@@ -31,6 +31,16 @@ use_repo(
"kotlinx_serialization_json",
"kotlinx_serialization_json_jvm",
"kotlin_build_tools_impl",
+ "com_github_jetbrains_kotlin_native_linux_x86_64",
+ "com_github_jetbrains_kotlin_native_linux_x86_64_git",
+ "com_github_jetbrains_kotlin_native_macos_aarch64",
+ "com_github_jetbrains_kotlin_native_macos_aarch64_git",
+ "com_github_jetbrains_kotlin_native_macos_x86_64",
+ "com_github_jetbrains_kotlin_native_macos_x86_64_git",
+ "com_github_jetbrains_kotlin_native_windows_x86_64",
+ "com_github_jetbrains_kotlin_native_windows_x86_64_git",
)
register_toolchains("//kotlin/internal:default_toolchain")
+
+register_toolchains("//kotlin/internal/native:all")
diff --git a/docs/kotlin.md b/docs/kotlin.md
index 1c96221eb..f0bd0721e 100755
--- a/docs/kotlin.md
+++ b/docs/kotlin.md
@@ -562,7 +562,7 @@ load("@rules_kotlin//kotlin:core.bzl", "kt_register_toolchains")
kt_register_toolchains()
-This macro registers the kotlin toolchain.
+This macro registers the kotlin/JVM toolchain and the kotlin native toolchain.
@@ -578,7 +578,9 @@ This macro registers the kotlin toolchain.
load("@rules_kotlin//kotlin:repositories.doc.bzl", "kotlin_repositories")
kotlin_repositories(is_bzlmod, compiler_repository_name, ksp_repository_name, compiler_release,
- ksp_compiler_release)
+ ksp_compiler_release, kotlin_native_release_linux_x86_64,
+ kotlin_native_release_macos_x86_64, kotlin_native_release_macos_aarch64,
+ kotlin_native_release_windows_x86_64)
Call this in the WORKSPACE file to setup the Kotlin rules.
@@ -593,6 +595,10 @@ Call this in the WORKSPACE file to setup the Kotlin rules.
| ksp_repository_name |
-
| `"com_github_google_ksp"` |
| compiler_release | version provider from versions.bzl. | `struct(sha256 = "1ba08a8b45da99339a0601134cc037b54cf85e9bc0edbe76dcbd27c2d684a977", url_templates = ["https://github.com/JetBrains/kotlin/releases/download/v{version}/kotlin-compiler-{version}.zip"], version = "2.1.21")` |
| ksp_compiler_release | (internal) version provider from versions.bzl. | `struct(sha256 = "44e965bb067b2bb5cd9184dab2c3dea6e3eab747d341c07645bb4c88f09e49c8", url_templates = ["https://github.com/google/ksp/releases/download/{version}/artifacts.zip"], version = "2.1.21-2.0.1")` |
+| kotlin_native_release_linux_x86_64 | (internal) version provider from versions.bzl | `struct(sha256 = "42fb88529b4039b6ac1961a137ccb1c79fc80315947f3ec31b56834c7ce20d0b", strip_prefix_template = "kotlin-native-prebuilt-linux-x86_64-{version}", url_templates = ["https://github.com/JetBrains/kotlin/releases/download/v{version}/kotlin-native-prebuilt-linux-x86_64-{version}.tar.gz"], version = "2.1.21")` |
+| kotlin_native_release_macos_x86_64 | (internal) version provider from versions.bzl | `struct(sha256 = "fc6b5979ec322be803bfac549661aaf0f8f7342aa3bd09008d471fff2757bbdf", strip_prefix_template = "kotlin-native-prebuilt-macos-x86_64-{version}", url_templates = ["https://github.com/JetBrains/kotlin/releases/download/v{version}/kotlin-native-prebuilt-macos-x86_64-{version}.tar.gz"], version = "2.1.21")` |
+| kotlin_native_release_macos_aarch64 | -
| `struct(sha256 = "8df16175b962bc4264a5c3b32cb042d91458babbd093c0f36194dc4645f5fe2e", strip_prefix_template = "kotlin-native-prebuilt-macos-aarch64-{version}", url_templates = ["https://github.com/JetBrains/kotlin/releases/download/v{version}/kotlin-native-prebuilt-macos-aarch64-{version}.tar.gz"], version = "2.1.21")` |
+| kotlin_native_release_windows_x86_64 | (internal) version provider from versions.bzl | `struct(sha256 = "03301473bb9e68dadfdd265857a2a5913a147e700e345d32db73e0a21a2ffbfa", strip_prefix_template = "kotlin-native-prebuilt-windows-x86_64-{version}", url_templates = ["https://github.com/JetBrains/kotlin/releases/download/v{version}/kotlin-native-prebuilt-windows-x86_64-{version}.zip"], version = "2.1.21")` |
diff --git a/kotlin/compiler/BUILD b/kotlin/compiler/BUILD
index f0698661d..17a08a0d0 100644
--- a/kotlin/compiler/BUILD
+++ b/kotlin/compiler/BUILD
@@ -15,6 +15,7 @@ load("//src/main/starlark/release:packager.bzl", "release_archive")
# limitations under the License.
load(":compiler.bzl", "kt_configure_compiler")
load(":ksp.bzl", "kt_configure_ksp")
+load(":native.bzl", "kt_configure_native_compiler")
package(default_visibility = ["//visibility:public"])
@@ -24,6 +25,9 @@ kt_configure_compiler()
# Configures the KSP plugins
kt_configure_ksp()
+# Configure the native compiler (used only for runfiles in KotlinBuilder)
+kt_configure_native_compiler()
+
release_archive(
name = "pkg",
srcs = glob(["*.bzl"]),
diff --git a/kotlin/compiler/BUILD.release.bazel b/kotlin/compiler/BUILD.release.bazel
index f50885af0..1c40bc1b5 100644
--- a/kotlin/compiler/BUILD.release.bazel
+++ b/kotlin/compiler/BUILD.release.bazel
@@ -15,6 +15,7 @@
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
load(":compiler.bzl", "kt_configure_compiler")
load(":ksp.bzl", "kt_configure_ksp")
+load(":native.bzl", "kt_configure_native_compiler")
package(default_visibility = ["//visibility:public"])
@@ -24,6 +25,9 @@ kt_configure_compiler()
# Configures the KSP plugins
kt_configure_ksp()
+# Configure the native compiler (used only for runfiles in KotlinBuilder)
+kt_configure_native_compiler()
+
bzl_library(
name = "compiler",
srcs = glob(["*.bzl"]),
diff --git a/kotlin/compiler/compiler.bzl b/kotlin/compiler/compiler.bzl
index 390cc9188..c60135414 100644
--- a/kotlin/compiler/compiler.bzl
+++ b/kotlin/compiler/compiler.bzl
@@ -25,18 +25,18 @@ KOTLIN_STDLIBS = [
"//kotlin/compiler:trove4j",
]
-def _import_artifacts(artifacts, rule_kind):
- _import_labels(artifacts.plugin, rule_kind)
- _import_labels(artifacts.runtime, rule_kind)
- _import_labels(artifacts.compile, rule_kind, neverlink = 1)
+def _import_artifacts(artifacts, rule_kind, compiler_repo = _KT_COMPILER_REPO):
+ _import_labels(artifacts.plugin, rule_kind, compiler_repo)
+ _import_labels(artifacts.runtime, rule_kind, compiler_repo)
+ _import_labels(artifacts.compile, rule_kind, compiler_repo, neverlink = 1)
-def _import_labels(labels, rule_kind, **rule_args):
+def _import_labels(labels, rule_kind, compiler_repo, **rule_args):
for (label, file) in labels.items():
if not file.endswith(".jar"):
native.filegroup(
name = label,
srcs = [
- "@%s//:%s" % (_KT_COMPILER_REPO, label),
+ "@%s//:%s" % (compiler_repo, label),
],
)
return
@@ -46,10 +46,10 @@ def _import_labels(labels, rule_kind, **rule_args):
args = dict(rule_args.items())
args["visibility"] = ["//visibility:public"]
args["name"] = label
- args["jars"] = ["@%s//:%s" % (_KT_COMPILER_REPO, label)]
+ args["jars"] = ["@%s//:%s" % (compiler_repo, label)]
sources = label + "-sources"
if sources in labels:
- args["srcjar"] = "@%s//:%s" % (_KT_COMPILER_REPO, sources)
+ args["srcjar"] = "@%s//:%s" % (compiler_repo, sources)
rule_kind(**args)
def kt_configure_compiler():
diff --git a/kotlin/compiler/native.bzl b/kotlin/compiler/native.bzl
new file mode 100644
index 000000000..e664cdc52
--- /dev/null
+++ b/kotlin/compiler/native.bzl
@@ -0,0 +1,17 @@
+load("//kotlin/internal:defs.bzl", "KT_NATIVE_COMPILER_REPO_PREFIX")
+
+def kt_configure_native_compiler():
+ # Ideally this would not be needed here and be available from the toolchain
+ # but the builder uses java_binary and jvm_flags are propagated for the runfile paths to it directly
+ # so it doesn't seem straightforward to do that, so this alias target allows us
+ # to reference it in the data dependencies there
+ native.alias(
+ name = "kotlin-native",
+ actual = select({
+ "@bazel_tools//src/conditions:linux_x86_64": "@" + KT_NATIVE_COMPILER_REPO_PREFIX + "_" + "linux_x86_64//:kotlin-native",
+ "@bazel_tools//src/conditions:darwin": "@" + KT_NATIVE_COMPILER_REPO_PREFIX + "_" + "macos_x86_64//:kotlin-native",
+ "@bazel_tools//src/conditions:windows": "@" + KT_NATIVE_COMPILER_REPO_PREFIX + "_" + "windows_x86_64//:kotlin-native",
+ "@bazel_tools//src/conditions:darwin_arm64": "@" + KT_NATIVE_COMPILER_REPO_PREFIX + "_" + "macos_aarch64//:kotlin-native",
+ }),
+ visibility = ["//src:__subpackages__"],
+ )
diff --git a/kotlin/internal/BUILD b/kotlin/internal/BUILD
index 019803452..852584548 100644
--- a/kotlin/internal/BUILD
+++ b/kotlin/internal/BUILD
@@ -30,6 +30,7 @@ release_archive(
deps = [
"//kotlin/internal/jvm:pkg",
"//kotlin/internal/lint:pkg",
+ "//kotlin/internal/native:pkg",
"//kotlin/internal/utils:pkg",
],
)
@@ -41,6 +42,7 @@ bzl_library(
deps = [
"//kotlin/internal/jvm",
"//kotlin/internal/lint",
+ "//kotlin/internal/native",
"//kotlin/internal/utils",
"//src/main/starlark",
"//src/main/starlark/core/compile",
diff --git a/kotlin/internal/BUILD.release.bazel b/kotlin/internal/BUILD.release.bazel
index 423b53698..d0861e7f6 100644
--- a/kotlin/internal/BUILD.release.bazel
+++ b/kotlin/internal/BUILD.release.bazel
@@ -24,6 +24,7 @@ bzl_library(
deps = [
"//kotlin/internal/jvm",
"//kotlin/internal/lint",
+ "//kotlin/internal/native",
"//kotlin/internal/utils",
"//src/main/starlark",
],
diff --git a/kotlin/internal/defs.bzl b/kotlin/internal/defs.bzl
index 8fc952f30..eca7ca9a8 100644
--- a/kotlin/internal/defs.bzl
+++ b/kotlin/internal/defs.bzl
@@ -16,6 +16,7 @@ load(
_JAVA_RUNTIME_TOOLCHAIN_TYPE = "JAVA_RUNTIME_TOOLCHAIN_TYPE",
_JAVA_TOOLCHAIN_TYPE = "JAVA_TOOLCHAIN_TYPE",
_KtJvmInfo = "KtJvmInfo",
+ _KtKlibInfo = "KtKlibInfo",
)
load(
"//src/main/starlark/core/plugin:providers.bzl",
@@ -27,6 +28,7 @@ load(
# The Kotlin Toolchain type.
TOOLCHAIN_TYPE = "%s" % Label("//kotlin/internal:kt_toolchain_type")
+NATIVE_TOOLCHAIN_TYPE = "%s" % Label("//kotlin/internal/native:kt_native_toolchain_type")
# Java toolchains
JAVA_TOOLCHAIN_TYPE = _JAVA_TOOLCHAIN_TYPE
@@ -35,6 +37,9 @@ JAVA_RUNTIME_TOOLCHAIN_TYPE = _JAVA_RUNTIME_TOOLCHAIN_TYPE
# The name of the Kotlin compiler workspace.
KT_COMPILER_REPO = "com_github_jetbrains_kotlin"
+# The preifx of the Kotlin native compiler workspace name (will be suffixed with the platform)
+KT_NATIVE_COMPILER_REPO_PREFIX = "com_github_jetbrains_kotlin_native"
+
# The name of the KSP compiler plugin workspace
KSP_COMPILER_PLUGIN_REPO = "com_github_google_ksp"
@@ -47,3 +52,5 @@ KspPluginInfo = _KspPluginInfo
KtCompilerPluginOption = _KtCompilerPluginOption
KtPluginConfiguration = _KtPluginConfiguration
+
+KtKlibInfo = _KtKlibInfo
diff --git a/kotlin/internal/native/BUILD.bazel b/kotlin/internal/native/BUILD.bazel
new file mode 100644
index 000000000..43844114c
--- /dev/null
+++ b/kotlin/internal/native/BUILD.bazel
@@ -0,0 +1,24 @@
+load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
+load("//kotlin/internal/native:toolchains.bzl", "kt_configure_native_toolchains")
+load("//src/main/starlark/release:packager.bzl", "release_archive")
+
+kt_configure_native_toolchains()
+
+release_archive(
+ name = "pkg",
+ srcs = glob(["*.bzl"]),
+ src_map = {
+ "BUILD.release.bazel": "BUILD.bazel",
+ },
+)
+
+bzl_library(
+ name = "native",
+ srcs = glob(["*.bzl"]),
+ visibility = ["//kotlin:__subpackages__"],
+ deps = [
+ "//kotlin/internal/utils",
+ "//src/main/starlark/core/repositories/kotlin",
+ "@bazel_skylib//rules/directory",
+ ],
+)
diff --git a/kotlin/internal/native/BUILD.release.bazel b/kotlin/internal/native/BUILD.release.bazel
new file mode 100644
index 000000000..3178ca320
--- /dev/null
+++ b/kotlin/internal/native/BUILD.release.bazel
@@ -0,0 +1,15 @@
+load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
+load(":toolchains.bzl", "kt_configure_native_toolchains")
+
+kt_configure_native_toolchains()
+
+bzl_library(
+ name = "native",
+ srcs = glob(["*.bzl"]),
+ visibility = ["//kotlin:__subpackages__"],
+ deps = [
+ "//kotlin/internal/utils",
+ "//src/main/starlark/core/repositories/kotlin",
+ "@bazel_skylib//rules/directory",
+ ],
+)
diff --git a/kotlin/internal/native/library.bzl b/kotlin/internal/native/library.bzl
new file mode 100644
index 000000000..856ebb157
--- /dev/null
+++ b/kotlin/internal/native/library.bzl
@@ -0,0 +1,91 @@
+load("//kotlin/internal:defs.bzl", _KtKlibInfo = "KtKlibInfo", _NATIVE_TOOLCHAIN_TYPE = "NATIVE_TOOLCHAIN_TYPE", _TOOLCHAIN_TYPE = "TOOLCHAIN_TYPE")
+load("//kotlin/internal/utils:utils.bzl", "utils")
+
+def _kt_library_impl(ctx):
+ module_name = utils.derive_module_name(ctx)
+ builder_args = utils.init_args(ctx, "kt_library", module_name)
+
+ klib = ctx.actions.declare_file("{}.klib".format(ctx.label.name))
+ outputs = [klib]
+
+ toolchains = ctx.toolchains[_TOOLCHAIN_TYPE]
+
+ # Retrieve konan.home from the chosen toolchain's distribution
+ native_toolchain_info = ctx.toolchains[_NATIVE_TOOLCHAIN_TYPE].kotlin_native_info
+ konan_home = native_toolchain_info.konan_home
+ native_target = native_toolchain_info.target
+
+ deps_klibs = []
+ transitive_klibs = []
+ runfiles = ctx.runfiles(files = [klib] + ctx.files.data)
+
+ for dep in ctx.attr.deps:
+ deps_klibs.append(dep[_KtKlibInfo].klibs)
+ transitive_klibs.append(dep[_KtKlibInfo].transitive_klibs)
+ runfiles = runfiles.merge(dep[DefaultInfo].default_runfiles)
+
+ for d in ctx.attr.data:
+ runfiles = runfiles.merge(d[DefaultInfo].default_runfiles)
+
+ libraries = depset(transitive = deps_klibs)
+ builder_args.add_all("--sources", ctx.files.srcs)
+ builder_inputs, _, input_manifests = ctx.resolve_command(tools = [toolchains.kotlinbuilder])
+
+ builder_args.add("--strict_kotlin_deps", "off")
+ builder_args.add("--reduced_classpath_mode", "off")
+ builder_args.add("--output_klib", klib.path)
+ builder_args.add("--kotlin_native_target", native_target)
+
+ libraries = depset(transitive = deps_klibs)
+ builder_args.add_all("--klibs", libraries)
+ builder_args.add("--konan_home", konan_home.path)
+
+ ctx.actions.run(
+ mnemonic = "KotlinKlibCompile",
+ inputs = depset(builder_inputs + ctx.files.srcs, transitive = [libraries, native_toolchain_info.konan_home_files]),
+ outputs = outputs,
+ executable = toolchains.kotlinbuilder.files_to_run.executable,
+ tools = [
+ toolchains.kotlinbuilder.files_to_run,
+ ],
+ execution_requirements = {"supports-workers": "1"},
+ arguments = [ctx.actions.args().add_all(toolchains.builder_args), builder_args],
+ progress_message = "Compiling Kotlin to Klib %%{label} { kt: %d }" % len(ctx.files.srcs),
+ input_manifests = input_manifests,
+ env = {
+ "REPOSITORY_NAME": utils.builder_workspace_name(ctx),
+ },
+ )
+
+ return [
+ DefaultInfo(files = depset(outputs, transitive = transitive_klibs + deps_klibs), runfiles = runfiles),
+ _KtKlibInfo(
+ klibs = depset(outputs),
+ transitive_klibs = depset(transitive = transitive_klibs + deps_klibs),
+ ),
+ ]
+
+kt_library = rule(
+ implementation = _kt_library_impl,
+ doc = """
+This rule is intended to leverage the new Kotlin IR backend to allow for compiling platform-independent Kotlin code
+to be shared between Kotlin code for different platforms (JS/JVM/WASM etc.). It produces a klib file as the output.
+ """,
+ attrs = {
+ "srcs": attr.label_list(
+ doc = "A list of source files to be compiled to klib",
+ allow_files = [".kt"],
+ ),
+ "deps": attr.label_list(
+ doc = "A list of other kt_klib_library targets that this library depends on for compilation",
+ providers = [_KtKlibInfo],
+ ),
+ "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,
+ ),
+ },
+ toolchains = [_TOOLCHAIN_TYPE, _NATIVE_TOOLCHAIN_TYPE],
+ provides = [_KtKlibInfo],
+)
diff --git a/kotlin/internal/native/toolchains.bzl b/kotlin/internal/native/toolchains.bzl
new file mode 100644
index 000000000..49f16ff03
--- /dev/null
+++ b/kotlin/internal/native/toolchains.bzl
@@ -0,0 +1,86 @@
+load("@bazel_skylib//rules/directory:providers.bzl", "DirectoryInfo")
+load("//src/main/starlark/core/repositories/kotlin:artifacts.bzl", "KOTLIN_NATIVE_TARGETS")
+
+KotlinNativeToolchainInfo = provider(fields = {
+ "konan_home": "The path to konan.home directory",
+ "konan_properties": "The kokna.properties file corresponding to this distribution",
+ "konan_home_files": "A depset containing all the files in konan.home",
+ "targets": "A list of Kotlin native targets this toolchain supports",
+ "target": "The target chosen for compilation and to be passed as --target",
+})
+
+def _kt_native_toolchain_impl(ctx):
+ konan_home_info = ctx.attr.konan_home[DirectoryInfo]
+ konan_properties = konan_home_info.get_file("konan/konan.properties")
+ konan_home = konan_home_info
+
+ return [
+ platform_common.ToolchainInfo(
+ kotlin_native_info = KotlinNativeToolchainInfo(
+ konan_home = konan_home,
+ konan_home_files = depset(transitive = [konan_home_info.transitive_files]),
+ konan_properties = konan_properties,
+ targets = ctx.attr.targets,
+ target = ctx.attr.target,
+ ),
+ ),
+ ]
+
+kt_native_toolchain = rule(
+ implementation = _kt_native_toolchain_impl,
+ attrs = {
+ "konan_home": attr.label(
+ providers = [DirectoryInfo],
+ doc = "The directory containing konan.home",
+ ),
+ "targets": attr.string_list(
+ doc = "The list of targets supported by this toolchain. Each target can be passed to kotlinc-native with -target option",
+ default = [],
+ ),
+ "target": attr.string(
+ doc = "The Kotlin native target for this toolchain. This corresponds to the --target argument passed to the kotlin native compiler",
+ ),
+ },
+ provides = [platform_common.ToolchainInfo],
+)
+
+def kt_configure_native_toolchains():
+ """Defines and registers the default toolchains for the kotlin-native compiler for all the platforms and targets supported."""
+ native.toolchain_type(
+ name = "kt_native_toolchain_type",
+ visibility = ["//visibility:public"],
+ )
+
+ # Create toolchains for each exec platform and their supported targets
+ for exec_platform, targets in KOTLIN_NATIVE_TARGETS.items():
+ exec_compatible_with = targets.exec_compatible_with
+ for target_constraint_tuple, kotlin_native_targets in targets.targets.items():
+ target_os, target_cpu = target_constraint_tuple
+
+ # Create a unique name for this toolchain
+ toolchain_suffix = "{}_to_{}_{}".format(
+ exec_platform,
+ Label(target_os).name,
+ Label(target_cpu).name,
+ )
+ toolchain_name = "default_kt_native_toolchain_{}".format(toolchain_suffix)
+ toolchain_impl = "default_kt_native_{}".format(toolchain_suffix)
+ default_target = targets.targets[target_constraint_tuple][0]
+
+ # Create the toolchain implementation
+ kt_native_toolchain(
+ name = toolchain_impl,
+ konan_home = "@com_github_jetbrains_kotlin_native_{}//:konan_home".format(exec_platform),
+ targets = kotlin_native_targets,
+ # TODO: provide a way to override this for this target platform with a config setting
+ target = default_target,
+ )
+
+ # Register the toolchain
+ native.toolchain(
+ name = toolchain_name,
+ exec_compatible_with = exec_compatible_with,
+ target_compatible_with = [target_os, target_cpu],
+ toolchain = ":" + toolchain_impl,
+ toolchain_type = ":kt_native_toolchain_type",
+ )
diff --git a/kotlin/internal/toolchains.bzl b/kotlin/internal/toolchains.bzl
index b69a16a1b..72fdad3a4 100644
--- a/kotlin/internal/toolchains.bzl
+++ b/kotlin/internal/toolchains.bzl
@@ -304,11 +304,15 @@ _kt_toolchain = rule(
)
_KT_DEFAULT_TOOLCHAIN = Label("//kotlin/internal:default_toolchain")
+_KT_DEFAULT_NATIVE_TOOLCHAINS = Label("//kotlin/internal/native:all")
def kt_register_toolchains():
- """This macro registers the kotlin toolchain."""
+ """This macro registers the kotlin/JVM toolchain and the kotlin native toolchain."""
native.register_toolchains(str(_KT_DEFAULT_TOOLCHAIN))
+ # Register all default native toolchains
+ native.register_toolchains(str(_KT_DEFAULT_NATIVE_TOOLCHAINS))
+
# Evaluating the select in the context of bzl file to get its repository
_DEBUG_SELECT = select({
str(Label("//kotlin/internal:builder_debug_trace")): ["trace"],
diff --git a/src/main/kotlin/BUILD.release.bazel b/src/main/kotlin/BUILD.release.bazel
index 2211fe94b..50680c987 100644
--- a/src/main/kotlin/BUILD.release.bazel
+++ b/src/main/kotlin/BUILD.release.bazel
@@ -42,6 +42,7 @@ java_binary(
"//kotlin/compiler:jvm-abi-gen",
"//kotlin/compiler:kotlin-annotation-processing",
"//kotlin/compiler:kotlin-compiler",
+ "//kotlin/compiler:kotlin-native",
"//kotlin/compiler:kotlin-reflect",
"//kotlin/compiler:symbol-processing-api",
"//kotlin/compiler:symbol-processing-cmdline",
@@ -63,6 +64,7 @@ java_binary(
"-D@rules_kotlin...jdeps-gen=$(rlocationpath //src/main/kotlin:jdeps-gen)",
"-D@rules_kotlin...skip-code-gen=$(rlocationpath //src/main/kotlin:skip-code-gen)",
"-D@rules_kotlin...compiler=$(rlocationpath //src/main/kotlin/io/bazel/kotlin/compiler)",
+ "-D@com_github_jetbrains_kotlin_native...kotlin-native=$(rlocationpath //kotlin/compiler:kotlin-native)",
"-D@com_github_google_ksp...symbol-processing-api=$(rlocationpath //kotlin/compiler:symbol-processing-api)",
"-D@com_github_google_ksp...symbol-processing-cmdline=$(rlocationpath //kotlin/compiler:symbol-processing-cmdline)",
"-D@rules_kotlin..kotlin.compiler.kotlin-reflect=$(rlocationpath //kotlin/compiler:kotlin-reflect)",
diff --git a/src/main/kotlin/io/bazel/kotlin/builder/KotlinBuilderComponent.java b/src/main/kotlin/io/bazel/kotlin/builder/KotlinBuilderComponent.java
index 9cda68bd8..0d8ca9ae7 100644
--- a/src/main/kotlin/io/bazel/kotlin/builder/KotlinBuilderComponent.java
+++ b/src/main/kotlin/io/bazel/kotlin/builder/KotlinBuilderComponent.java
@@ -22,6 +22,7 @@
import io.bazel.kotlin.builder.tasks.CompileKotlin;
import io.bazel.kotlin.builder.tasks.jvm.InternalCompilerPlugins;
import io.bazel.kotlin.builder.tasks.jvm.KotlinJvmTaskExecutor;
+import io.bazel.kotlin.builder.tasks.knative.KotlinNativeTaskExecutor;
import io.bazel.kotlin.builder.toolchain.KotlinToolchain;
import javax.inject.Singleton;
@@ -33,6 +34,8 @@ public interface KotlinBuilderComponent {
KotlinJvmTaskExecutor jvmTaskExecutor();
+ KotlinNativeTaskExecutor nativeTaskExecutor();
+
CompileKotlin work();
@Component.Builder
diff --git a/src/main/kotlin/io/bazel/kotlin/builder/cmd/BUILD.bazel b/src/main/kotlin/io/bazel/kotlin/builder/cmd/BUILD.bazel
index 98511d7b3..27a9804f7 100644
--- a/src/main/kotlin/io/bazel/kotlin/builder/cmd/BUILD.bazel
+++ b/src/main/kotlin/io/bazel/kotlin/builder/cmd/BUILD.bazel
@@ -19,6 +19,7 @@ kt_bootstrap_binary(
"//kotlin/compiler:jvm-abi-gen",
"//kotlin/compiler:kotlin-annotation-processing",
"//kotlin/compiler:kotlin-compiler",
+ "//kotlin/compiler:kotlin-native",
"//kotlin/compiler:kotlin-reflect",
"//kotlin/compiler:symbol-processing-api",
"//kotlin/compiler:symbol-processing-cmdline",
@@ -44,6 +45,7 @@ kt_bootstrap_binary(
"-D@rules_kotlin...compiler=$(rlocationpath //src/main/kotlin/io/bazel/kotlin/compiler:compiler.jar)",
"-D@com_github_google_ksp...symbol-processing-api=$(rlocationpath //kotlin/compiler:symbol-processing-api)",
"-D@com_github_google_ksp...symbol-processing-cmdline=$(rlocationpath //kotlin/compiler:symbol-processing-cmdline)",
+ "-D@com_github_jetbrains_kotlin_native...kotlin-native=$(rlocationpath //kotlin/compiler:kotlin-native)",
"-D@rules_kotlin..kotlin.compiler.kotlin-reflect=$(rlocationpath //kotlin/compiler:kotlin-reflect)",
"-XX:-MaxFDLimit",
],
diff --git a/src/main/kotlin/io/bazel/kotlin/builder/tasks/KotlinBuilder.kt b/src/main/kotlin/io/bazel/kotlin/builder/tasks/KotlinBuilder.kt
index e4ab30c5d..5dddf20a1 100644
--- a/src/main/kotlin/io/bazel/kotlin/builder/tasks/KotlinBuilder.kt
+++ b/src/main/kotlin/io/bazel/kotlin/builder/tasks/KotlinBuilder.kt
@@ -17,6 +17,7 @@
package io.bazel.kotlin.builder.tasks
import io.bazel.kotlin.builder.tasks.jvm.KotlinJvmTaskExecutor
+import io.bazel.kotlin.builder.tasks.knative.KotlinNativeTaskExecutor
import io.bazel.kotlin.builder.toolchain.CompilationStatusException
import io.bazel.kotlin.builder.toolchain.CompilationTaskContext
import io.bazel.kotlin.builder.utils.ArgMap
@@ -26,6 +27,7 @@ import io.bazel.kotlin.builder.utils.partitionJvmSources
import io.bazel.kotlin.builder.utils.resolveNewDirectories
import io.bazel.kotlin.model.CompilationTaskInfo
import io.bazel.kotlin.model.JvmCompilationTask
+import io.bazel.kotlin.model.KotlinNativeCompilationTask
import io.bazel.kotlin.model.Platform
import io.bazel.kotlin.model.RuleKind
import io.bazel.worker.WorkerContext
@@ -43,6 +45,7 @@ class KotlinBuilder
@Inject
internal constructor(
private val jvmTaskExecutor: KotlinJvmTaskExecutor,
+ private val nativeTaskExecutor: KotlinNativeTaskExecutor,
) {
companion object {
@JvmStatic
@@ -89,6 +92,10 @@ class KotlinBuilder
INSTRUMENT_COVERAGE("--instrument_coverage"),
KSP_GENERATED_JAVA_SRCJAR("--ksp_generated_java_srcjar"),
BUILD_TOOLS_API("--build_tools_api"),
+ KLIBS("--klibs"),
+ OUTPUT_KLIB("--output_klib"),
+ KONAN_HOME("--konan_home"),
+ KOTLIN_NATIVE_TARGET("--kotlin_native_target"),
}
}
@@ -105,6 +112,12 @@ class KotlinBuilder
Platform.JVM,
Platform.ANDROID,
-> executeJvmTask(compileContext, taskContext.directory, argMap)
+ Platform.NATIVE_LIBRARY ->
+ executeKotlinNativeTask(
+ compileContext,
+ taskContext.directory,
+ argMap,
+ )
Platform.UNRECOGNIZED -> throw IllegalStateException(
"unrecognized platform: ${compileContext.info}",
)
@@ -146,8 +159,13 @@ class KotlinBuilder
argMap.mandatorySingle(KotlinBuilderFlags.RULE_KIND).also {
val splitRuleKind = it.split("_")
require(splitRuleKind[0] == "kt") { "Invalid rule kind $it" }
- platform = Platform.valueOf(splitRuleKind[1].uppercase())
ruleKind = RuleKind.valueOf(splitRuleKind.last().uppercase())
+ platform =
+ when (it) {
+ // kt_library is a special case
+ "kt_library" -> Platform.NATIVE_LIBRARY
+ else -> Platform.valueOf(splitRuleKind[1].uppercase())
+ }
}
moduleName =
argMap.mandatorySingle(KotlinBuilderFlags.MODULE_NAME).also {
@@ -189,6 +207,47 @@ class KotlinBuilder
jvmTaskExecutor.execute(context, task)
}
+ private fun executeKotlinNativeTask(
+ context: CompilationTaskContext,
+ workingDir: Path,
+ argMap: ArgMap,
+ ) {
+ val task = buildKotlinNativeTask(context.info, workingDir, argMap)
+ context.whenTracing { printProto("kotlin native compile task input", task) }
+ nativeTaskExecutor.execute(context, task)
+ }
+
+ private fun buildKotlinNativeTask(
+ info: CompilationTaskInfo,
+ workingDir: Path,
+ argMap: ArgMap,
+ ): KotlinNativeCompilationTask =
+ with(KotlinNativeCompilationTask.newBuilder()) {
+ this.info = info
+ with(directoriesBuilder) {
+ temp = workingDir.toString()
+ }
+
+ with(infoBuilder.toolchainInfoBuilder.nativeBuilder) {
+ this.setKonanHome(argMap.mandatorySingle(KotlinBuilderFlags.KONAN_HOME))
+ this.setKotlinNativeTarget(
+ argMap.mandatorySingle(KotlinBuilderFlags.KOTLIN_NATIVE_TARGET),
+ )
+ }
+
+ with(inputsBuilder) {
+ argMap.optional(KotlinBuilderFlags.KLIBS)?.let {
+ addAllLibraries(it)
+ }
+ addAllKotlinSources(argMap.mandatory(KotlinBuilderFlags.SOURCES))
+ }
+
+ with(outputsBuilder) {
+ this.setKlib(argMap.mandatorySingle(KotlinBuilderFlags.OUTPUT_KLIB))
+ }
+ build()
+ }
+
private fun buildJvmTask(
info: CompilationTaskInfo,
workingDir: Path,
diff --git a/src/main/kotlin/io/bazel/kotlin/builder/tasks/knative/KotlinNativeTaskExecutor.kt b/src/main/kotlin/io/bazel/kotlin/builder/tasks/knative/KotlinNativeTaskExecutor.kt
new file mode 100644
index 000000000..af3a20d64
--- /dev/null
+++ b/src/main/kotlin/io/bazel/kotlin/builder/tasks/knative/KotlinNativeTaskExecutor.kt
@@ -0,0 +1,101 @@
+package io.bazel.kotlin.builder.tasks.knative
+
+import io.bazel.kotlin.builder.toolchain.CompilationTaskContext
+import io.bazel.kotlin.builder.toolchain.KotlinToolchain
+import io.bazel.kotlin.builder.utils.addAll
+import io.bazel.kotlin.model.KotlinNativeCompilationTask
+import java.nio.file.FileSystem
+import java.nio.file.FileSystems
+import java.nio.file.Files
+import java.nio.file.Path
+import java.nio.file.Paths
+import java.util.stream.Collectors
+import javax.inject.Inject
+import javax.inject.Singleton
+import kotlin.io.path.absolutePathString
+import kotlin.io.path.exists
+import kotlin.io.path.pathString
+
+@Singleton
+class KotlinNativeTaskExecutor
+ @Inject
+ constructor(
+ private val invoker: KotlinToolchain.K2NativeCompilerInvoker,
+ ) {
+ private val fileSystem: FileSystem = FileSystems.getDefault()
+
+ fun execute(
+ context: CompilationTaskContext,
+ task: KotlinNativeCompilationTask,
+ ) {
+ task.compile(context)
+ }
+
+ private fun KotlinNativeCompilationTask.workingDirectory(): Path =
+ fileSystem.getPath(directories.temp)
+
+ private fun KotlinNativeCompilationTask.commonArgs(): MutableList {
+ val workDir = workingDirectory()
+ if (!workDir.exists()) {
+ workDir.toFile().mkdirs()
+ }
+
+ val konanHome = this.info.toolchainInfo.native.konanHome
+ if (!Paths.get(konanHome).exists()) {
+ throw IllegalArgumentException("$konanHome doesn't point to konan.home or doesn't exist.")
+ }
+
+ System.setProperty("konan.home", konanHome)
+
+ val autoCacheDirectory = workingDirectory().resolve("native_auto_cache")
+ if (!autoCacheDirectory.exists()) {
+ autoCacheDirectory.toFile().mkdirs()
+ }
+
+ val autoCacheFromDirectory = workingDirectory().resolve("native_auto_from")
+ if (!autoCacheFromDirectory.exists()) {
+ autoCacheFromDirectory.toFile().mkdirs()
+ }
+
+ val execRoot = fileSystem.getPath(".")
+ return mutableListOf().apply {
+ addAll(passThroughFlagsList)
+ add("-Xklib-normalize-absolute-path")
+ // Avoid downloading any dependencies during the build
+ add("-Xoverride-konan-properties=airplaneMode=true")
+ add("-nostdlib")
+
+ // the target for which we should compile libaries/binaries to
+ add("-target=${info.toolchainInfo.native.kotlinNativeTarget}")
+
+ // Map paths in debug symbols to relative paths to execroot
+ add("-Xdebug-prefix-map=" + execRoot + "=.")
+ // Use relative paths in klibs
+ add("-Xklib-relative-path-base=" + execRoot)
+ addAll("-module-name=${info.moduleName}")
+ addAll(inputs.kotlinSourcesList.map { execRoot.resolve(it).absolutePathString() })
+ }
+ }
+
+ private fun KotlinNativeCompilationTask.compile(context: CompilationTaskContext) {
+ val args = commonArgs()
+ val klibOut = fileSystem.getPath(outputs.klib)
+ inputs.librariesList.forEach { library ->
+ args.addAll("-library=$library")
+ }
+ args.addAll("-produce", "library")
+ args.addAll("-o", klibOut.pathString.substringBeforeLast('.'))
+ context.whenTracing { printLines("klib compile args", args) }
+
+ val outputDirectory = klibOut.parent
+ Files.createDirectories(outputDirectory)
+
+ context.executeCompilerTask(args, invoker::compile)
+ context.whenTracing {
+ printLines(
+ "outputs",
+ Files.walk(outputDirectory).map { p -> p.toString() }.collect(Collectors.toList()),
+ )
+ }
+ }
+ }
diff --git a/src/main/kotlin/io/bazel/kotlin/builder/toolchain/KotlinToolchain.kt b/src/main/kotlin/io/bazel/kotlin/builder/toolchain/KotlinToolchain.kt
index d5ed414cf..e07a96f5b 100644
--- a/src/main/kotlin/io/bazel/kotlin/builder/toolchain/KotlinToolchain.kt
+++ b/src/main/kotlin/io/bazel/kotlin/builder/toolchain/KotlinToolchain.kt
@@ -83,6 +83,13 @@ class KotlinToolchain private constructor(
).toPath()
}
+ private val KOTLIN_NATIVE by lazy {
+ BazelRunFiles
+ .resolveVerifiedFromProperty(
+ "@com_github_jetbrains_kotlin_native...kotlin-native",
+ ).toPath()
+ }
+
private val KSP_SYMBOL_PROCESSING_API by lazy {
BazelRunFiles
.resolveVerifiedFromProperty(
@@ -150,6 +157,7 @@ class KotlinToolchain private constructor(
createToolchain(
JAVA_HOME,
KOTLINC.verified().absoluteFile,
+ KOTLIN_NATIVE.verified().absoluteFile,
COMPILER.verified().absoluteFile,
BUILD_TOOLS_API.verified().absoluteFile,
JVM_ABI_PLUGIN.verified().absoluteFile,
@@ -167,6 +175,7 @@ class KotlinToolchain private constructor(
fun createToolchain(
javaHome: Path,
kotlinc: File,
+ kotlinNative: File,
buildTools: File,
compiler: File,
jvmAbiGenFile: File,
@@ -182,6 +191,7 @@ class KotlinToolchain private constructor(
KotlinToolchain(
listOf(
kotlinc,
+ kotlinNative,
compiler,
buildTools,
// plugins *must* be preloaded. Not doing so causes class conflicts
@@ -321,4 +331,14 @@ class KotlinToolchain private constructor(
return KotlincInvoker(toolchain = toolchain, clazz = clazz)
}
}
+
+ @Singleton
+ class K2NativeCompilerInvoker
+ @Inject
+ constructor(
+ toolchain: KotlinToolchain,
+ ) : KotlincInvoker(
+ toolchain,
+ "io.bazel.kotlin.compiler.BazelK2NativeCompiler",
+ )
}
diff --git a/src/main/kotlin/io/bazel/kotlin/compiler/BazelK2NativeCompiler.kt b/src/main/kotlin/io/bazel/kotlin/compiler/BazelK2NativeCompiler.kt
new file mode 100644
index 000000000..aabc0bd83
--- /dev/null
+++ b/src/main/kotlin/io/bazel/kotlin/compiler/BazelK2NativeCompiler.kt
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+package io.bazel.kotlin.compiler
+
+import org.jetbrains.kotlin.cli.bc.K2Native
+import org.jetbrains.kotlin.cli.common.ExitCode
+import org.jetbrains.kotlin.cli.common.messages.MessageRenderer
+import org.jetbrains.kotlin.cli.common.messages.PrintingMessageCollector
+import org.jetbrains.kotlin.config.Services
+
+@Suppress("unused")
+class BazelK2NativeCompiler {
+ fun exec(
+ errStream: java.io.PrintStream,
+ vararg args: String,
+ ): ExitCode {
+ System.setProperty("zip.handler.uses.crc.instead.of.timestamp", "true")
+ val delegate = K2Native()
+ val arguments = delegate.createArguments().also { delegate.parseArguments(args, it) }
+ val collector =
+ PrintingMessageCollector(errStream, MessageRenderer.PLAIN_RELATIVE_PATHS, arguments.verbose)
+ return delegate.exec(collector, Services.EMPTY, arguments)
+ }
+}
diff --git a/src/main/protobuf/kotlin_model.proto b/src/main/protobuf/kotlin_model.proto
index cfae8edcc..ea6485747 100644
--- a/src/main/protobuf/kotlin_model.proto
+++ b/src/main/protobuf/kotlin_model.proto
@@ -41,8 +41,17 @@ message KotlinToolchainInfo {
string jvm_target = 1;
}
+ // Properties specific to the native compiler
+ message Native {
+ // The path to the konan directory in the distribution
+ string konan_home = 1;
+ // The kotlin native target for which to produce libraries/binaries
+ string kotlin_native_target = 2;
+ }
+
Common common = 1;
Jvm jvm = 2;
+ Native native = 3;
}
enum RuleKind {
@@ -55,6 +64,7 @@ enum RuleKind {
enum Platform {
JVM = 0;
ANDROID = 1;
+ NATIVE_LIBRARY = 3;
}
// Common info about a Kotlin compilation task, this message is shared by all compilation tasks.
@@ -175,3 +185,34 @@ message JvmCompilationTask {
bool compile_kotlin = 6;
bool instrument_coverage = 7;
}
+
+
+message KotlinNativeCompilationTask {
+ // Directories used by the builder.
+ message Directories {
+ // A temp directory that the compiler may use.
+ string temp = 4;
+ // Path to the konan distribution directory of the native compiler
+ string konan_home = 5;
+ }
+
+ message Outputs {
+ string klib = 1;
+ }
+
+ message Inputs {
+ // other klibs required for compilation
+ repeated string libraries = 1;
+ // One or more source files
+ repeated string kotlin_sources = 2;
+ }
+
+ CompilationTaskInfo info = 1;
+ Outputs outputs = 3;
+ Inputs inputs = 4;
+
+ // flags that should be passed through straight to the kotlin native compiler.
+ repeated string pass_through_flags = 5;
+
+ Directories directories = 6;
+}
\ No newline at end of file
diff --git a/src/main/starlark/core/compile/BUILD.bazel b/src/main/starlark/core/compile/BUILD.bazel
index 6164469ff..273788046 100644
--- a/src/main/starlark/core/compile/BUILD.bazel
+++ b/src/main/starlark/core/compile/BUILD.bazel
@@ -8,6 +8,13 @@ toolchain_type(
],
)
+toolchain_type(
+ name = "native_toolchain_type",
+ visibility = [
+ "//visibility:public",
+ ],
+)
+
bzl_library(
name = "compile",
srcs = [
diff --git a/src/main/starlark/core/compile/cli/BUILD.bazel b/src/main/starlark/core/compile/cli/BUILD.bazel
index 46ed8b78b..b401255d6 100644
--- a/src/main/starlark/core/compile/cli/BUILD.bazel
+++ b/src/main/starlark/core/compile/cli/BUILD.bazel
@@ -3,6 +3,7 @@ load("@rules_java//java:java_import.bzl", "java_import")
load("//kotlin/compiler:compiler.bzl", _KOTLIN_STDLIBS = "KOTLIN_STDLIBS")
load("//src/main/starlark/core/compile:common.bzl", "TYPE")
load("//src/main/starlark/core/repositories:versions.bzl", "versions")
+load(":native.bzl", "define_native_cli_toolchains")
load(":toolchain.bzl", "cli_toolchain")
java_import(
@@ -35,3 +36,5 @@ toolchain(
toolchain = ":cli_toolchain",
toolchain_type = TYPE,
)
+
+define_native_cli_toolchains()
diff --git a/src/main/starlark/core/compile/cli/native.bzl b/src/main/starlark/core/compile/cli/native.bzl
new file mode 100644
index 000000000..32f24e8ad
--- /dev/null
+++ b/src/main/starlark/core/compile/cli/native.bzl
@@ -0,0 +1,73 @@
+load("@rules_java//java/common:java_info.bzl", "JavaInfo")
+load("//kotlin/internal:defs.bzl", "KT_NATIVE_COMPILER_REPO_PREFIX", "KtJvmInfo")
+load("//src/main/starlark/core/compile:common.bzl", "NATIVE_TYPE")
+load("//src/main/starlark/core/repositories/kotlin:artifacts.bzl", "KOTLIN_NATIVE_TARGETS")
+
+KotlinNativeCompileInfo = provider(
+ doc = "Provies the necessary info about the Kotlin native CLI toolchain",
+ fields = {
+ "native_java_infos": "A list of JavaInfo objects that represent the kotlin-native CLI toolchain",
+ "jvm_flags": "A list of JVM flags to be used with kotlinc-native CLI toolchain",
+ },
+)
+
+def _kotlin_native_cli_toolchain_impl(ctx):
+ native_java_infos = [j[JavaInfo] for j in ctx.attr.native_jars]
+ return [
+ platform_common.ToolchainInfo(
+ kotlin_native_compile_info = KotlinNativeCompileInfo(
+ native_java_infos = native_java_infos,
+ jvm_flags = ctx.attr.jvm_flags,
+ ),
+ ),
+ ]
+
+kotlin_native_cli_toolchain = rule(
+ implementation = _kotlin_native_cli_toolchain_impl,
+ attrs = {
+ "native_jars": attr.label_list(
+ doc = "One ore more jars that are required to run the kotlinc-native CLI",
+ providers = [KtJvmInfo],
+ ),
+ "jvm_flags": attr.string_list(
+ doc = "A list of JVM flags to be used in binaries to use the kotlinc-native CLI toolchain",
+ default = [],
+ ),
+ },
+)
+
+def define_native_cli_toolchains():
+ for exec_platform, targets in KOTLIN_NATIVE_TARGETS.items():
+ exec_compatible_with = targets.exec_compatible_with
+
+ for target_constraint_tuple in targets.targets.keys():
+ target_os, target_cpu = target_constraint_tuple
+
+ # Create a unique name for this toolchain
+ toolchain_suffix = "{}_to_{}_{}".format(
+ exec_platform,
+ Label(target_os).name,
+ Label(target_cpu).name,
+ )
+ toolchain_name = "default_kt_native_toolchain_{}".format(toolchain_suffix)
+ toolchain_impl = "default_kt_native_{}".format(toolchain_suffix)
+
+ kotlin_native = Label("@" + KT_NATIVE_COMPILER_REPO_PREFIX + "_" + exec_platform + "//:kotlin-native")
+
+ # Create the toolchain implementation
+ kotlin_native_cli_toolchain(
+ name = toolchain_impl,
+ native_jars = [
+ kotlin_native,
+ "@" + KT_NATIVE_COMPILER_REPO_PREFIX + "_" + exec_platform + "//:trove4j",
+ ],
+ )
+
+ # Register the toolchain
+ native.toolchain(
+ name = toolchain_name,
+ exec_compatible_with = exec_compatible_with,
+ target_compatible_with = [target_os, target_cpu],
+ toolchain = ":" + toolchain_impl,
+ toolchain_type = NATIVE_TYPE,
+ )
diff --git a/src/main/starlark/core/compile/common.bzl b/src/main/starlark/core/compile/common.bzl
index 7b892e496..7e03caf4f 100644
--- a/src/main/starlark/core/compile/common.bzl
+++ b/src/main/starlark/core/compile/common.bzl
@@ -1,4 +1,5 @@
TYPE = "//src/main/starlark/core/compile:toolchain_type"
+NATIVE_TYPE = "//src/main/starlark/core/compile:native_toolchain_type"
# Java toolchains
JAVA_TOOLCHAIN_TYPE = Label("@bazel_tools//tools/jdk:toolchain_type")
@@ -19,3 +20,11 @@ KtJvmInfo = provider(
"all_output_jars": "Returns all the output Jars produced by this rule. [bazel-bsp-aspect]",
},
)
+
+KtKlibInfo = provider(
+ fields = {
+ "module_name": "the module_name",
+ "klibs": "the klibs provided by the output of compilation",
+ "transitive_klibs": "Returns the transitive set of klibs required to build the target",
+ },
+)
diff --git a/src/main/starlark/core/compile/rules.bzl b/src/main/starlark/core/compile/rules.bzl
index 668ee7778..2c92733f3 100644
--- a/src/main/starlark/core/compile/rules.bzl
+++ b/src/main/starlark/core/compile/rules.bzl
@@ -1,5 +1,5 @@
load("@rules_java//java:defs.bzl", "JavaInfo")
-load(":common.bzl", "KtJvmInfo", "TYPE")
+load(":common.bzl", "KtJvmInfo", "NATIVE_TYPE", "TYPE")
_COMMON_ATTRS = {
"srcs": attr.label_list(
@@ -59,6 +59,9 @@ _COMMON_ATTRS = {
def _kt_jvm_library_impl(ctx):
kt_tools = ctx.toolchains[TYPE]
+ native_toolchain = ctx.toolchains[NATIVE_TYPE]
+ native_java_infos = native_toolchain.kotlin_native_compile_info.native_java_infos
+
class_jar = ctx.outputs.class_jar
source_jar = ctx.outputs.source_jar
java_info_deps = [d[JavaInfo] for d in ctx.attr.deps if JavaInfo in d]
@@ -66,7 +69,7 @@ def _kt_jvm_library_impl(ctx):
kt_tools.compile(
actions = ctx.actions,
srcs = ctx.files.srcs,
- dep_jars = depset(transitive = [j.compile_jars for j in java_info_deps]),
+ dep_jars = depset(transitive = [j.compile_jars for j in java_info_deps] + [j.compile_jars for j in native_java_infos]),
class_jar = class_jar,
output_srcjar = source_jar,
module_name = module_name,
@@ -121,6 +124,7 @@ _kt_jvm_library = rule(
attrs = _COMMON_ATTRS,
toolchains = [
TYPE,
+ NATIVE_TYPE,
],
provides = [JavaInfo, KtJvmInfo],
)
@@ -135,10 +139,13 @@ def core_kt_jvm_library(name, **kwargs):
def _kt_jvm_binary_impl(ctx):
kt_tools = ctx.toolchains[TYPE]
+ native_toolchain = ctx.toolchains[NATIVE_TYPE]
+ native_java_infos = native_toolchain.kotlin_native_compile_info.native_java_infos
+ native_jvm_flags = native_toolchain.kotlin_native_compile_info.jvm_flags
providers = _kt_jvm_library_impl(ctx)
java_info_deps = [d[JavaInfo] for d in ctx.attr.deps if JavaInfo in d]
- runtime_jars = depset([ctx.outputs.class_jar], transitive = [j.transitive_runtime_jars for j in java_info_deps])
+ runtime_jars = depset([ctx.outputs.class_jar], transitive = [j.transitive_runtime_jars for j in java_info_deps] + [j.transitive_runtime_jars for j in native_java_infos])
executable = ctx.outputs.executable
launch_runfiles = kt_tools.launch(
@@ -147,7 +154,7 @@ def _kt_jvm_binary_impl(ctx):
actions = ctx.actions,
path_separator = ctx.configuration.host_path_separator,
workspace_prefix = ctx.workspace_name + "/",
- jvm_flags = " ".join([ctx.expand_location(f, ctx.attr.data) for f in ctx.attr.jvm_flags]),
+ jvm_flags = " ".join([ctx.expand_location(f, ctx.attr.data) for f in ctx.attr.jvm_flags + native_jvm_flags]),
runtime_jars = runtime_jars,
)
@@ -185,6 +192,7 @@ _kt_jvm_binary = rule(
},
toolchains = [
TYPE,
+ NATIVE_TYPE,
],
executable = True,
)
diff --git a/src/main/starlark/core/repositories/BUILD b/src/main/starlark/core/repositories/BUILD
index 869f9e74d..550ebae31 100644
--- a/src/main/starlark/core/repositories/BUILD
+++ b/src/main/starlark/core/repositories/BUILD
@@ -19,10 +19,14 @@ release_archive(
srcs = [
"BUILD.com_github_google_ksp.bazel",
"BUILD.com_github_jetbrains_kotlin.bazel",
+ "BUILD.com_github_jetbrains_kotlin_native.bazel",
+ "BUILD.kotlin-native_capabilities.bazel",
"BUILD.kotlin_capabilities.bazel",
"bzlmod_impl.bzl",
+ "capabilities.bzl",
"compiler.bzl",
"ksp.bzl",
+ "native.bzl",
"versions.bzl",
],
src_map = {
diff --git a/src/main/starlark/core/repositories/BUILD.com_github_jetbrains_kotlin_native.bazel b/src/main/starlark/core/repositories/BUILD.com_github_jetbrains_kotlin_native.bazel
new file mode 100644
index 000000000..e04b88613
--- /dev/null
+++ b/src/main/starlark/core/repositories/BUILD.com_github_jetbrains_kotlin_native.bazel
@@ -0,0 +1,63 @@
+# Copyright 2025 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.
+load("@bazel_skylib//rules/directory:directory.bzl", "directory")
+load("@rules_kotlin//kotlin/internal/jvm:jvm.bzl", "kt_jvm_import")
+
+package(default_visibility = ["//visibility:public"])
+
+filegroup(
+ name = "bin",
+ srcs = glob(["bin/**"]),
+)
+
+directory(
+ name = "konan_home",
+ srcs = glob([
+ "konan/**",
+ "klib/**",
+ ]),
+)
+
+filegroup(
+ name = "konan_properties",
+ srcs = ["konan/konan.properties"],
+)
+
+filegroup(
+ name = "stdlib",
+ srcs = glob(["klib/common/stdlib/**"]),
+)
+
+# Have a filegroup for the kotlin-native jars that will be explicitly aliased
+[
+ filegroup(
+ name = name.replace(".", "_"),
+ srcs = glob(["" + name]),
+ )
+ for name in glob(["konan/lib/**"])
+]
+
+kt_jvm_import(
+ name = "kotlin-native",
+ jars = [
+ "konan/lib/kotlin-native.jar",
+ ],
+)
+
+kt_jvm_import(
+ name = "trove4j",
+ jars = [
+ "konan/lib/trove4j.jar",
+ ],
+)
diff --git a/src/main/starlark/core/repositories/BUILD.kotlin-native_capabilities.bazel b/src/main/starlark/core/repositories/BUILD.kotlin-native_capabilities.bazel
new file mode 100644
index 000000000..5c4c0d026
--- /dev/null
+++ b/src/main/starlark/core/repositories/BUILD.kotlin-native_capabilities.bazel
@@ -0,0 +1,41 @@
+# Copyright 2025 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.
+load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
+
+package(default_visibility = ["//visibility:public"])
+
+bzl_library(
+ name = "capabilities",
+ srcs = glob(["*.bzl"]),
+)
+
+alias(
+ name = "konan_home",
+ actual = "@$git_repo$//:konan_home",
+)
+
+alias(
+ name = "konan_properties",
+ actual = "@$git_repo$//:konan_properties",
+)
+
+alias(
+ name = "kotlin-native",
+ actual = "@$git_repo$//:kotlin-native",
+)
+
+alias(
+ name = "trove4j",
+ actual = "@$git_repo$//:trove4j",
+)
diff --git a/src/main/starlark/core/repositories/capabilities.bzl b/src/main/starlark/core/repositories/capabilities.bzl
new file mode 100644
index 000000000..4346fee81
--- /dev/null
+++ b/src/main/starlark/core/repositories/capabilities.bzl
@@ -0,0 +1,98 @@
+load("//src/main/starlark/core/repositories/kotlin:templates.bzl", "TEMPLATES")
+
+def _kotlin_capabilities_impl(repository_ctx):
+ """Creates the kotlinc or kotlin-native repository."""
+ attr = repository_ctx.attr
+ repository_ctx.file(
+ "WORKSPACE",
+ content = """workspace(name = "%s")""" % attr.name,
+ )
+ repository_ctx.template(
+ "BUILD.bazel",
+ attr.template,
+ executable = False,
+ substitutions = {
+ "$git_repo$": attr.git_repository_name,
+ },
+ )
+ repository_ctx.template(
+ "artifacts.bzl",
+ attr._artifacts_template,
+ executable = False,
+ )
+ template = _get_capability_template(
+ attr.compiler_version,
+ [repository_ctx.path(ct) for ct in attr._capability_templates],
+ )
+ repository_ctx.template(
+ "capabilities.bzl",
+ template,
+ executable = False,
+ )
+
+def _coerce_int(string_value):
+ digits = "".join([
+ string_value[i]
+ for i in range(len(string_value))
+ if string_value[i].isdigit()
+ ])
+ return 0 if not digits else int(digits)
+
+def _version(version_string):
+ return tuple([
+ _coerce_int(segment)
+ for segment in version_string.split(".", 3)
+ ])
+
+def _parse_version(basename):
+ if "capabilities" not in basename:
+ return None
+ version_string = basename[len("capabilities_"):basename.find(".bzl")]
+ return _version(version_string)
+
+def _get_capability_template(compiler_version, templates):
+ version_index = {}
+ target = _version(compiler_version)
+ if len(target) > 2:
+ target = target[0:2]
+ for template in templates:
+ version = _parse_version(template.basename)
+ if not version:
+ continue
+
+ if target == version:
+ return template
+ version_index[version] = template
+
+ last_version = sorted(version_index.keys(), reverse = True)[0]
+
+ # After latest version, chosen by major revision
+ if target[0] >= last_version[0]:
+ return version_index[last_version]
+
+ # Legacy
+ return version_index[(0, 0, 0)]
+
+kotlin_capabilities_repository = repository_rule(
+ implementation = _kotlin_capabilities_impl,
+ attrs = {
+ "git_repository_name": attr.string(
+ doc = "Name of the repository containing kotlin compiler libraries",
+ ),
+ "compiler_version": attr.string(
+ doc = "compiler version",
+ ),
+ "_capability_templates": attr.label_list(
+ doc = "List of compiler capability templates.",
+ default = TEMPLATES,
+ ),
+ "template": attr.label(
+ doc = "repository build file template",
+ default = ":BUILD.kotlin_capabilities.bazel",
+ ),
+ "_artifacts_template": attr.label(
+ doc = "kotlinc artifacts template",
+ default = "//src/main/starlark/core/repositories/kotlin:artifacts.bzl",
+ ),
+ },
+)
diff --git a/src/main/starlark/core/repositories/compiler.bzl b/src/main/starlark/core/repositories/compiler.bzl
index ac45b3147..640cfde78 100644
--- a/src/main/starlark/core/repositories/compiler.bzl
+++ b/src/main/starlark/core/repositories/compiler.bzl
@@ -2,7 +2,7 @@
Defines kotlin compiler repositories.
"""
-load("//src/main/starlark/core/repositories/kotlin:templates.bzl", "TEMPLATES")
+load(":capabilities.bzl", "kotlin_capabilities_repository")
def _kotlin_compiler_impl(repository_ctx):
attr = repository_ctx.attr
@@ -17,103 +17,6 @@ def _kotlin_compiler_impl(repository_ctx):
executable = False,
)
-def _kotlin_capabilities_impl(repository_ctx):
- """Creates the kotlinc repository."""
- attr = repository_ctx.attr
- repository_ctx.file(
- "WORKSPACE",
- content = """workspace(name = "%s")""" % attr.name,
- )
- repository_ctx.template(
- "BUILD.bazel",
- attr._template,
- executable = False,
- substitutions = {
- "$git_repo$": attr.git_repository_name,
- },
- )
- repository_ctx.template(
- "artifacts.bzl",
- attr._artifacts_template,
- executable = False,
- )
- template = _get_capability_template(
- attr.compiler_version,
- [repository_ctx.path(ct) for ct in attr._capability_templates],
- )
- repository_ctx.template(
- "capabilities.bzl",
- template,
- executable = False,
- )
-
-def _coerce_int(string_value):
- digits = "".join([
- string_value[i]
- for i in range(len(string_value))
- if string_value[i].isdigit()
- ])
- return 0 if not digits else int(digits)
-
-def _version(version_string):
- return tuple([
- _coerce_int(segment)
- for segment in version_string.split(".", 3)
- ])
-
-def _parse_version(basename):
- if "capabilities" not in basename:
- return None
- version_string = basename[len("capabilities_"):basename.find(".bzl")]
- return _version(version_string)
-
-def _get_capability_template(compiler_version, templates):
- version_index = {}
- target = _version(compiler_version)
- if len(target) > 2:
- target = target[0:2]
- for template in templates:
- version = _parse_version(template.basename)
- if not version:
- continue
-
- if target == version:
- return template
- version_index[version] = template
-
- last_version = sorted(version_index.keys(), reverse = True)[0]
-
- # After latest version, chosen by major revision
- if target[0] >= last_version[0]:
- return version_index[last_version]
-
- # Legacy
- return version_index[(0, 0, 0)]
-
-kotlin_capabilities_repository = repository_rule(
- implementation = _kotlin_capabilities_impl,
- attrs = {
- "git_repository_name": attr.string(
- doc = "Name of the repository containing kotlin compiler libraries",
- ),
- "compiler_version": attr.string(
- doc = "compiler version",
- ),
- "_capability_templates": attr.label_list(
- doc = "List of compiler capability templates.",
- default = TEMPLATES,
- ),
- "_template": attr.label(
- doc = "repository build file template",
- default = ":BUILD.kotlin_capabilities.bazel",
- ),
- "_artifacts_template": attr.label(
- doc = "kotlinc artifacts template",
- default = "//src/main/starlark/core/repositories/kotlin:artifacts.bzl",
- ),
- },
-)
-
kotlin_compiler_git_repository = repository_rule(
implementation = _kotlin_compiler_impl,
attrs = {
diff --git a/src/main/starlark/core/repositories/initialize.bzl b/src/main/starlark/core/repositories/initialize.bzl
index 81d298bad..a83fabacd 100644
--- a/src/main/starlark/core/repositories/initialize.bzl
+++ b/src/main/starlark/core/repositories/initialize.bzl
@@ -31,12 +31,20 @@ ksp_version = _ksp_version
def kotlin_repositories(
is_bzlmod = False,
compiler_release = versions.KOTLIN_CURRENT_COMPILER_RELEASE,
- ksp_compiler_release = versions.KSP_CURRENT_COMPILER_PLUGIN_RELEASE):
+ ksp_compiler_release = versions.KSP_CURRENT_COMPILER_PLUGIN_RELEASE,
+ kotlin_native_release_linux_x86_64 = versions.KOTLIN_NATIVE_CURRENT_RELEASE_LINUX_X86_64,
+ kotlin_native_release_macos_x86_64 = versions.KOTLIN_NATIVE_CURRENT_RELEASE_MACOS_X86_64,
+ kotlin_native_release_macos_aarch64 = versions.KOTLIN_NATIVE_CURRENT_RELEASE_MACOS_AARCH64,
+ kotlin_native_release_windows_x86_64 = versions.KOTLIN_NATIVE_CURRENT_RELEASE_WINDOWS_X86_64):
"""Call this in the WORKSPACE file to setup the Kotlin rules.
Args:
compiler_release: (internal) version provider from versions.bzl.
ksp_compiler_release: (internal) version provider from versions.bzl.
+ kotlin_native_release_linux_x86_64: (internal) version provider from versions.bzl
+ kotlin_native_release_macos_x86_64: (internal) version provider from versions.bzl
+ kotlin_native_release_macos_aarch_64: (internal) version provider from versions.bzl
+ kotlin_native_release_windows_x86_64: (internal) version provider from versions.bzl
"""
- _release_kotlin_repositories(is_bzlmod = is_bzlmod, compiler_release = compiler_release, ksp_compiler_release = ksp_compiler_release)
+ _release_kotlin_repositories(is_bzlmod = is_bzlmod, compiler_release = compiler_release, ksp_compiler_release = ksp_compiler_release, kotlin_native_release_linux_x86_64 = kotlin_native_release_linux_x86_64, kotlin_native_release_macos_x86_64 = kotlin_native_release_macos_x86_64, kotlin_native_release_windows_x86_64 = kotlin_native_release_windows_x86_64, kotlin_native_release_macos_aarch64 = kotlin_native_release_macos_aarch64)
kt_configure()
diff --git a/src/main/starlark/core/repositories/initialize.release.bzl b/src/main/starlark/core/repositories/initialize.release.bzl
index f834c95cc..fb183ae56 100644
--- a/src/main/starlark/core/repositories/initialize.release.bzl
+++ b/src/main/starlark/core/repositories/initialize.release.bzl
@@ -25,9 +25,11 @@ load(
"//kotlin/internal:defs.bzl",
_KSP_COMPILER_PLUGIN_REPO = "KSP_COMPILER_PLUGIN_REPO",
_KT_COMPILER_REPO = "KT_COMPILER_REPO",
+ _KT_NATIVE_COMPILER_REPO_PREFIX = "KT_NATIVE_COMPILER_REPO_PREFIX",
)
load(":compiler.bzl", "kotlin_compiler_repository")
load(":ksp.bzl", "ksp_compiler_plugin_repository")
+load(":native.bzl", "kotlin_native_compiler_repository")
load(":versions.bzl", "version", _versions = "versions")
versions = _versions
@@ -39,7 +41,11 @@ def kotlin_repositories(
compiler_repository_name = _KT_COMPILER_REPO,
ksp_repository_name = _KSP_COMPILER_PLUGIN_REPO,
compiler_release = versions.KOTLIN_CURRENT_COMPILER_RELEASE,
- ksp_compiler_release = versions.KSP_CURRENT_COMPILER_PLUGIN_RELEASE):
+ ksp_compiler_release = versions.KSP_CURRENT_COMPILER_PLUGIN_RELEASE,
+ kotlin_native_release_linux_x86_64 = versions.KOTLIN_NATIVE_CURRENT_RELEASE_LINUX_X86_64,
+ kotlin_native_release_macos_x86_64 = versions.KOTLIN_NATIVE_CURRENT_RELEASE_MACOS_X86_64,
+ kotlin_native_release_macos_aarch64 = versions.KOTLIN_NATIVE_CURRENT_RELEASE_MACOS_AARCH64,
+ kotlin_native_release_windows_x86_64 = versions.KOTLIN_NATIVE_CURRENT_RELEASE_WINDOWS_X86_64):
"""Call this in the WORKSPACE file to setup the Kotlin rules.
Args:
@@ -48,6 +54,10 @@ def kotlin_repositories(
configured_repository_name: for the default versioned kt_* rules repository. If None, no versioned repository is
created.
ksp_compiler_release: (internal) version provider from versions.bzl.
+ kotlin_native_release_linux_x86_64: (internal) version provider from versions.bzl
+ kotlin_native_release_macos_x86_64: (internal) version provider from versions.bzl
+ kotlin_native_release_macos_aarch_64: (internal) version provider from versions.bzl
+ kotlin_native_release_windows_x86_64: (internal) version provider from versions.bzl
"""
kotlin_compiler_repository(
@@ -57,6 +67,38 @@ def kotlin_repositories(
compiler_version = compiler_release.version,
)
+ kotlin_native_compiler_repository(
+ name = _KT_NATIVE_COMPILER_REPO_PREFIX + "_linux_x86_64",
+ compiler_version = kotlin_native_release_linux_x86_64.version,
+ urls = [url.format(version = kotlin_native_release_linux_x86_64.version) for url in kotlin_native_release_linux_x86_64.url_templates],
+ sha256 = kotlin_native_release_linux_x86_64.sha256,
+ strip_prefix = kotlin_native_release_linux_x86_64.strip_prefix_template.format(version = kotlin_native_release_linux_x86_64.version),
+ )
+
+ kotlin_native_compiler_repository(
+ name = _KT_NATIVE_COMPILER_REPO_PREFIX + "_macos_x86_64",
+ compiler_version = kotlin_native_release_macos_x86_64.version,
+ urls = [url.format(version = kotlin_native_release_macos_x86_64.version) for url in kotlin_native_release_macos_x86_64.url_templates],
+ sha256 = kotlin_native_release_macos_x86_64.sha256,
+ strip_prefix = kotlin_native_release_macos_x86_64.strip_prefix_template.format(version = kotlin_native_release_macos_x86_64.version),
+ )
+
+ kotlin_native_compiler_repository(
+ name = _KT_NATIVE_COMPILER_REPO_PREFIX + "_macos_aarch64",
+ compiler_version = kotlin_native_release_macos_aarch64.version,
+ urls = [url.format(version = kotlin_native_release_macos_aarch64.version) for url in kotlin_native_release_macos_aarch64.url_templates],
+ sha256 = kotlin_native_release_macos_aarch64.sha256,
+ strip_prefix = kotlin_native_release_macos_aarch64.strip_prefix_template.format(version = kotlin_native_release_macos_aarch64.version),
+ )
+
+ kotlin_native_compiler_repository(
+ name = _KT_NATIVE_COMPILER_REPO_PREFIX + "_windows_x86_64",
+ compiler_version = kotlin_native_release_windows_x86_64.version,
+ urls = [url.format(version = kotlin_native_release_windows_x86_64.version) for url in kotlin_native_release_windows_x86_64.url_templates],
+ sha256 = kotlin_native_release_windows_x86_64.sha256,
+ strip_prefix = kotlin_native_release_windows_x86_64.strip_prefix_template.format(version = kotlin_native_release_windows_x86_64.version),
+ )
+
ksp_compiler_plugin_repository(
name = ksp_repository_name,
urls = [url.format(version = ksp_compiler_release.version) for url in ksp_compiler_release.url_templates],
diff --git a/src/main/starlark/core/repositories/kotlin/artifacts.bzl b/src/main/starlark/core/repositories/kotlin/artifacts.bzl
index a837b1cfa..6c9ba1b8f 100644
--- a/src/main/starlark/core/repositories/kotlin/artifacts.bzl
+++ b/src/main/starlark/core/repositories/kotlin/artifacts.bzl
@@ -70,6 +70,79 @@ KOTLINC_ARTIFACTS = struct(
),
)
+KOTLIN_NATIVE_TARGETS = {
+ "linux_x86_64": struct(
+ exec_compatible_with = ["@platforms//os:linux", "@platforms//cpu:x86_64"],
+ # the targets have been extracted here manually by either running kotlinc-native -list-targets for the relevant distribution
+ # or listing entries under /targets/, and then map Bazel platforms for it so that we can create the relevant toolchains
+ # with the right target_compatible_with
+ targets = {
+ ("@platforms//os:android", "@platforms//cpu:armv7"): ["android_arm32"],
+ ("@platforms//os:android", "@platforms//cpu:arm64"): ["android_arm64"],
+ ("@platforms//os:android", "@platforms//cpu:x86_64"): ["android_x64"],
+ ("@platforms//os:linux", "@platforms//cpu:armv7"): ["linux_arm32_hfp"],
+ ("@platforms//os:linux", "@platforms//cpu:x86_64"): ["linux_x64"],
+ ("@platforms//os:windows", "@platforms//cpu:x86_64"): ["mingw_x64"],
+ },
+ ),
+ "macos_x86_64": struct(
+ exec_compatible_with = ["@platforms//os:macos", "@platforms//cpu:x86_64"],
+ targets = {
+ ("@platforms//os:android", "@platforms//cpu:armv7"): ["android_arm32"],
+ ("@platforms//os:android", "@platforms//cpu:arm64"): ["android_arm64"],
+ ("@platforms//os:android", "@platforms//cpu:x86_64"): ["android_x64"],
+ ("@platforms//os:android", "@platforms//cpu:x86_32"): ["android_x86"],
+ ("@platforms//os:ios", "@platforms//cpu:arm64"): ["ios_arm64", "ios_simulator_arm64"],
+ ("@platforms//os:ios", "@platforms//cpu:x86_64"): ["ios_x64"],
+ ("@platforms//os:linux", "@platforms//cpu:armv7"): ["linux_arm32_hfp"],
+ ("@platforms//os:linux", "@platforms//cpu:arm64"): ["linux_arm64"],
+ ("@platforms//os:linux", "@platforms//cpu:x86_64"): ["linux_x64"],
+ ("@platforms//os:macos", "@platforms//cpu:arm64"): ["macos_arm64"],
+ ("@platforms//os:macos", "@platforms//cpu:x86_64"): ["macos_x64"],
+ ("@platforms//os:windows", "@platforms//cpu:x86_64"): ["mingw_x64"],
+ ("@platforms//os:tvos", "@platforms//cpu:arm64"): ["tvos_arm64", "tvos_simulator_arm64"],
+ ("@platforms//os:tvos", "@platforms//cpu:x86_64"): ["tvos_x64"],
+ ("@platforms//os:watchos", "@platforms//cpu:armv7k"): ["watchos_arm32"],
+ ("@platforms//os:watchos", "@platforms//cpu:arm64"): ["watchos_arm64", "watchos_simulator_arm64"],
+ ("@platforms//os:watchos", "@platforms//cpu:arm64_32"): ["watchos_device_arm64"],
+ ("@platforms//os:watchos", "@platforms//cpu:x86_64"): ["watchos_x64"],
+ },
+ ),
+ "macos_aarch64": struct(
+ exec_compatible_with = ["@platforms//os:macos", "@platforms//cpu:arm64"],
+ targets = {
+ ("@platforms//os:linux", "@platforms//cpu:x86_64"): ["linux_x64"],
+ ("@platforms//os:linux", "@platforms//cpu:arm64"): ["linux_arm64"],
+ ("@platforms//os:windows", "@platforms//cpu:x86_64"): ["mingw_x64"],
+ ("@platforms//os:android", "@platforms//cpu:x86_32"): ["android_x86"],
+ ("@platforms//os:android", "@platforms//cpu:x86_64"): ["android_x64"],
+ ("@platforms//os:android", "@platforms//cpu:armv7"): ["android_arm32"],
+ ("@platforms//os:android", "@platforms//cpu:arm64"): ["android_arm64"],
+ ("@platforms//os:macos", "@platforms//cpu:x86_64"): ["macos_x64"],
+ ("@platforms//os:macos", "@platforms//cpu:arm64"): ["macos_arm64"],
+ ("@platforms//os:ios", "@platforms//cpu:arm64"): ["ios_arm64", "ios_simulator_arm64"],
+ ("@platforms//os:ios", "@platforms//cpu:x86_64"): ["ios_x64"],
+ ("@platforms//os:watchos", "@platforms//cpu:armv7k"): ["watchos_arm32"],
+ ("@platforms//os:watchos", "@platforms//cpu:arm64"): ["watchos_arm64", "watchos_simulator_arm64"],
+ ("@platforms//os:watchos", "@platforms//cpu:arm64_32"): ["watchos_device_arm64"],
+ ("@platforms//os:watchos", "@platforms//cpu:x86_64"): ["watchos_x64"],
+ ("@platforms//os:tvos", "@platforms//cpu:arm64"): ["tvos_arm64", "tvos_simulator_arm64"],
+ ("@platforms//os:tvos", "@platforms//cpu:x86_64"): ["tvos_x64"],
+ },
+ ),
+ "windows_x86_64": struct(
+ exec_compatible_with = ["@platforms//os:windows", "@platforms//cpu:x86_64"],
+ targets = {
+ ("@platforms//os:windows", "@platforms//cpu:x86_64"): ["mingw_x64"],
+ ("@platforms//os:android", "@platforms//cpu:armv7"): ["android_arm32"],
+ ("@platforms//os:android", "@platforms//cpu:arm64"): ["android_arm64"],
+ ("@platforms//os:android", "@platforms//cpu:x86_32"): ["android_x86"],
+ ("@platforms//os:android", "@platforms//cpu:x86_64"): ["android_x64"],
+ ("@platforms//os:linux", "@platforms//cpu:x86_64"): ["linux_64"],
+ },
+ ),
+}
+
KOTLINC_ARTIFACT_LIST = {
label: file
for lang in ["jvm", "core"]
diff --git a/src/main/starlark/core/repositories/native.bzl b/src/main/starlark/core/repositories/native.bzl
new file mode 100644
index 000000000..d04ae22ba
--- /dev/null
+++ b/src/main/starlark/core/repositories/native.bzl
@@ -0,0 +1,52 @@
+load(":capabilities.bzl", "kotlin_capabilities_repository")
+
+_CAPABILITIES_BUILD_TEMPLATE = Label("BUILD.kotlin-native_capabilities.bazel")
+
+def _kotlin_native_compiler_repository_impl(repository_ctx):
+ attr = repository_ctx.attr
+ repository_ctx.download_and_extract(
+ attr.urls,
+ sha256 = attr.sha256,
+ stripPrefix = attr.strip_prefix,
+ )
+ repository_ctx.template(
+ "BUILD.bazel",
+ attr._template,
+ executable = False,
+ )
+
+kotlin_native_compiler_repository_rule = repository_rule(
+ implementation = _kotlin_native_compiler_repository_impl,
+ attrs = {
+ "urls": attr.string_list(
+ mandatory = True,
+ doc = "A list of urls for the kotlin-native compiler",
+ ),
+ "sha256": attr.string(
+ mandatory = True,
+ doc = "the sha256 of the kotlin-native tar/zip for this platform/version.",
+ ),
+ "_template": attr.label(
+ doc = "The build file template for the kotlin-native repository",
+ default = ":BUILD.com_github_jetbrains_kotlin_native.bazel",
+ ),
+ "strip_prefix": attr.string(
+ mandatory = True,
+ doc = "The prefix to be stripped from the extracted kotlin-native compiler archive, and is platform specific",
+ ),
+ },
+)
+
+def kotlin_native_compiler_repository(name, compiler_version, **kwargs):
+ git_repo = name + "_git"
+ kotlin_native_compiler_repository_rule(
+ name = git_repo,
+ **kwargs
+ )
+
+ kotlin_capabilities_repository(
+ name = name,
+ git_repository_name = git_repo,
+ compiler_version = compiler_version,
+ template = _CAPABILITIES_BUILD_TEMPLATE,
+ )
diff --git a/src/main/starlark/core/repositories/versions.bzl b/src/main/starlark/core/repositories/versions.bzl
index 814ae02b5..4f80685a9 100644
--- a/src/main/starlark/core/repositories/versions.bzl
+++ b/src/main/starlark/core/repositories/versions.bzl
@@ -10,6 +10,8 @@ version = provider(
},
)
+_DEFAULT_KOTLIN_COMPILER_RELEASE_VERSION = "2.1.21"
+
def _use_repository(name, version, rule, **kwargs):
http_archive_arguments = dict(kwargs)
http_archive_arguments["sha256"] = version.sha256
@@ -74,12 +76,44 @@ versions = struct(
sha256 = "5ba1ac917a06b0f02daaa60d10abbedd2220d60216af670c67a45b91c74cf8bb",
),
KOTLIN_CURRENT_COMPILER_RELEASE = version(
- version = "2.1.21",
+ version = _DEFAULT_KOTLIN_COMPILER_RELEASE_VERSION,
url_templates = [
"https://github.com/JetBrains/kotlin/releases/download/v{version}/kotlin-compiler-{version}.zip",
],
sha256 = "1ba08a8b45da99339a0601134cc037b54cf85e9bc0edbe76dcbd27c2d684a977",
),
+ KOTLIN_NATIVE_CURRENT_RELEASE_LINUX_X86_64 = version(
+ version = _DEFAULT_KOTLIN_COMPILER_RELEASE_VERSION,
+ url_templates = [
+ "https://github.com/JetBrains/kotlin/releases/download/v{version}/kotlin-native-prebuilt-linux-x86_64-{version}.tar.gz",
+ ],
+ sha256 = "42fb88529b4039b6ac1961a137ccb1c79fc80315947f3ec31b56834c7ce20d0b",
+ strip_prefix_template = "kotlin-native-prebuilt-linux-x86_64-{version}",
+ ),
+ KOTLIN_NATIVE_CURRENT_RELEASE_MACOS_X86_64 = version(
+ version = _DEFAULT_KOTLIN_COMPILER_RELEASE_VERSION,
+ url_templates = [
+ "https://github.com/JetBrains/kotlin/releases/download/v{version}/kotlin-native-prebuilt-macos-x86_64-{version}.tar.gz",
+ ],
+ sha256 = "fc6b5979ec322be803bfac549661aaf0f8f7342aa3bd09008d471fff2757bbdf",
+ strip_prefix_template = "kotlin-native-prebuilt-macos-x86_64-{version}",
+ ),
+ KOTLIN_NATIVE_CURRENT_RELEASE_MACOS_AARCH64 = version(
+ version = _DEFAULT_KOTLIN_COMPILER_RELEASE_VERSION,
+ url_templates = [
+ "https://github.com/JetBrains/kotlin/releases/download/v{version}/kotlin-native-prebuilt-macos-aarch64-{version}.tar.gz",
+ ],
+ sha256 = "8df16175b962bc4264a5c3b32cb042d91458babbd093c0f36194dc4645f5fe2e",
+ strip_prefix_template = "kotlin-native-prebuilt-macos-aarch64-{version}",
+ ),
+ KOTLIN_NATIVE_CURRENT_RELEASE_WINDOWS_X86_64 = version(
+ version = _DEFAULT_KOTLIN_COMPILER_RELEASE_VERSION,
+ url_templates = [
+ "https://github.com/JetBrains/kotlin/releases/download/v{version}/kotlin-native-prebuilt-windows-x86_64-{version}.zip",
+ ],
+ sha256 = "03301473bb9e68dadfdd265857a2a5913a147e700e345d32db73e0a21a2ffbfa",
+ strip_prefix_template = "kotlin-native-prebuilt-windows-x86_64-{version}",
+ ),
KSP_CURRENT_COMPILER_PLUGIN_RELEASE = version(
version = "2.1.21-2.0.1",
url_templates = [
diff --git a/src/test/data/native/BUILD.bazel b/src/test/data/native/BUILD.bazel
new file mode 100644
index 000000000..a152999a8
--- /dev/null
+++ b/src/test/data/native/BUILD.bazel
@@ -0,0 +1,26 @@
+load("//kotlin/internal/native:library.bzl", "kt_library")
+
+kt_library(
+ name = "basic",
+ srcs = ["basic/Hello.kt"],
+)
+
+kt_library(
+ name = "deps_greeting",
+ srcs = ["deps/data/Greeting.kt"],
+)
+
+kt_library(
+ name = "deps_main",
+ srcs = ["deps/Main.kt"],
+ deps = [":deps_greeting"],
+)
+
+filegroup(
+ name = "klib_tests",
+ srcs = [
+ "deps_main",
+ ":basic",
+ ],
+ visibility = ["//src/test:__subpackages__"],
+)
diff --git a/src/test/data/native/basic/Hello.kt b/src/test/data/native/basic/Hello.kt
new file mode 100644
index 000000000..e4a5e73f3
--- /dev/null
+++ b/src/test/data/native/basic/Hello.kt
@@ -0,0 +1,19 @@
+package basic
+
+fun main() {
+ val rawNames = listOf("alice", "", "Bob", "charlie", " ", "dave")
+
+ // Clean up names: trim, filter blanks
+ val cleanedNames = rawNames
+ .map { it.trim() }
+ .filter { it.isNotEmpty() }
+ .sortedBy { it.lowercase() }
+
+ // Capitalize each name
+ val capitalizedNames = cleanedNames.map { it.replaceFirstChar { c -> c.uppercaseChar() } }
+
+ // Print numbered list
+ capitalizedNames.forEachIndexed { index, name ->
+ println("${index + 1}. $name")
+ }
+}
diff --git a/src/test/data/native/deps/Main.kt b/src/test/data/native/deps/Main.kt
new file mode 100644
index 000000000..8507ec84f
--- /dev/null
+++ b/src/test/data/native/deps/Main.kt
@@ -0,0 +1,9 @@
+package main
+
+import data.createGreeting
+
+fun main() {
+ val name = "Alice"
+ val greeting = createGreeting(name)
+ println(greeting)
+}
diff --git a/src/test/data/native/deps/data/Greeting.kt b/src/test/data/native/deps/data/Greeting.kt
new file mode 100644
index 000000000..a19859e1e
--- /dev/null
+++ b/src/test/data/native/deps/data/Greeting.kt
@@ -0,0 +1,5 @@
+package data
+
+fun createGreeting(name: String): String {
+ return "Hello, $name!"
+}
diff --git a/src/test/kotlin/io/bazel/kotlin/BUILD b/src/test/kotlin/io/bazel/kotlin/BUILD
index 2ac635bd5..35d684395 100644
--- a/src/test/kotlin/io/bazel/kotlin/BUILD
+++ b/src/test/kotlin/io/bazel/kotlin/BUILD
@@ -68,6 +68,14 @@ kt_rules_e2e_test(
data = ["//src/test/data/jvm/ksp"],
)
+kt_rules_e2e_test(
+ name = "KotlinKlibAssertionTest",
+ srcs = ["KotlinKlibAssertionTest.kt"],
+ data = [
+ "//src/test/data/native:klib_tests",
+ ],
+)
+
test_suite(
name = "assertion_tests",
tests = [
diff --git a/src/test/kotlin/io/bazel/kotlin/KotlinAssertionTestCase.kt b/src/test/kotlin/io/bazel/kotlin/KotlinAssertionTestCase.kt
index 07156823d..5be14a690 100644
--- a/src/test/kotlin/io/bazel/kotlin/KotlinAssertionTestCase.kt
+++ b/src/test/kotlin/io/bazel/kotlin/KotlinAssertionTestCase.kt
@@ -26,6 +26,7 @@ import java.time.ZoneId
import java.util.concurrent.TimeUnit
import java.util.jar.JarEntry
import java.util.jar.JarFile
+import java.util.zip.ZipFile
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertTrue
@@ -37,6 +38,9 @@ class TestCaseFailedException(name: String? = null, description: String? = null,
cause
)
+// klib is just a zip file with specific entries
+typealias KlibZipFile = ZipFile
+
abstract class KotlinAssertionTestCase(root: String) : BasicAssertionTestCase() {
private lateinit var currentFile: File
@@ -70,6 +74,28 @@ abstract class KotlinAssertionTestCase(root: String) : BasicAssertionTestCase()
runTestCase(name, description) { JarFile(currentFile).op() }
}
+ protected fun klibTestCase(
+ name: String,
+ description: String? = null,
+ op: KlibZipFile.() -> Unit
+ ) {
+ currentFile = testRunfileRoot.resolve(name).toFile()
+ check(currentFile.exists()) {
+ "testFile $name did not exist in test case root $testRunfileRoot"
+ }
+ runTestCase(name, description) {
+ KlibZipFile(currentFile).op()
+ }
+ }
+
+ protected fun KlibZipFile.assertContainsEntries(vararg want: String) {
+ val got = this.entries().asSequence().map { it.name }.toSet()
+ val missing = want.toSet() - got
+ check(missing.isEmpty()) {
+ "Entries Missing: $missing \nFrom: $got"
+ }
+ }
+
protected fun JarFile.assertContainsEntries(vararg want: String) {
val got = this.entries().asSequence().map { it.name }.toSet()
val missing = want.toSet() - got
diff --git a/src/test/kotlin/io/bazel/kotlin/KotlinKlibAssertionTest.kt b/src/test/kotlin/io/bazel/kotlin/KotlinKlibAssertionTest.kt
new file mode 100644
index 000000000..978d9fb0d
--- /dev/null
+++ b/src/test/kotlin/io/bazel/kotlin/KotlinKlibAssertionTest.kt
@@ -0,0 +1,28 @@
+package io.bazel.kotlin
+
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(JUnit4::class)
+class KotlinKlibAssertionTest : KotlinAssertionTestCase("src/test/data/native") {
+ @Test
+ fun testBasicKlibIsProduced() {
+ klibTestCase("basic.klib", "kt_lib_library produces klib with stdlib usage") {
+ assertContainsEntries(
+ "default/linkdata/package_basic/0_basic.knm",
+ "default/manifest",
+ )
+ }
+ }
+
+ @Test
+ fun testDepsKlibIsProduced() {
+ klibTestCase("deps_main.klib", "kt_lib_library produces klib with stdlib usage") {
+ assertContainsEntries(
+ "default/linkdata/package_main/0_main.knm",
+ "default/manifest",
+ )
+ }
+ }
+}
diff --git a/src/test/kotlin/io/bazel/kotlin/builder/KotlinAbstractTestBuilder.java b/src/test/kotlin/io/bazel/kotlin/builder/KotlinAbstractTestBuilder.java
index ff2292288..b4278df49 100644
--- a/src/test/kotlin/io/bazel/kotlin/builder/KotlinAbstractTestBuilder.java
+++ b/src/test/kotlin/io/bazel/kotlin/builder/KotlinAbstractTestBuilder.java
@@ -235,6 +235,7 @@ static KotlinToolchain toolchainForTest() {
return KotlinToolchain.createToolchain(
javaHome,
new File(Deps.Dep.fromLabel("//kotlin/compiler:kotlin-compiler").singleCompileJar()),
+ new File(Deps.Dep.fromLabel("//kotlin/compiler:kotlin-native").singleCompileJar()),
new File(Deps.Dep.fromLabel("@kotlin_build_tools_impl//jar").singleCompileJar()),
new File(Deps.Dep.fromLabel("//src/main/kotlin/io/bazel/kotlin/compiler:compiler.jar").singleCompileJar()),
new File(Deps.Dep.fromLabel("//kotlin/compiler:jvm-abi-gen").singleCompileJar()),
diff --git a/src/test/kotlin/io/bazel/kotlin/builder/KotlinJvmTestBuilder.java b/src/test/kotlin/io/bazel/kotlin/builder/KotlinJvmTestBuilder.java
index bab333ef6..7caee8757 100644
--- a/src/test/kotlin/io/bazel/kotlin/builder/KotlinJvmTestBuilder.java
+++ b/src/test/kotlin/io/bazel/kotlin/builder/KotlinJvmTestBuilder.java
@@ -23,7 +23,6 @@
import io.bazel.kotlin.builder.toolchain.CompilationTaskContext;
import io.bazel.kotlin.model.CompilationTaskInfo;
import io.bazel.kotlin.model.JvmCompilationTask;
-import io.bazel.kotlin.model.KotlinToolchainInfo;
import java.util.EnumSet;
import java.util.HashSet;
diff --git a/src/test/kotlin/io/bazel/kotlin/defs.bzl b/src/test/kotlin/io/bazel/kotlin/defs.bzl
index fe5e2111c..4252c8e99 100644
--- a/src/test/kotlin/io/bazel/kotlin/defs.bzl
+++ b/src/test/kotlin/io/bazel/kotlin/defs.bzl
@@ -39,6 +39,7 @@ def kt_rules_test(name, **kwargs):
"//kotlin/compiler:annotations",
"//kotlin/compiler:jvm-abi-gen",
"//kotlin/compiler:kotlin-compiler",
+ "//kotlin/compiler:kotlin-native",
"//kotlin/compiler:kotlin-stdlib",
"//kotlin/compiler:kotlin-stdlib-jdk7",
"//kotlin/compiler:kotlin-stdlib-jdk8",
diff --git a/src/test/starlark/internal/native/BUILD.bazel b/src/test/starlark/internal/native/BUILD.bazel
new file mode 100644
index 000000000..ebf6e36ba
--- /dev/null
+++ b/src/test/starlark/internal/native/BUILD.bazel
@@ -0,0 +1,3 @@
+load(":kt_library_tests.bzl", "kt_library_test_suite")
+
+kt_library_test_suite(name = "library_tests")
diff --git a/src/test/starlark/internal/native/kt_library_tests.bzl b/src/test/starlark/internal/native/kt_library_tests.bzl
new file mode 100644
index 000000000..5a80ae9de
--- /dev/null
+++ b/src/test/starlark/internal/native/kt_library_tests.bzl
@@ -0,0 +1,97 @@
+load("@rules_testing//lib:analysis_test.bzl", "analysis_test")
+load("@rules_testing//lib:test_suite.bzl", "test_suite")
+load("//kotlin/internal:defs.bzl", "KtKlibInfo")
+load("//kotlin/internal/native:library.bzl", "kt_library")
+
+def _common_assertions(env, target):
+ # Assertions common to all kt_library tests
+ target_subject = env.expect.that_target(target)
+ target_subject.has_provider(KtKlibInfo)
+
+ action_subject = target_subject.action_named("KotlinKlibCompile")
+ action_subject.argv().contains_at_least(["--rule_kind", "kt_library", "--output_klib", "--konan_home"])
+
+def _test_kt_library_basic_impl(env, target):
+ _common_assertions(env, target)
+ target_subject = env.expect.that_target(target)
+ action_subject = target_subject.action_named("KotlinKlibCompile")
+ action_subject.inputs().contains("src/test/starlark/internal/native/Basic.kt")
+
+ target_subject.runfiles().contains("_main/src/test/starlark/internal/native/basic.klib")
+
+def _test_kt_library_basic(name):
+ kt_library(name = "basic", srcs = ["Basic.kt"], tags = ["manual"])
+
+ analysis_test(name, target = "basic", impl = _test_kt_library_basic_impl)
+
+def _test_kt_library_deps_impl(env, target):
+ _common_assertions(env, target)
+
+ target_subject = env.expect.that_target(target)
+ action_subject = target_subject.action_named("KotlinKlibCompile")
+ action_subject.inputs().contains("src/test/starlark/internal/native/Second.kt")
+
+ # the klib from first compilation is passed as input
+ action_subject.inputs().contains("src/test/starlark/internal/native/first.klib")
+
+ # and it's passed through the arguments
+ action_subject.argv().contains_at_least(["--klibs"])
+
+ # Transitive outputs are propagated in runfiles
+ target_subject.runfiles().contains_at_least(["_main/src/test/starlark/internal/native/first.klib", "_main/src/test/starlark/internal/native/second.klib"])
+
+def _test_kt_library_deps(name):
+ kt_library(name = "first", srcs = ["First.kt"], tags = ["manual"])
+
+ kt_library(name = "second", srcs = ["Second.kt"], deps = [":first"], tags = ["manual"])
+
+ analysis_test(name, target = "second", impl = _test_kt_library_deps_impl)
+
+def _test_kt_library_runfiles_impl(env, target):
+ _common_assertions(env, target)
+
+ target_subject = env.expect.that_target(target)
+ target_subject.data_runfiles().contains_at_least(["_main/src/test/starlark/internal/native/foo.txt"])
+
+def _test_kt_library_runfiles(name):
+ native.filegroup(
+ name = "runfiles1",
+ srcs = ["foo.txt"],
+ tags = ["manual"],
+ )
+ kt_library(name = "lib_with_data", srcs = ["First.kt"], data = [":runfiles1"], tags = ["manual"])
+
+ analysis_test(name, target = "lib_with_data", impl = _test_kt_library_runfiles_impl)
+
+def _test_kt_library_transitive_runfiles_impl(env, target):
+ _common_assertions(env, target)
+
+ target_subject = env.expect.that_target(target)
+ target_subject.data_runfiles().contains_at_least(["_main/src/test/starlark/internal/native/foo.txt"])
+
+def _test_kt_library_transitive_runfiles(name):
+ native.filegroup(
+ name = "runfiles2",
+ srcs = ["foo.txt"],
+ tags = ["manual"],
+ )
+ kt_library(name = "lib2_with_data", srcs = ["First.kt"], data = [":runfiles2"], tags = ["manual"])
+
+ kt_library(name = "final_lib", srcs = ["Second.kt"], deps = [":lib2_with_data"], tags = ["manual"])
+
+ analysis_test(name, target = "final_lib", impl = _test_kt_library_transitive_runfiles_impl)
+
+def kt_library_test_suite(name):
+ test_suite(
+ name = name,
+ tests = [
+ # assert compilation of single target with no deps works
+ _test_kt_library_basic,
+ # Assert compilation with deps works and transitive outputs are propagated
+ _test_kt_library_deps,
+ # Assert runfiles are available
+ _test_kt_library_runfiles,
+ # Assert transitive runfiles are propagated
+ _test_kt_library_transitive_runfiles,
+ ],
+ )