From 913b1ad6b35e956a01e2071b9c0192d2c102d85b Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Sun, 6 Jul 2025 16:50:26 -0400 Subject: [PATCH 01/40] Initial changes to support kotlin-native toolchain --- MODULE.bazel | 8 + kotlin/compiler/compiler.bzl | 35 +- kotlin/internal/common/BUILD.bazel | 0 kotlin/internal/common/common.bzl | 62 +++ kotlin/internal/defs.bzl | 6 + kotlin/internal/toolchains.bzl | 12 + .../io/bazel/kotlin/builder/cmd/BUILD.bazel | 2 + .../kotlin/builder/tasks/KotlinBuilder.kt | 41 +- .../tasks/common/KotlinKlibTaskExecutor.kt | 78 +++ .../kotlin/builder/toolchain/BUILD.bazel | 1 + .../builder/toolchain/KotlinToolchain.kt | 20 + .../io/bazel/kotlin/compiler/BUILD.bazel | 1 + .../kotlin/compiler/BazeK2NativeCompiler.kt | 38 ++ src/main/protobuf/kotlin_model.proto | 30 ++ src/main/starlark/core/compile/common.bzl | 8 + .../starlark/core/options/opts.native.bzl | 494 ++++++++++++++++++ src/main/starlark/core/repositories/BUILD | 2 + ...D.com_github_jetbrains_kotlin_native.bazel | 48 ++ .../BUILD.kotlin-native_capabilities.bazel | 40 ++ .../core/repositories/capabilities.bzl | 98 ++++ .../starlark/core/repositories/compiler.bzl | 99 +--- .../starlark/core/repositories/initialize.bzl | 12 +- .../core/repositories/initialize.release.bzl | 44 +- .../core/repositories/kotlin/artifacts.bzl | 42 ++ .../starlark/core/repositories/native.bzl | 52 ++ .../starlark/core/repositories/versions.bzl | 36 +- src/test/data/common/BUILD.bazel | 6 + src/test/data/common/basic/Hello.kt | 3 + 28 files changed, 1202 insertions(+), 116 deletions(-) create mode 100644 kotlin/internal/common/BUILD.bazel create mode 100644 kotlin/internal/common/common.bzl create mode 100644 src/main/kotlin/io/bazel/kotlin/builder/tasks/common/KotlinKlibTaskExecutor.kt create mode 100644 src/main/kotlin/io/bazel/kotlin/compiler/BazeK2NativeCompiler.kt create mode 100644 src/main/starlark/core/options/opts.native.bzl create mode 100644 src/main/starlark/core/repositories/BUILD.com_github_jetbrains_kotlin_native.bazel create mode 100644 src/main/starlark/core/repositories/BUILD.kotlin-native_capabilities.bazel create mode 100644 src/main/starlark/core/repositories/capabilities.bzl create mode 100644 src/main/starlark/core/repositories/native.bzl create mode 100644 src/test/data/common/BUILD.bazel create mode 100644 src/test/data/common/basic/Hello.kt diff --git a/MODULE.bazel b/MODULE.bazel index 40af3bee4..408b0e631 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", diff --git a/kotlin/compiler/compiler.bzl b/kotlin/compiler/compiler.bzl index 390cc9188..5c65f39d2 100644 --- a/kotlin/compiler/compiler.bzl +++ b/kotlin/compiler/compiler.bzl @@ -12,9 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -load("@com_github_jetbrains_kotlin//:artifacts.bzl", "KOTLINC_ARTIFACTS") +load("@com_github_jetbrains_kotlin//:artifacts.bzl", "KOTLINC_ARTIFACTS", "KOTLIN_NATIVE_ARTIFACTS") load("//kotlin:jvm.bzl", "kt_jvm_import") -load("//kotlin/internal:defs.bzl", _KT_COMPILER_REPO = "KT_COMPILER_REPO") +load("//kotlin/internal:defs.bzl", _KT_COMPILER_REPO = "KT_COMPILER_REPO", _KT_NATIVE_COMPILER_REPO_PREFIX = "KT_NATIVE_COMPILER_REPO_PREFIX") KOTLIN_STDLIBS = [ "//kotlin/compiler:annotations", @@ -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(): @@ -63,3 +63,18 @@ def kt_configure_compiler(): _import_artifacts(KOTLINC_ARTIFACTS.jvm, kt_jvm_import) _import_artifacts(KOTLINC_ARTIFACTS.core, kt_jvm_import) + _import_artifacts(KOTLIN_NATIVE_ARTIFACTS.linux_x86_64, kt_jvm_import, compiler_repo = _KT_NATIVE_COMPILER_REPO_PREFIX + "_linux_x86_64") + _import_artifacts(KOTLIN_NATIVE_ARTIFACTS.macos_x86_64, kt_jvm_import, compiler_repo = _KT_NATIVE_COMPILER_REPO_PREFIX + "_macos_x86_64") + _import_artifacts(KOTLIN_NATIVE_ARTIFACTS.macos_aarch64, kt_jvm_import, compiler_repo = _KT_NATIVE_COMPILER_REPO_PREFIX + "_macos_aarch64") + _import_artifacts(KOTLIN_NATIVE_ARTIFACTS.windows_x86_64, kt_jvm_import, compiler_repo = _KT_NATIVE_COMPILER_REPO_PREFIX + "_windows_x86_64") + + # a convenience alias for kotlin-native to be referenced in other places + native.alias( + actual = select({ + "@bazel_tools//src/conditions:linux_x86_64": "//kotlin/compiler:kotlin-native-linux-x86_64", + "@bazel_tools//src/conditions:darwin": "//kotlin/compiler:kotlin-native-macos-x86_64", + "@bazel_tools//src/conditions:windows": "//kotlin/compiler:kotlin-native-windows_x86_64", + "@bazel_tools//src/conditions:darwin_arm64": "//kotlin/compiler:kotlin-native-macos_aarch64", + }), + name = "kotlin-native", + ) diff --git a/kotlin/internal/common/BUILD.bazel b/kotlin/internal/common/BUILD.bazel new file mode 100644 index 000000000..e69de29bb diff --git a/kotlin/internal/common/common.bzl b/kotlin/internal/common/common.bzl new file mode 100644 index 000000000..75fbdc4a7 --- /dev/null +++ b/kotlin/internal/common/common.bzl @@ -0,0 +1,62 @@ +load("//kotlin/internal:defs.bzl", _KtKlibCommonInfo = "KtKlibCommonInfo", _TOOLCHAIN_TYPE = "TOOLCHAIN_TYPE") +load("//kotlin/internal/utils:utils.bzl", "utils") + +def _kt_klib_library(ctx): + module_name = utils.derive_module_name(ctx) + builder_args = utils.init_args(ctx, "kt_klib_library", module_name) + + klib = ctx.actions.declare_file("{}.klib".format(ctx.label.name)) + outputs = [klib] + + toolchains = ctx.toolchains[_TOOLCHAIN_TYPE] + deps_klibs = [] + for dep in ctx.attr.deps: + deps_klibs.append(dep[_KtKlibCommonInfo].klibs) + libraries = depset(transitive = deps_klibs) + builder_args.add_all("--sources", ctx.files.srcs) + builder_inputs, _, input_manifests = ctx.resolve_command(tools = [toolchains.kotlinbuilder, toolchains.konan_home]) + + builder_args.add("--strict_kotlin_deps", "off") + builder_args.add("--reduced_classpath_mode", "off") + builder_args.add("--output_klib", klib.path) + + ctx.actions.run( + mnemonic = "KotlinKlibCompile", + inputs = depset(builder_inputs + ctx.files.srcs, transitive = [libraries]), + outputs = outputs, + executable = toolchains.kotlinbuilder.files_to_run.executable, + tools = [ + toolchains.kotlinbuilder.files_to_run, + toolchains.konan_home[DefaultInfo].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)), + _KtKlibCommonInfo( + klibs = depset(outputs), + ), + ] + +kt_klib_library = rule( + implementation = _kt_klib_library, + 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 = [_KtKlibCommonInfo], + ), + }, + toolchains = [_TOOLCHAIN_TYPE], + provides = [_KtKlibCommonInfo], +) diff --git a/kotlin/internal/defs.bzl b/kotlin/internal/defs.bzl index 8fc952f30..89428346d 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", + _KtKlibCommonInfo = "KtKlibCommonInfo", ) load( "//src/main/starlark/core/plugin:providers.bzl", @@ -35,6 +36,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 +51,5 @@ KspPluginInfo = _KspPluginInfo KtCompilerPluginOption = _KtCompilerPluginOption KtPluginConfiguration = _KtPluginConfiguration + +KtKlibCommonInfo = _KtKlibCommonInfo diff --git a/kotlin/internal/toolchains.bzl b/kotlin/internal/toolchains.bzl index b69a16a1b..24e6d2e58 100644 --- a/kotlin/internal/toolchains.bzl +++ b/kotlin/internal/toolchains.bzl @@ -16,6 +16,7 @@ load("@rules_java//java:defs.bzl", "JavaInfo", "java_common") load( "//kotlin/internal:defs.bzl", _KT_COMPILER_REPO = "KT_COMPILER_REPO", + _KT_NATIVE_COMPILER_REPO_PREFIX = "KT_NATIVE_COMPILER_REPO_PREFIX", _TOOLCHAIN_TYPE = "TOOLCHAIN_TYPE", ) load( @@ -79,6 +80,7 @@ def _kotlin_toolchain_impl(ctx): ], jdeps_merger = ctx.attr.jdeps_merger, kotlin_home = ctx.attr.kotlin_home, + konan_home = ctx.attr.konan_home, jvm_stdlibs = java_common.merge(compile_time_providers + runtime_providers), jvm_emit_jdeps = ctx.attr._jvm_emit_jdeps[BuildSettingInfo].value, execution_requirements = { @@ -115,6 +117,10 @@ _kt_toolchain = rule( default = Label("@" + _KT_COMPILER_REPO + "//:home"), allow_files = True, ), + "konan_home": attr.label( + doc = "the filegroup defining the konan/kotlin-native home", + allow_files = True, + ), "kotlinbuilder": attr.label( doc = "the kotlin builder executable", default = Label("//src/main/kotlin:build"), @@ -379,6 +385,12 @@ def define_kt_toolchain( jvm_runtime = jvm_runtime if jvm_runtime != None else [ Label("//kotlin/compiler:kotlin-stdlib"), ], + konan_home = select({ + "@bazel_tools//src/conditions:linux_x86_64": Label("@" + _KT_NATIVE_COMPILER_REPO_PREFIX + "_linux_x86_64//:konan_home"), + "@bazel_tools//src/conditions:darwin_arm64": Label("@" + _KT_NATIVE_COMPILER_REPO_PREFIX + "_macos_aarch64//:konan_home"), + "@bazel_tools//src/conditions:darwin_x86_64": Label("@" + _KT_NATIVE_COMPILER_REPO_PREFIX + "_macos_x86_64//:konan_home"), + "@bazel_tools//src/conditions:windows": Label("@" + _KT_NATIVE_COMPILER_REPO_PREFIX + "_windows_x86_64//:konan_home"), + }), ) native.toolchain( name = name, 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..c542f8a48 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", @@ -38,6 +39,7 @@ kt_bootstrap_binary( "-D@com_github_jetbrains_kotlin...build-tools-impl=$(rlocationpath @kotlin_build_tools_impl//jar)", "-D@com_github_jetbrains_kotlin...jvm-abi-gen=$(rlocationpath //kotlin/compiler:jvm-abi-gen)", "-D@com_github_jetbrains_kotlin...kotlin-compiler=$(rlocationpath //kotlin/compiler:kotlin-compiler)", + "-D@com_github_jetbrains_kotlin_native...kotlin-native=$(rlocationpath //kotlin/compiler:kotlin-native)", "-D@com_github_jetbrains_kotlin...kapt=$(rlocationpath //kotlin/compiler:kotlin-annotation-processing)", "-D@rules_kotlin...jdeps-gen=$(rlocationpath //src/main/kotlin:jdeps-gen)", "-D@rules_kotlin...skip-code-gen=$(rlocationpath //src/main/kotlin:skip-code-gen)", 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..025c722e7 100644 --- a/src/main/kotlin/io/bazel/kotlin/builder/tasks/KotlinBuilder.kt +++ b/src/main/kotlin/io/bazel/kotlin/builder/tasks/KotlinBuilder.kt @@ -16,6 +16,7 @@ */ package io.bazel.kotlin.builder.tasks +import io.bazel.kotlin.builder.tasks.common.KotlinKlibTaskExecutor import io.bazel.kotlin.builder.tasks.jvm.KotlinJvmTaskExecutor import io.bazel.kotlin.builder.toolchain.CompilationStatusException import io.bazel.kotlin.builder.toolchain.CompilationTaskContext @@ -24,10 +25,7 @@ import io.bazel.kotlin.builder.utils.ArgMaps import io.bazel.kotlin.builder.utils.Flag 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.Platform -import io.bazel.kotlin.model.RuleKind +import io.bazel.kotlin.model.* import io.bazel.worker.WorkerContext import java.nio.charset.StandardCharsets import java.nio.file.FileSystems @@ -43,6 +41,7 @@ class KotlinBuilder @Inject internal constructor( private val jvmTaskExecutor: KotlinJvmTaskExecutor, + private val klibTaskExecutor: KotlinKlibTaskExecutor, ) { companion object { @JvmStatic @@ -89,6 +88,8 @@ 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") } } @@ -105,6 +106,7 @@ class KotlinBuilder Platform.JVM, Platform.ANDROID, -> executeJvmTask(compileContext, taskContext.directory, argMap) + Platform.KLIB -> executeKlibTask(compileContext, taskContext.directory, argMap) Platform.UNRECOGNIZED -> throw IllegalStateException( "unrecognized platform: ${compileContext.info}", ) @@ -189,6 +191,37 @@ class KotlinBuilder jvmTaskExecutor.execute(context, task) } + private fun executeKlibTask( + context: CompilationTaskContext, + workingDir: Path, + argMap: ArgMap, + ) { + val task = buildKlibTask(context.info, workingDir, argMap) + context.whenTracing { printProto("klib common task input", task) } + buildKlibTask(context.info, workingDir, argMap) + klibTaskExecutor.execute(context, task) + } + + private fun buildKlibTask(info: CompilationTaskInfo, workingDir: Path, argMap: ArgMap): KlibCompilationTask = + with(KlibCompilationTask.newBuilder()) { + this.info = info + with(directoriesBuilder) { + temp = workingDir.toString() + } + + 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/common/KotlinKlibTaskExecutor.kt b/src/main/kotlin/io/bazel/kotlin/builder/tasks/common/KotlinKlibTaskExecutor.kt new file mode 100644 index 000000000..b4f44c903 --- /dev/null +++ b/src/main/kotlin/io/bazel/kotlin/builder/tasks/common/KotlinKlibTaskExecutor.kt @@ -0,0 +1,78 @@ +package io.bazel.kotlin.builder.tasks.common + +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.KlibCompilationTask +import java.nio.file.FileSystem +import java.nio.file.FileSystems +import java.nio.file.Files +import java.nio.file.Path +import java.util.stream.Collectors +import javax.inject.Inject +import javax.inject.Singleton +import kotlin.io.path.absolute +import kotlin.io.path.absolutePathString +import kotlin.io.path.exists + +@Singleton +class KotlinKlibTaskExecutor +@Inject +constructor( + private val invoker: KotlinToolchain.K2NativeCompilerInvoker, +) { + private val fileSystem: FileSystem = FileSystems.getDefault() + + fun execute( + context: CompilationTaskContext, + task: KlibCompilationTask, + ) { + task.compile(context) + } + + private fun KlibCompilationTask.workingDirectory(): Path = fileSystem.getPath(directories.temp) + + private fun KlibCompilationTask.commonArgs(): MutableList { + val workDir = workingDirectory() + if (!workDir.exists()) { + workDir.toFile().mkdirs() + } + + val execRoot = fileSystem.getPath(".").absolute() + return mutableListOf().apply { + addAll(passThroughFlagsList) + addAll( + "-library", + inputs.librariesList + .map { + execRoot + .resolve( + it, + ).absolutePathString() + }.joinToString(":"), + ) + addAll("-module-name=${info.moduleName}") + addAll(inputs.kotlinSourcesList.map { execRoot.resolve(it).absolutePathString() }) + } + } + + private fun KlibCompilationTask.compile(context: CompilationTaskContext) { + val args = commonArgs() + val klibOut = fileSystem.getPath(outputs.klib) + args.addAll("-produce", "library") + context.whenTracing { printLines("klib compile args", args) } + + val outputDirectory = klibOut.parent + val workDir = workingDirectory() + + context.executeCompilerTask(args, invoker::compile) + context.whenTracing { + printLines( + "outputs", + Files.walk(outputDirectory).map { p -> p.toString() }.collect(Collectors.toList()), + ) + } + Files.copy(workDir.resolve(klibOut.fileName), klibOut) + } + +} diff --git a/src/main/kotlin/io/bazel/kotlin/builder/toolchain/BUILD.bazel b/src/main/kotlin/io/bazel/kotlin/builder/toolchain/BUILD.bazel index fe3390a58..81aa8b226 100644 --- a/src/main/kotlin/io/bazel/kotlin/builder/toolchain/BUILD.bazel +++ b/src/main/kotlin/io/bazel/kotlin/builder/toolchain/BUILD.bazel @@ -24,6 +24,7 @@ kt_bootstrap_library( "//kotlin/compiler:symbol-processing-api", "//kotlin/compiler:symbol-processing-cmdline", "//kotlin/compiler:kotlin-preloader", + "//kotlin/compiler:kotlin-native", ], visibility = ["//src:__subpackages__"], deps = [ 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/BUILD.bazel b/src/main/kotlin/io/bazel/kotlin/compiler/BUILD.bazel index 0372403ac..ed6dae343 100644 --- a/src/main/kotlin/io/bazel/kotlin/compiler/BUILD.bazel +++ b/src/main/kotlin/io/bazel/kotlin/compiler/BUILD.bazel @@ -23,6 +23,7 @@ kt_bootstrap_library( "//kotlin/compiler:kotlin-compiler", "//kotlin/compiler:kotlin-annotation-processing", "//kotlin/compiler:kotlin-script-runtime", + "//kotlin/compiler:kotlin-native", ], visibility = ["//src:__subpackages__"], ) diff --git a/src/main/kotlin/io/bazel/kotlin/compiler/BazeK2NativeCompiler.kt b/src/main/kotlin/io/bazel/kotlin/compiler/BazeK2NativeCompiler.kt new file mode 100644 index 000000000..0eb8bcc85 --- /dev/null +++ b/src/main/kotlin/io/bazel/kotlin/compiler/BazeK2NativeCompiler.kt @@ -0,0 +1,38 @@ +/* + * 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..1d1fc8c21 100644 --- a/src/main/protobuf/kotlin_model.proto +++ b/src/main/protobuf/kotlin_model.proto @@ -55,6 +55,7 @@ enum RuleKind { enum Platform { JVM = 0; ANDROID = 1; + KLIB = 3; } // Common info about a Kotlin compilation task, this message is shared by all compilation tasks. @@ -175,3 +176,32 @@ message JvmCompilationTask { bool compile_kotlin = 6; bool instrument_coverage = 7; } + + +message KlibCompilationTask { + // Directories used by the builder. + message Directories { + // A temp directory that the compiler may use. + string temp = 4; + } + + 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/common.bzl b/src/main/starlark/core/compile/common.bzl index 7b892e496..f29367e28 100644 --- a/src/main/starlark/core/compile/common.bzl +++ b/src/main/starlark/core/compile/common.bzl @@ -19,3 +19,11 @@ KtJvmInfo = provider( "all_output_jars": "Returns all the output Jars produced by this rule. [bazel-bsp-aspect]", }, ) + +KtKlibCommonInfo = 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/options/opts.native.bzl b/src/main/starlark/core/options/opts.native.bzl new file mode 100644 index 000000000..1c66319a6 --- /dev/null +++ b/src/main/starlark/core/options/opts.native.bzl @@ -0,0 +1,494 @@ +# 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("@com_github_jetbrains_kotlin//:capabilities.bzl", _KOTLIN_OPTS = "KOTLIN_OPTS") +load("//src/main/starlark/core/options:convert.bzl", "convert") +load("//src/main/starlark/core/options:derive.bzl", "derive") + +def _map_optin_class_to_flag(values): + return ["-opt-in=%s" % v for v in values] + +def _map_backend_threads_to_flag(n): + if n == 1: + return None + return ["-Xbackend-threads=%d" % n] + +def _map_jvm_target_to_flag(version): + if not version: + return None + return ["-jvm-target=%s" % version] + +def _map_jdk_release_to_flag(version): + if not version: + return None + return ["-Xjdk-release=%s" % version] + +_KOPTS_ALL = { + "warn": struct( + args = dict( + default = "report", + doc = "Control warning behaviour.", + values = ["off", "report", "error"], + ), + type = attr.string, + value_to_flag = { + "off": ["-nowarn"], + "report": None, + "error": ["-Werror"], + }, + ), + "include_stdlibs": struct( + args = dict( + default = "all", + doc = "Don't automatically include the Kotlin standard libraries into the classpath (stdlib and reflect).", + values = ["all", "stdlib", "none"], + ), + type = attr.string, + value_to_flag = { + "all": None, + "stdlib": ["-no-reflect"], + "none": ["-no-stdlib"], + }, + ), + "x_skip_prerelease_check": struct( + flag = "-Xskip-prerelease-check", + args = dict( + default = False, + doc = "Suppress errors thrown when using pre-release classes.", + ), + type = attr.bool, + value_to_flag = { + True: ["-Xskip-prerelease-check"], + }, + ), + "x_context_receivers": struct( + flag = "-Xcontext-receivers", + args = dict( + default = False, + doc = "Enable experimental context receivers.", + ), + type = attr.bool, + value_to_flag = { + True: ["-Xcontext-receivers"], + }, + ), + "x_suppress_version_warnings": struct( + flag = "-Xsuppress-version-warnings", + args = dict( + default = False, + doc = "Suppress warnings about outdated, inconsistent, or experimental language or API versions.", + ), + type = attr.bool, + value_to_flag = { + True: ["-Xsuppress-version-warnings"], + }, + ), + "x_inline_classes": struct( + flag = "-Xinline-classes", + args = dict( + default = False, + doc = "Enable experimental inline classes", + ), + type = attr.bool, + value_to_flag = { + True: ["-Xinline-classes"], + }, + ), + "x_allow_result_return_type": struct( + flag = "-Xallow-result-return-type", + args = dict( + default = False, + doc = "Enable kotlin.Result as a return type", + ), + type = attr.bool, + value_to_flag = { + True: ["-Xallow-result-return-type"], + }, + ), + "x_jvm_default": struct( + flag = "-Xjvm-default", + args = dict( + default = "off", + doc = "Specifies that a JVM default method should be generated for non-abstract Kotlin interface member.", + values = ["off", "enable", "disable", "compatibility", "all-compatibility", "all"], + ), + type = attr.string, + value_to_flag = { + "off": None, + "enable": ["-Xjvm-default=enable"], + "disable": ["-Xjvm-default=disable"], + "compatibility": ["-Xjvm-default=compatibility"], + "all-compatibility": ["-Xjvm-default=all-compatibility"], + "all": ["-Xjvm-default=all"], + }, + ), + "x_no_call_assertions": struct( + flag = "-Xno-call-assertions", + args = dict( + default = False, + doc = "Don't generate not-null assertions for arguments of platform types", + ), + type = attr.bool, + value_to_flag = { + True: ["-Xno-call-assertions"], + }, + ), + "x_no_param_assertions": struct( + flag = "-Xno-param-assertions", + args = dict( + default = False, + doc = "Don't generate not-null assertions on parameters of methods accessible from Java", + ), + type = attr.bool, + value_to_flag = { + True: ["-Xno-param-assertions"], + }, + ), + "x_no_receiver_assertions": struct( + flag = "-Xno-receiver-assertions", + args = dict( + default = False, + doc = "Don't generate not-null assertion for extension receiver arguments of platform types", + ), + type = attr.bool, + value_to_flag = { + True: ["-Xno-receiver-assertions"], + }, + ), + "x_no_optimized_callable_references": struct( + flag = "-Xno-optimized-callable-references", + args = dict( + default = False, + doc = "Do not use optimized callable reference superclasses. Available from 1.4.", + ), + type = attr.bool, + value_to_flag = { + True: ["-Xno-optimized-callable-references"], + }, + ), + "x_explicit_api_mode": struct( + flag = "-Xexplicit-api", + args = dict( + default = "off", + doc = "Enable explicit API mode for Kotlin libraries.", + values = ["off", "warning", "strict"], + ), + type = attr.string, + value_to_flag = { + "off": None, + "warning": ["-Xexplicit-api=warning"], + "strict": ["-Xexplicit-api=strict"], + }, + ), + "x_annotation_default_target": struct( + args = dict( + default = "off", + doc = """Change the default annotation targets for constructor properties: +-Xannotation-default-target=first-only: use the first of the following allowed targets: '@param:', '@property:', '@field:'; +-Xannotation-default-target=first-only-warn: same as first-only, and raise warnings when both '@param:' and either '@property:' or '@field:' are allowed; +-Xannotation-default-target=param-property: use '@param:' target if applicable, and also use the first of either '@property:' or '@field:'; +default: 'first-only-warn' in language version 2.2+, 'first-only' in version 2.1 and before.""", + values = ["off", "first-only", "first-only-warn", "param-property"], + ), + type = attr.string, + value_to_flag = { + "off": None, + "first-only": ["-Xannotation-default-target=first-only"], + "first-only-warn": ["-Xannotation-default-target=first-only-warn"], + "param-property": ["-Xannotation-default-target=param-property"], + }, + ), + "java_parameters": struct( + args = dict( + default = False, + doc = "Generate metadata for Java 1.8+ reflection on method parameters.", + ), + type = attr.bool, + value_to_flag = { + True: ["-java-parameters"], + }, + ), + "x_multi_platform": struct( + flag = "-Xmulti-platform", + args = dict( + default = False, + doc = "Enable experimental language support for multi-platform projects", + ), + type = attr.bool, + value_to_flag = { + True: ["-Xmulti-platform"], + }, + ), + "x_sam_conversions": struct( + flag = "-Xsam-conversions", + args = dict( + default = "class", + doc = "Change codegen behavior of SAM/functional interfaces", + values = ["class", "indy"], + ), + type = attr.string, + value_to_flag = { + "class": ["-Xsam-conversions=class"], + "indy": ["-Xsam-conversions=indy"], + }, + ), + "x_lambdas": struct( + flag = "-Xlambdas", + args = dict( + default = "class", + doc = "Change codegen behavior of lambdas", + values = ["class", "indy"], + ), + type = attr.string, + value_to_flag = { + "class": ["-Xlambdas=class"], + "indy": ["-Xlambdas=indy"], + }, + ), + "x_emit_jvm_type_annotations": struct( + flag = "-Xemit-jvm-type-annotations", + args = dict( + default = False, + doc = "Basic support for type annotations in JVM bytecode.", + ), + type = attr.bool, + value_to_flag = { + True: ["-Xemit-jvm-type-annotations"], + }, + ), + "x_optin": struct( + args = dict( + default = [], + doc = "Define APIs to opt-in to.", + ), + type = attr.string_list, + value_to_flag = None, + map_value_to_flag = _map_optin_class_to_flag, + ), + "x_use_fir": struct( + # 1.6 + flag = "-Xuse-fir", + args = dict( + default = False, + doc = "Compile using the experimental Kotlin Front-end IR. Available from 1.6.", + ), + type = attr.bool, + value_to_flag = { + True: ["-Xuse-fir"], + }, + ), + "x_use_k2": struct( + # 1.7 + flag = "-Xuse-k2", + args = dict( + default = False, + doc = "Compile using experimental K2. K2 is a new compiler pipeline, no compatibility guarantees are yet provided", + ), + type = attr.bool, + value_to_flag = { + True: ["-Xuse-k2"], + }, + ), + "x_no_optimize": struct( + flag = "-Xno-optimize", + args = dict( + default = False, + doc = "Disable optimizations", + ), + type = attr.bool, + value_to_flag = { + True: ["-Xno-optimize"], + }, + ), + "x_backend_threads": struct( + # 1.6.20, 1.7 + flag = "-Xbackend-threads", + args = dict( + default = 1, + doc = "When using the IR backend, run lowerings by file in N parallel threads. 0 means use a thread per processor core. Default value is 1.", + ), + type = attr.int, + value_to_flag = None, + map_value_to_flag = _map_backend_threads_to_flag, + ), + "x_enable_incremental_compilation": struct( + args = dict( + default = False, + doc = "Enable incremental compilation", + ), + type = attr.bool, + value_to_flag = { + True: ["-Xenable-incremental-compilation"], + }, + ), + "x_report_perf": struct( + flag = "-Xreport-perf", + args = dict( + default = False, + doc = "Report detailed performance statistics", + ), + type = attr.bool, + value_to_flag = { + True: ["-Xreport-perf"], + }, + ), + "x_use_fir_lt": struct( + args = dict( + default = False, + doc = "Compile using LightTree parser with Front-end IR. Warning: this feature is far from being production-ready", + ), + type = attr.bool, + value_to_flag = { + True: ["-Xuse-fir-lt"], + }, + ), + "x_no_source_debug_extension": struct( + args = dict( + default = False, + doc = "Do not generate @kotlin.jvm.internal.SourceDebugExtension annotation on a class with the copy of SMAP", + ), + type = attr.bool, + value_to_flag = { + True: ["-Xno-source-debug-extension"], + }, + ), + "x_type_enhancement_improvements_strict_mode": struct( + args = dict( + default = False, + doc = "Enables strict mode for type enhancement improvements, enforcing stricter type checking and enhancements.", + ), + type = attr.bool, + value_to_flag = { + True: ["-Xtype-enhancement-improvements-strict-mode"], + }, + ), + "x_jsr_305": struct( + args = dict( + default = "", + doc = "Specifies how to handle JSR-305 annotations in Kotlin code. Options are 'default', 'ignore', 'warn', and 'strict'.", + values = ["default", "ignore", "warn", "strict"], + ), + type = attr.string, + value_to_flag = { + "default": None, + "ignore": ["-Xjsr305=ignore"], + "warn": ["-Xjsr305=warn"], + "strict": ["-Xjsr305=strict"], + }, + map_value_to_flag = None, + ), + "x_assertions": struct( + args = dict( + default = "", + doc = "Configures how assertions are handled. The 'jvm' option enables assertions in JVM code.", + values = ["jvm"], + ), + type = attr.string, + value_to_flag = { + "default": None, + "jvm": ["-Xassertions=jvm"], + }, + map_value_to_flag = None, + ), + "x_jspecify_annotations": struct( + args = dict( + default = "", + doc = "Controls how JSpecify annotations are treated. Options are 'default', 'ignore', 'warn', and 'strict'.", + values = ["default", "ignore", "warn", "strict"], + ), + type = attr.string, + value_to_flag = { + "default": None, + "ignore": ["-Xjspecify-annotations=ignore"], + "warn": ["-Xjspecify-annotations=warn"], + "strict": ["-Xjspecify-annotations=strict"], + }, + map_value_to_flag = None, + ), + "x_consistent_data_class_copy_visibility": struct( + args = dict( + default = False, + doc = "The effect of this compiler flag is the same as applying @ConsistentCopyVisibility annotation to all data classes in the module. See https://youtrack.jetbrains.com/issue/KT-11914", + ), + type = attr.bool, + value_to_flag = { + True: ["-Xconsistent-data-class-copy-visibility"], + }, + ), + "jvm_target": struct( + args = dict( + default = "", + doc = "The target version of the generated JVM bytecode", + values = ["1.6", "1.8", "9", "10", "11", "12", "13", "15", "16", "17"], + ), + type = attr.string, + value_to_flag = None, + map_value_to_flag = _map_jvm_target_to_flag, + ), + "x_jdk_release": struct( + args = dict( + default = "", + doc = """Compile against the specified JDK API version, similarly to javac's '-release'. This requires JDK 9 or newer. + The supported versions depend on the JDK used; for JDK 17+, the supported versions are 1.8 and 9–21. + This also sets the value of '-jvm-target' to be equal to the selected JDK version.""", + values = ["1.6", "1.8", "9", "10", "11", "12", "13", "15", "16", "17"], + ), + type = attr.string, + value_to_flag = None, + map_value_to_flag = _map_jdk_release_to_flag, + ), + "x_suppress_warning": struct( + args = dict( + default = [], + doc = "Suppress specific warnings globally", + ), + type = attr.string_list, + value_to_flag = { + derive.info: derive.repeated_values_for("-Xsuppress-warning="), + }, + ), +} + +def _merge(key, rule_defined): + """Merges rule option with compiler option.""" + if key not in _KOTLIN_OPTS: + # No flag associated with option. + return rule_defined + generated = _KOTLIN_OPTS[key] + merged = {k: getattr(k, rule_defined) for k in dir(rule_defined)} + merged["doc"] = generated.doc + merged["default"] = generated.default + return struct(**merged) + +def _no_merge(_, definition): + return definition + +_maybe_merge_definition = _merge if hasattr(_KOTLIN_OPTS, "get") else _no_merge + +# Filters out options that are not available in current compiler release +_KOPTS = { + attr: _maybe_merge_definition(attr, defn) + for (attr, defn) in _KOPTS_ALL.items() + if not hasattr(defn, "flag") or defn.flag in _KOTLIN_OPTS +} + +KotlincOptions = provider( + fields = { + name: o.args["doc"] + for name, o in _KOPTS.items() + }, +) + +def _kotlinc_options_impl(ctx): + return [KotlincOptions(**{n: getattr(ctx.attr, n, None) for n in _KOPTS})] diff --git a/src/main/starlark/core/repositories/BUILD b/src/main/starlark/core/repositories/BUILD index 869f9e74d..aa441ab31 100644 --- a/src/main/starlark/core/repositories/BUILD +++ b/src/main/starlark/core/repositories/BUILD @@ -19,10 +19,12 @@ release_archive( srcs = [ "BUILD.com_github_google_ksp.bazel", "BUILD.com_github_jetbrains_kotlin.bazel", + "BUILD.com_github_jetbrains_kotlin_native.bazel", "BUILD.kotlin_capabilities.bazel", "bzlmod_impl.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..d2696332a --- /dev/null +++ b/src/main/starlark/core/repositories/BUILD.com_github_jetbrains_kotlin_native.bazel @@ -0,0 +1,48 @@ +# 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"]) + +filegroup( + name = "bin", + srcs = glob(["bin/**"]), +) + +filegroup( + name = "konan_home", + srcs = glob(["konan/**"]) +) + +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/**"]) +] + 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..e55385d96 --- /dev/null +++ b/src/main/starlark/core/repositories/BUILD.kotlin-native_capabilities.bazel @@ -0,0 +1,40 @@ +# 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") +load(":artifacts.bzl", "KOTLIN_NATIVE_ARTIFACT_LIST") + +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 = label, + actual = "@$git_repo$//:%s" % file.replace(".", "_"), + ) + for (label, file) in KOTLIN_NATIVE_ARTIFACT_LIST.items() +] \ No newline at end of file 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..3bb9a152f 100644 --- a/src/main/starlark/core/repositories/kotlin/artifacts.bzl +++ b/src/main/starlark/core/repositories/kotlin/artifacts.bzl @@ -70,9 +70,51 @@ KOTLINC_ARTIFACTS = struct( ), ) +KOTLIN_NATIVE_ARTIFACTS = struct( + linux_x86_64 = struct( + plugin = {}, + compile = { + "kotlin-native-linux-x86_64": "konan/lib/kotlin-native.jar", + "trove4j-linux-x86_64": "konan/lib/trove4j.jar", + }, + runtime = {}, + ), + macos_x86_64 = struct( + plugin = {}, + compile = { + "kotlin-native-macos-x86_64": "konan/lib/kotlin-native.jar", + "trove4j-macos-x86_64": "konan/lib/trove4j.jar", + }, + runtime = {}, + ), + macos_aarch64 = struct( + plugin = {}, + compile = { + "kotlin-native-macos_aarch64": "konan/lib/kotlin-native.jar", + "trove4j-macos_aarch64": "konan/lib/trove4j.jar", + }, + runtime = {}, + ), + windows_x86_64 = struct( + plugin = {}, + compile = { + "kotlin-native-windows_x86_64": "konan/lib/kotlin-native.jar", + "trove4j-windows_x86_64": "konan/lib/trove4j.jar", + }, + runtime = {}, + ), +) + KOTLINC_ARTIFACT_LIST = { label: file for lang in ["jvm", "core"] for type in ["compile", "plugin", "runtime"] for (label, file) in getattr(getattr(KOTLINC_ARTIFACTS, lang), type).items() } + +KOTLIN_NATIVE_ARTIFACT_LIST = { + label: file + for platform in ["linux_x86_64", "macos_x86_64", "macos_aarch64", "windows_x86_64"] + for type in ["compile", "plugin", "runtime"] + for (label, file) in getattr(getattr(KOTLIN_NATIVE_ARTIFACTS, platform), type).items() +} 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..92f74d3ba 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 = "8df16175b962bc4264a5c3b32cb042d91458babbd093c0f36194dc4645f5fe2", + 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/common/BUILD.bazel b/src/test/data/common/BUILD.bazel new file mode 100644 index 000000000..dd3e261fa --- /dev/null +++ b/src/test/data/common/BUILD.bazel @@ -0,0 +1,6 @@ +load("//kotlin/internal/common:common.bzl", "kt_klib_library") + +kt_klib_library( + name = "basic", + srcs = ["basic/Hello.kt"], +) diff --git a/src/test/data/common/basic/Hello.kt b/src/test/data/common/basic/Hello.kt new file mode 100644 index 000000000..c9120dde3 --- /dev/null +++ b/src/test/data/common/basic/Hello.kt @@ -0,0 +1,3 @@ +fun sayHello() { + println("Hello, world!") +} From e5eb0a56f5e3f10fc41adcd5ef3fa98200a5bbdb Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Sun, 6 Jul 2025 18:10:30 -0400 Subject: [PATCH 02/40] KtKlibInfo --- kotlin/internal/common/common.bzl | 14 +++++++++----- kotlin/internal/defs.bzl | 4 ++-- src/main/starlark/core/compile/common.bzl | 2 +- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/kotlin/internal/common/common.bzl b/kotlin/internal/common/common.bzl index 75fbdc4a7..383e8f355 100644 --- a/kotlin/internal/common/common.bzl +++ b/kotlin/internal/common/common.bzl @@ -1,4 +1,4 @@ -load("//kotlin/internal:defs.bzl", _KtKlibCommonInfo = "KtKlibCommonInfo", _TOOLCHAIN_TYPE = "TOOLCHAIN_TYPE") +load("//kotlin/internal:defs.bzl", _KtKlibInfo = "KtKlibInfo", _TOOLCHAIN_TYPE = "TOOLCHAIN_TYPE") load("//kotlin/internal/utils:utils.bzl", "utils") def _kt_klib_library(ctx): @@ -11,7 +11,7 @@ def _kt_klib_library(ctx): toolchains = ctx.toolchains[_TOOLCHAIN_TYPE] deps_klibs = [] for dep in ctx.attr.deps: - deps_klibs.append(dep[_KtKlibCommonInfo].klibs) + deps_klibs.append(dep[_KtKlibInfo].klibs) libraries = depset(transitive = deps_klibs) builder_args.add_all("--sources", ctx.files.srcs) builder_inputs, _, input_manifests = ctx.resolve_command(tools = [toolchains.kotlinbuilder, toolchains.konan_home]) @@ -40,13 +40,17 @@ def _kt_klib_library(ctx): return [ DefaultInfo(files = depset(outputs)), - _KtKlibCommonInfo( + _KtKlibInfo( klibs = depset(outputs), ), ] kt_klib_library = rule( implementation = _kt_klib_library, + 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", @@ -54,9 +58,9 @@ kt_klib_library = rule( ), "deps": attr.label_list( doc = "A list of other kt_klib_library targets that this library depends on for compilation", - providers = [_KtKlibCommonInfo], + providers = [_KtKlibInfo], ), }, toolchains = [_TOOLCHAIN_TYPE], - provides = [_KtKlibCommonInfo], + provides = [_KtKlibInfo], ) diff --git a/kotlin/internal/defs.bzl b/kotlin/internal/defs.bzl index 89428346d..82b9ea89c 100644 --- a/kotlin/internal/defs.bzl +++ b/kotlin/internal/defs.bzl @@ -16,7 +16,7 @@ load( _JAVA_RUNTIME_TOOLCHAIN_TYPE = "JAVA_RUNTIME_TOOLCHAIN_TYPE", _JAVA_TOOLCHAIN_TYPE = "JAVA_TOOLCHAIN_TYPE", _KtJvmInfo = "KtJvmInfo", - _KtKlibCommonInfo = "KtKlibCommonInfo", + _KtKlibInfo = "KtKlibInfo", ) load( "//src/main/starlark/core/plugin:providers.bzl", @@ -52,4 +52,4 @@ KtCompilerPluginOption = _KtCompilerPluginOption KtPluginConfiguration = _KtPluginConfiguration -KtKlibCommonInfo = _KtKlibCommonInfo +KtKlibInfo = _KtKlibInfo diff --git a/src/main/starlark/core/compile/common.bzl b/src/main/starlark/core/compile/common.bzl index f29367e28..71791f086 100644 --- a/src/main/starlark/core/compile/common.bzl +++ b/src/main/starlark/core/compile/common.bzl @@ -20,7 +20,7 @@ KtJvmInfo = provider( }, ) -KtKlibCommonInfo = provider( +KtKlibInfo = provider( fields = { "module_name": "the module_name", "klibs": "the klibs provided by the output of compilation", From 94abd2d8fae4d62446e20239585068debe495b39 Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Sun, 13 Jul 2025 15:06:32 -0400 Subject: [PATCH 03/40] Add initial support for kotlin-native toolchain and klib compilation --- MODULE.bazel | 2 + kotlin/compiler/compiler.bzl | 1 + kotlin/internal/{common => klib}/BUILD.bazel | 0 .../{common/common.bzl => klib/klib.bzl} | 12 +++ .../kotlin/builder/tasks/KotlinBuilder.kt | 68 ++++++++------- .../tasks/common/KotlinKlibTaskExecutor.kt | 78 ----------------- .../tasks/klib/KotlinKlibTaskExecutor.kt | 87 +++++++++++++++++++ ...veCompiler.kt => BazelK2NativeCompiler.kt} | 4 + ...D.com_github_jetbrains_kotlin_native.bazel | 19 +++- src/test/data/common/BUILD.bazel | 6 -- src/test/data/common/basic/Hello.kt | 3 - src/test/data/klib/BUILD.bazel | 26 ++++++ src/test/data/klib/basic/Hello.kt | 19 ++++ src/test/data/klib/deps/Main.kt | 9 ++ src/test/data/klib/deps/data/Greeting.kt | 5 ++ src/test/kotlin/io/bazel/kotlin/BUILD | 8 ++ .../bazel/kotlin/KotlinAssertionTestCase.kt | 26 ++++++ .../bazel/kotlin/KotlinKlibAssertionTest.kt | 28 ++++++ .../builder/KotlinAbstractTestBuilder.java | 1 + .../kotlin/builder/KotlinJvmTestBuilder.java | 3 +- src/test/starlark/internal/klib/BUILD.bazel | 3 + .../starlark/internal/klib/klib_tests.bzl | 53 +++++++++++ 22 files changed, 341 insertions(+), 120 deletions(-) rename kotlin/internal/{common => klib}/BUILD.bazel (100%) rename kotlin/internal/{common/common.bzl => klib/klib.bzl} (84%) delete mode 100644 src/main/kotlin/io/bazel/kotlin/builder/tasks/common/KotlinKlibTaskExecutor.kt create mode 100644 src/main/kotlin/io/bazel/kotlin/builder/tasks/klib/KotlinKlibTaskExecutor.kt rename src/main/kotlin/io/bazel/kotlin/compiler/{BazeK2NativeCompiler.kt => BazelK2NativeCompiler.kt} (89%) delete mode 100644 src/test/data/common/BUILD.bazel delete mode 100644 src/test/data/common/basic/Hello.kt create mode 100644 src/test/data/klib/BUILD.bazel create mode 100644 src/test/data/klib/basic/Hello.kt create mode 100644 src/test/data/klib/deps/Main.kt create mode 100644 src/test/data/klib/deps/data/Greeting.kt create mode 100644 src/test/kotlin/io/bazel/kotlin/KotlinKlibAssertionTest.kt create mode 100644 src/test/starlark/internal/klib/BUILD.bazel create mode 100644 src/test/starlark/internal/klib/klib_tests.bzl diff --git a/MODULE.bazel b/MODULE.bazel index 408b0e631..ee198325a 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -19,6 +19,8 @@ bazel_dep(name = "rules_shell", version = "0.4.1") bazel_dep(name = "buildifier_prebuilt", version = "8.0.3", dev_dependency = True) +bazel_dep(name = "aspect_bazel_lib", version = "2.19.4") + rules_java_toolchains = use_extension("@rules_java//java:extensions.bzl", "toolchains") use_repo(rules_java_toolchains, "remote_java_tools") diff --git a/kotlin/compiler/compiler.bzl b/kotlin/compiler/compiler.bzl index 5c65f39d2..cecaab295 100644 --- a/kotlin/compiler/compiler.bzl +++ b/kotlin/compiler/compiler.bzl @@ -13,6 +13,7 @@ # limitations under the License. load("@com_github_jetbrains_kotlin//:artifacts.bzl", "KOTLINC_ARTIFACTS", "KOTLIN_NATIVE_ARTIFACTS") +load("@rules_java//java:defs.bzl", "java_binary") load("//kotlin:jvm.bzl", "kt_jvm_import") load("//kotlin/internal:defs.bzl", _KT_COMPILER_REPO = "KT_COMPILER_REPO", _KT_NATIVE_COMPILER_REPO_PREFIX = "KT_NATIVE_COMPILER_REPO_PREFIX") diff --git a/kotlin/internal/common/BUILD.bazel b/kotlin/internal/klib/BUILD.bazel similarity index 100% rename from kotlin/internal/common/BUILD.bazel rename to kotlin/internal/klib/BUILD.bazel diff --git a/kotlin/internal/common/common.bzl b/kotlin/internal/klib/klib.bzl similarity index 84% rename from kotlin/internal/common/common.bzl rename to kotlin/internal/klib/klib.bzl index 383e8f355..46117b766 100644 --- a/kotlin/internal/common/common.bzl +++ b/kotlin/internal/klib/klib.bzl @@ -20,6 +20,17 @@ def _kt_klib_library(ctx): builder_args.add("--reduced_classpath_mode", "off") builder_args.add("--output_klib", klib.path) + deps_klibs = [] + for dep in ctx.attr.deps: + deps_klibs.append(dep[_KtKlibInfo].klibs) + libraries = depset(transitive = deps_klibs) + builder_args.add_all("--klibs", libraries, omit_if_empty = False) + + # This will be a directory we need to propagate to the compiler + konan_home = toolchains.konan_home[DefaultInfo].files.to_list()[0] + if not konan_home.is_directory: + fail("konan home must be a directory!") + ctx.actions.run( mnemonic = "KotlinKlibCompile", inputs = depset(builder_inputs + ctx.files.srcs, transitive = [libraries]), @@ -35,6 +46,7 @@ def _kt_klib_library(ctx): input_manifests = input_manifests, env = { "REPOSITORY_NAME": utils.builder_workspace_name(ctx), + "KONAN_HOME": konan_home.path, }, ) 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 025c722e7..0f160ae3b 100644 --- a/src/main/kotlin/io/bazel/kotlin/builder/tasks/KotlinBuilder.kt +++ b/src/main/kotlin/io/bazel/kotlin/builder/tasks/KotlinBuilder.kt @@ -16,8 +16,8 @@ */ package io.bazel.kotlin.builder.tasks -import io.bazel.kotlin.builder.tasks.common.KotlinKlibTaskExecutor import io.bazel.kotlin.builder.tasks.jvm.KotlinJvmTaskExecutor +import io.bazel.kotlin.builder.tasks.klib.KotlinKlibTaskExecutor import io.bazel.kotlin.builder.toolchain.CompilationStatusException import io.bazel.kotlin.builder.toolchain.CompilationTaskContext import io.bazel.kotlin.builder.utils.ArgMap @@ -25,7 +25,11 @@ import io.bazel.kotlin.builder.utils.ArgMaps import io.bazel.kotlin.builder.utils.Flag import io.bazel.kotlin.builder.utils.partitionJvmSources import io.bazel.kotlin.builder.utils.resolveNewDirectories -import io.bazel.kotlin.model.* +import io.bazel.kotlin.model.CompilationTaskInfo +import io.bazel.kotlin.model.JvmCompilationTask +import io.bazel.kotlin.model.KlibCompilationTask +import io.bazel.kotlin.model.Platform +import io.bazel.kotlin.model.RuleKind import io.bazel.worker.WorkerContext import java.nio.charset.StandardCharsets import java.nio.file.FileSystems @@ -89,7 +93,7 @@ class KotlinBuilder KSP_GENERATED_JAVA_SRCJAR("--ksp_generated_java_srcjar"), BUILD_TOOLS_API("--build_tools_api"), KLIBS("--klibs"), - OUTPUT_KLIB("--output_klib") + OUTPUT_KLIB("--output_klib"), } } @@ -191,36 +195,40 @@ class KotlinBuilder jvmTaskExecutor.execute(context, task) } - private fun executeKlibTask( - context: CompilationTaskContext, - workingDir: Path, - argMap: ArgMap, - ) { - val task = buildKlibTask(context.info, workingDir, argMap) - context.whenTracing { printProto("klib common task input", task) } - buildKlibTask(context.info, workingDir, argMap) - klibTaskExecutor.execute(context, task) - } + private fun executeKlibTask( + context: CompilationTaskContext, + workingDir: Path, + argMap: ArgMap, + ) { + val task = buildKlibTask(context.info, workingDir, argMap) + context.whenTracing { printProto("klib common task input", task) } + buildKlibTask(context.info, workingDir, argMap) + klibTaskExecutor.execute(context, task) + } - private fun buildKlibTask(info: CompilationTaskInfo, workingDir: Path, argMap: ArgMap): KlibCompilationTask = - with(KlibCompilationTask.newBuilder()) { - this.info = info - with(directoriesBuilder) { - temp = workingDir.toString() - } + private fun buildKlibTask( + info: CompilationTaskInfo, + workingDir: Path, + argMap: ArgMap, + ): KlibCompilationTask = + with(KlibCompilationTask.newBuilder()) { + this.info = info + with(directoriesBuilder) { + temp = workingDir.toString() + } - with(inputsBuilder) { - argMap.optional(KotlinBuilderFlags.KLIBS)?.let{ - addAllLibraries(it) - } - addAllKotlinSources(argMap.mandatory(KotlinBuilderFlags.SOURCES)) - } + with(inputsBuilder) { + argMap.optional(KotlinBuilderFlags.KLIBS)?.let { + addAllLibraries(it) + } + addAllKotlinSources(argMap.mandatory(KotlinBuilderFlags.SOURCES)) + } - with(outputsBuilder) { - this.setKlib(argMap.mandatorySingle(KotlinBuilderFlags.OUTPUT_KLIB)) - } - build() - } + with(outputsBuilder) { + this.setKlib(argMap.mandatorySingle(KotlinBuilderFlags.OUTPUT_KLIB)) + } + build() + } private fun buildJvmTask( info: CompilationTaskInfo, diff --git a/src/main/kotlin/io/bazel/kotlin/builder/tasks/common/KotlinKlibTaskExecutor.kt b/src/main/kotlin/io/bazel/kotlin/builder/tasks/common/KotlinKlibTaskExecutor.kt deleted file mode 100644 index b4f44c903..000000000 --- a/src/main/kotlin/io/bazel/kotlin/builder/tasks/common/KotlinKlibTaskExecutor.kt +++ /dev/null @@ -1,78 +0,0 @@ -package io.bazel.kotlin.builder.tasks.common - -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.KlibCompilationTask -import java.nio.file.FileSystem -import java.nio.file.FileSystems -import java.nio.file.Files -import java.nio.file.Path -import java.util.stream.Collectors -import javax.inject.Inject -import javax.inject.Singleton -import kotlin.io.path.absolute -import kotlin.io.path.absolutePathString -import kotlin.io.path.exists - -@Singleton -class KotlinKlibTaskExecutor -@Inject -constructor( - private val invoker: KotlinToolchain.K2NativeCompilerInvoker, -) { - private val fileSystem: FileSystem = FileSystems.getDefault() - - fun execute( - context: CompilationTaskContext, - task: KlibCompilationTask, - ) { - task.compile(context) - } - - private fun KlibCompilationTask.workingDirectory(): Path = fileSystem.getPath(directories.temp) - - private fun KlibCompilationTask.commonArgs(): MutableList { - val workDir = workingDirectory() - if (!workDir.exists()) { - workDir.toFile().mkdirs() - } - - val execRoot = fileSystem.getPath(".").absolute() - return mutableListOf().apply { - addAll(passThroughFlagsList) - addAll( - "-library", - inputs.librariesList - .map { - execRoot - .resolve( - it, - ).absolutePathString() - }.joinToString(":"), - ) - addAll("-module-name=${info.moduleName}") - addAll(inputs.kotlinSourcesList.map { execRoot.resolve(it).absolutePathString() }) - } - } - - private fun KlibCompilationTask.compile(context: CompilationTaskContext) { - val args = commonArgs() - val klibOut = fileSystem.getPath(outputs.klib) - args.addAll("-produce", "library") - context.whenTracing { printLines("klib compile args", args) } - - val outputDirectory = klibOut.parent - val workDir = workingDirectory() - - context.executeCompilerTask(args, invoker::compile) - context.whenTracing { - printLines( - "outputs", - Files.walk(outputDirectory).map { p -> p.toString() }.collect(Collectors.toList()), - ) - } - Files.copy(workDir.resolve(klibOut.fileName), klibOut) - } - -} diff --git a/src/main/kotlin/io/bazel/kotlin/builder/tasks/klib/KotlinKlibTaskExecutor.kt b/src/main/kotlin/io/bazel/kotlin/builder/tasks/klib/KotlinKlibTaskExecutor.kt new file mode 100644 index 000000000..dba7542b8 --- /dev/null +++ b/src/main/kotlin/io/bazel/kotlin/builder/tasks/klib/KotlinKlibTaskExecutor.kt @@ -0,0 +1,87 @@ +package io.bazel.kotlin.builder.tasks.klib + +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.KlibCompilationTask +import java.nio.file.FileSystem +import java.nio.file.FileSystems +import java.nio.file.Files +import java.nio.file.Path +import java.util.stream.Collectors +import javax.inject.Inject +import javax.inject.Singleton +import kotlin.io.path.absolute +import kotlin.io.path.absolutePathString +import kotlin.io.path.exists +import kotlin.io.path.pathString + +@Singleton +class KotlinKlibTaskExecutor + @Inject + constructor( + private val invoker: KotlinToolchain.K2NativeCompilerInvoker, + ) { + private val fileSystem: FileSystem = FileSystems.getDefault() + + fun execute( + context: CompilationTaskContext, + task: KlibCompilationTask, + ) { + task.compile(context) + } + + private fun KlibCompilationTask.workingDirectory(): Path = fileSystem.getPath(directories.temp) + + private fun KlibCompilationTask.commonArgs(): MutableList { + val workDir = workingDirectory() + if (!workDir.exists()) { + workDir.toFile().mkdirs() + } + + 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(".").absolute() + return mutableListOf().apply { + addAll(passThroughFlagsList) + // kotlin-native klib compilation requires caching and no way to disable, so pass a temp directory + // within the current working directory to isolate its cache (which is unique to this worker anyway) + // Ideally we disable caching though and rely only on Bazel + add("-Xauto-cache-dir=${autoCacheDirectory.absolutePathString()}") + add("-Xauto-cache-from=${autoCacheFromDirectory.absolutePathString()}") + add("-Xklib-normalize-absolute-path") + addAll("-module-name=${info.moduleName}") + addAll(inputs.kotlinSourcesList.map { execRoot.resolve(it).absolutePathString() }) + } + } + + private fun KlibCompilationTask.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/compiler/BazeK2NativeCompiler.kt b/src/main/kotlin/io/bazel/kotlin/compiler/BazelK2NativeCompiler.kt similarity index 89% rename from src/main/kotlin/io/bazel/kotlin/compiler/BazeK2NativeCompiler.kt rename to src/main/kotlin/io/bazel/kotlin/compiler/BazelK2NativeCompiler.kt index 0eb8bcc85..30e6cdf4d 100644 --- a/src/main/kotlin/io/bazel/kotlin/compiler/BazeK2NativeCompiler.kt +++ b/src/main/kotlin/io/bazel/kotlin/compiler/BazelK2NativeCompiler.kt @@ -28,6 +28,10 @@ class BazelK2NativeCompiler { vararg args: String, ): ExitCode { System.setProperty("zip.handler.uses.crc.instead.of.timestamp", "true") + val konanHome = System.getenv("KONAN_HOME") + requireNotNull(konanHome) {"KONAN_HOME env var must be set!"} + + System.setProperty("konan.home", konanHome) val delegate = K2Native() val arguments = delegate.createArguments().also { delegate.parseArguments(args, it) } 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 index d2696332a..8a8241d21 100644 --- 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 @@ -12,6 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. load("@bazel_skylib//:bzl_library.bzl", "bzl_library") +load("@aspect_bazel_lib//lib:copy_to_directory.bzl", "copy_to_directory") +load("@bazel_skylib//rules:write_file.bzl", "write_file") + package(default_visibility = ["//visibility:public"]) @@ -20,11 +23,23 @@ filegroup( srcs = glob(["bin/**"]), ) -filegroup( +write_file( + name = "klib_system_cache_marker", + out = "klib/cache/macos_arm64STATIC/klib_cache_marker", + content = [ + "Marker file intended to create the klib system cache placeholder even if we don't use it. The native compiler errors out otherwise", + "See See https://github.com/JetBrains/kotlin/blob/v2.1.21/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt#L567" + ], +) + + +copy_to_directory( name = "konan_home", - srcs = glob(["konan/**"]) + # TODO: figure out if all files are needed + srcs = glob(["konan/**", "klib/**"]) + [":klib_system_cache_marker"], ) + filegroup( name = "konan_properties", srcs = ["konan/konan.properties"], diff --git a/src/test/data/common/BUILD.bazel b/src/test/data/common/BUILD.bazel deleted file mode 100644 index dd3e261fa..000000000 --- a/src/test/data/common/BUILD.bazel +++ /dev/null @@ -1,6 +0,0 @@ -load("//kotlin/internal/common:common.bzl", "kt_klib_library") - -kt_klib_library( - name = "basic", - srcs = ["basic/Hello.kt"], -) diff --git a/src/test/data/common/basic/Hello.kt b/src/test/data/common/basic/Hello.kt deleted file mode 100644 index c9120dde3..000000000 --- a/src/test/data/common/basic/Hello.kt +++ /dev/null @@ -1,3 +0,0 @@ -fun sayHello() { - println("Hello, world!") -} diff --git a/src/test/data/klib/BUILD.bazel b/src/test/data/klib/BUILD.bazel new file mode 100644 index 000000000..0bdcd940d --- /dev/null +++ b/src/test/data/klib/BUILD.bazel @@ -0,0 +1,26 @@ +load("//kotlin/internal/klib:klib.bzl", "kt_klib_library") + +kt_klib_library( + name = "basic", + srcs = ["basic/Hello.kt"], +) + +kt_klib_library( + name = "deps_greeting", + srcs = ["deps/data/Greeting.kt"], +) + +kt_klib_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/klib/basic/Hello.kt b/src/test/data/klib/basic/Hello.kt new file mode 100644 index 000000000..e4a5e73f3 --- /dev/null +++ b/src/test/data/klib/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/klib/deps/Main.kt b/src/test/data/klib/deps/Main.kt new file mode 100644 index 000000000..8507ec84f --- /dev/null +++ b/src/test/data/klib/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/klib/deps/data/Greeting.kt b/src/test/data/klib/deps/data/Greeting.kt new file mode 100644 index 000000000..a19859e1e --- /dev/null +++ b/src/test/data/klib/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..0a9fa3ebe 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/klib: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..3d14a303c --- /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/klib") { + @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..ddbb11167 100644 --- a/src/test/kotlin/io/bazel/kotlin/builder/KotlinJvmTestBuilder.java +++ b/src/test/kotlin/io/bazel/kotlin/builder/KotlinJvmTestBuilder.java @@ -40,7 +40,8 @@ public final class KotlinJvmTestBuilder extends KotlinAbstractTestBuilder ALL_DIRECTORY_TYPES = diff --git a/src/test/starlark/internal/klib/BUILD.bazel b/src/test/starlark/internal/klib/BUILD.bazel new file mode 100644 index 000000000..137d2d61d --- /dev/null +++ b/src/test/starlark/internal/klib/BUILD.bazel @@ -0,0 +1,3 @@ +load(":klib_tests.bzl", "kt_klib_test_suite") + +kt_klib_test_suite(name = "klib_tests") diff --git a/src/test/starlark/internal/klib/klib_tests.bzl b/src/test/starlark/internal/klib/klib_tests.bzl new file mode 100644 index 000000000..161fe98a8 --- /dev/null +++ b/src/test/starlark/internal/klib/klib_tests.bzl @@ -0,0 +1,53 @@ +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/klib:klib.bzl", "kt_klib_library") + +def _common_assertions(env, target): + # Assertions common to all kt_klib_library tests + target_subject = env.expect.that_target(target) + target_subject.has_provider(KtKlibInfo) + + action_subject = target_subject.action_named("KotlinKlibCompile") + action_subject.env().keys().contains("KONAN_HOME") + action_subject.argv().contains_at_least(["--rule_kind", "kt_klib_library", "--output_klib"]) + +def _test_kt_klib_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/klib/Basic.kt") + +def _test_kt_klib_basic(name): + kt_klib_library(name = "basic", srcs = ["Basic.kt"]) + + analysis_test(name, target = "basic", impl = _test_kt_klib_basic_impl) + +def _test_kt_klib_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/klib/Second.kt") + + # the klib from first compilation is passed as input + action_subject.inputs().contains("src/test/starlark/internal/klib/first.klib") + + # and it's passed through the arguments + action_subject.argv().contains_at_least(["--klibs"]) + +def _test_kt_klib_deps(name): + kt_klib_library(name = "first", srcs = ["First.kt"]) + + kt_klib_library(name = "second", srcs = ["Second.kt"], deps = [":first"]) + + analysis_test(name, target = "second", impl = _test_kt_klib_deps_impl) + +def kt_klib_test_suite(name): + test_suite( + name = name, + tests = [ + _test_kt_klib_basic, + _test_kt_klib_deps, + ], + ) From 3553ace02fb6660f61332927fbe01ee73b0b278f Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Sun, 13 Jul 2025 15:29:04 -0400 Subject: [PATCH 04/40] Fix cache marker for other platforms --- kotlin/compiler/compiler.bzl | 1 - .../kotlin/compiler/BazelK2NativeCompiler.kt | 2 +- ...D.com_github_jetbrains_kotlin_native.bazel | 23 ++++++++++++++++--- .../starlark/internal/klib/klib_tests.bzl | 6 ++--- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/kotlin/compiler/compiler.bzl b/kotlin/compiler/compiler.bzl index cecaab295..5c65f39d2 100644 --- a/kotlin/compiler/compiler.bzl +++ b/kotlin/compiler/compiler.bzl @@ -13,7 +13,6 @@ # limitations under the License. load("@com_github_jetbrains_kotlin//:artifacts.bzl", "KOTLINC_ARTIFACTS", "KOTLIN_NATIVE_ARTIFACTS") -load("@rules_java//java:defs.bzl", "java_binary") load("//kotlin:jvm.bzl", "kt_jvm_import") load("//kotlin/internal:defs.bzl", _KT_COMPILER_REPO = "KT_COMPILER_REPO", _KT_NATIVE_COMPILER_REPO_PREFIX = "KT_NATIVE_COMPILER_REPO_PREFIX") diff --git a/src/main/kotlin/io/bazel/kotlin/compiler/BazelK2NativeCompiler.kt b/src/main/kotlin/io/bazel/kotlin/compiler/BazelK2NativeCompiler.kt index 30e6cdf4d..41f02024b 100644 --- a/src/main/kotlin/io/bazel/kotlin/compiler/BazelK2NativeCompiler.kt +++ b/src/main/kotlin/io/bazel/kotlin/compiler/BazelK2NativeCompiler.kt @@ -29,7 +29,7 @@ class BazelK2NativeCompiler { ): ExitCode { System.setProperty("zip.handler.uses.crc.instead.of.timestamp", "true") val konanHome = System.getenv("KONAN_HOME") - requireNotNull(konanHome) {"KONAN_HOME env var must be set!"} + requireNotNull(konanHome) { "KONAN_HOME env var must be set!" } System.setProperty("konan.home", konanHome) 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 index 8a8241d21..d3bfac5cb 100644 --- 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 @@ -11,7 +11,6 @@ # 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") load("@aspect_bazel_lib//lib:copy_to_directory.bzl", "copy_to_directory") load("@bazel_skylib//rules:write_file.bzl", "write_file") @@ -24,7 +23,7 @@ filegroup( ) write_file( - name = "klib_system_cache_marker", + name = "klib_system_cache_marker_macos_arm64", out = "klib/cache/macos_arm64STATIC/klib_cache_marker", content = [ "Marker file intended to create the klib system cache placeholder even if we don't use it. The native compiler errors out otherwise", @@ -32,11 +31,29 @@ write_file( ], ) +write_file( + name = "klib_system_cache_marker_linux_x64", + out = "klib/cache/linux_x64STATIC/klib_cache_marker", + content = [ + "Marker file intended to create the klib system cache placeholder even if we don't use it. The native compiler errors out otherwise", + "See See https://github.com/JetBrains/kotlin/blob/v2.1.21/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt#L567" + ], +) + +write_file( + name = "klib_system_cache_marker_macos_x64", + out = "klib/cache/macos_x64STATIC/klib_cache_marker", + content = [ + "Marker file intended to create the klib system cache placeholder even if we don't use it. The native compiler errors out otherwise", + "See See https://github.com/JetBrains/kotlin/blob/v2.1.21/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt#L567" + ], +) + copy_to_directory( name = "konan_home", # TODO: figure out if all files are needed - srcs = glob(["konan/**", "klib/**"]) + [":klib_system_cache_marker"], + srcs = glob(["konan/**", "klib/**"]) + [":klib_system_cache_marker_macos_arm64", ":klib_system_cache_marker_linux_x64", ":klib_system_cache_marker_macos_x64"], ) diff --git a/src/test/starlark/internal/klib/klib_tests.bzl b/src/test/starlark/internal/klib/klib_tests.bzl index 161fe98a8..2d47f4ea2 100644 --- a/src/test/starlark/internal/klib/klib_tests.bzl +++ b/src/test/starlark/internal/klib/klib_tests.bzl @@ -19,7 +19,7 @@ def _test_kt_klib_basic_impl(env, target): action_subject.inputs().contains("src/test/starlark/internal/klib/Basic.kt") def _test_kt_klib_basic(name): - kt_klib_library(name = "basic", srcs = ["Basic.kt"]) + kt_klib_library(name = "basic", srcs = ["Basic.kt"], tags = ["manual"]) analysis_test(name, target = "basic", impl = _test_kt_klib_basic_impl) @@ -37,9 +37,9 @@ def _test_kt_klib_deps_impl(env, target): action_subject.argv().contains_at_least(["--klibs"]) def _test_kt_klib_deps(name): - kt_klib_library(name = "first", srcs = ["First.kt"]) + kt_klib_library(name = "first", srcs = ["First.kt"], tags = ["manual"]) - kt_klib_library(name = "second", srcs = ["Second.kt"], deps = [":first"]) + kt_klib_library(name = "second", srcs = ["Second.kt"], deps = [":first"], tags = ["manual"]) analysis_test(name, target = "second", impl = _test_kt_klib_deps_impl) From d2a3ca9ff4dec44ff9ecb6382946b3cefb1d33e3 Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Sun, 13 Jul 2025 15:30:19 -0400 Subject: [PATCH 05/40] buildifier --- ...D.com_github_jetbrains_kotlin_native.bazel | 27 ++++++++++--------- .../BUILD.kotlin-native_capabilities.bazel | 2 +- 2 files changed, 15 insertions(+), 14 deletions(-) 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 index d3bfac5cb..d3aa621da 100644 --- 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 @@ -14,7 +14,6 @@ load("@aspect_bazel_lib//lib:copy_to_directory.bzl", "copy_to_directory") load("@bazel_skylib//rules:write_file.bzl", "write_file") - package(default_visibility = ["//visibility:public"]) filegroup( @@ -24,39 +23,44 @@ filegroup( write_file( name = "klib_system_cache_marker_macos_arm64", - out = "klib/cache/macos_arm64STATIC/klib_cache_marker", + out = "klib/cache/macos_arm64STATIC/klib_cache_marker", content = [ "Marker file intended to create the klib system cache placeholder even if we don't use it. The native compiler errors out otherwise", - "See See https://github.com/JetBrains/kotlin/blob/v2.1.21/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt#L567" + "See See https://github.com/JetBrains/kotlin/blob/v2.1.21/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt#L567", ], ) write_file( name = "klib_system_cache_marker_linux_x64", - out = "klib/cache/linux_x64STATIC/klib_cache_marker", + out = "klib/cache/linux_x64STATIC/klib_cache_marker", content = [ "Marker file intended to create the klib system cache placeholder even if we don't use it. The native compiler errors out otherwise", - "See See https://github.com/JetBrains/kotlin/blob/v2.1.21/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt#L567" + "See See https://github.com/JetBrains/kotlin/blob/v2.1.21/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt#L567", ], ) write_file( name = "klib_system_cache_marker_macos_x64", - out = "klib/cache/macos_x64STATIC/klib_cache_marker", + out = "klib/cache/macos_x64STATIC/klib_cache_marker", content = [ "Marker file intended to create the klib system cache placeholder even if we don't use it. The native compiler errors out otherwise", - "See See https://github.com/JetBrains/kotlin/blob/v2.1.21/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt#L567" + "See See https://github.com/JetBrains/kotlin/blob/v2.1.21/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt#L567", ], ) - copy_to_directory( name = "konan_home", # TODO: figure out if all files are needed - srcs = glob(["konan/**", "klib/**"]) + [":klib_system_cache_marker_macos_arm64", ":klib_system_cache_marker_linux_x64", ":klib_system_cache_marker_macos_x64"], + srcs = glob([ + "konan/**", + "klib/**", + ]) + [ + ":klib_system_cache_marker_linux_x64", + ":klib_system_cache_marker_macos_arm64", + ":klib_system_cache_marker_macos_x64", + ], ) - filegroup( name = "konan_properties", srcs = ["konan/konan.properties"], @@ -67,8 +71,6 @@ filegroup( srcs = glob(["klib/common/stdlib/**"]), ) - - # Have a filegroup for the kotlin-native jars that will be explicitly aliased [ filegroup( @@ -77,4 +79,3 @@ filegroup( ) for name in glob(["konan/lib/**"]) ] - diff --git a/src/main/starlark/core/repositories/BUILD.kotlin-native_capabilities.bazel b/src/main/starlark/core/repositories/BUILD.kotlin-native_capabilities.bazel index e55385d96..9ee1911fd 100644 --- a/src/main/starlark/core/repositories/BUILD.kotlin-native_capabilities.bazel +++ b/src/main/starlark/core/repositories/BUILD.kotlin-native_capabilities.bazel @@ -37,4 +37,4 @@ alias( actual = "@$git_repo$//:%s" % file.replace(".", "_"), ) for (label, file) in KOTLIN_NATIVE_ARTIFACT_LIST.items() -] \ No newline at end of file +] From f0385a306d5f3894af4103fa0ac9b29edab467f0 Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Sun, 13 Jul 2025 18:12:45 -0400 Subject: [PATCH 06/40] remove unused stuff --- .../kotlin/io/bazel/kotlin/builder/KotlinJvmTestBuilder.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/test/kotlin/io/bazel/kotlin/builder/KotlinJvmTestBuilder.java b/src/test/kotlin/io/bazel/kotlin/builder/KotlinJvmTestBuilder.java index ddbb11167..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; @@ -40,8 +39,7 @@ public final class KotlinJvmTestBuilder extends KotlinAbstractTestBuilder ALL_DIRECTORY_TYPES = From b1083088c33000724c4dfa0df3997621807f3731 Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Sun, 13 Jul 2025 20:02:27 -0400 Subject: [PATCH 07/40] remove opts.native.bzl --- .../starlark/core/options/opts.native.bzl | 494 ------------------ 1 file changed, 494 deletions(-) delete mode 100644 src/main/starlark/core/options/opts.native.bzl diff --git a/src/main/starlark/core/options/opts.native.bzl b/src/main/starlark/core/options/opts.native.bzl deleted file mode 100644 index 1c66319a6..000000000 --- a/src/main/starlark/core/options/opts.native.bzl +++ /dev/null @@ -1,494 +0,0 @@ -# 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("@com_github_jetbrains_kotlin//:capabilities.bzl", _KOTLIN_OPTS = "KOTLIN_OPTS") -load("//src/main/starlark/core/options:convert.bzl", "convert") -load("//src/main/starlark/core/options:derive.bzl", "derive") - -def _map_optin_class_to_flag(values): - return ["-opt-in=%s" % v for v in values] - -def _map_backend_threads_to_flag(n): - if n == 1: - return None - return ["-Xbackend-threads=%d" % n] - -def _map_jvm_target_to_flag(version): - if not version: - return None - return ["-jvm-target=%s" % version] - -def _map_jdk_release_to_flag(version): - if not version: - return None - return ["-Xjdk-release=%s" % version] - -_KOPTS_ALL = { - "warn": struct( - args = dict( - default = "report", - doc = "Control warning behaviour.", - values = ["off", "report", "error"], - ), - type = attr.string, - value_to_flag = { - "off": ["-nowarn"], - "report": None, - "error": ["-Werror"], - }, - ), - "include_stdlibs": struct( - args = dict( - default = "all", - doc = "Don't automatically include the Kotlin standard libraries into the classpath (stdlib and reflect).", - values = ["all", "stdlib", "none"], - ), - type = attr.string, - value_to_flag = { - "all": None, - "stdlib": ["-no-reflect"], - "none": ["-no-stdlib"], - }, - ), - "x_skip_prerelease_check": struct( - flag = "-Xskip-prerelease-check", - args = dict( - default = False, - doc = "Suppress errors thrown when using pre-release classes.", - ), - type = attr.bool, - value_to_flag = { - True: ["-Xskip-prerelease-check"], - }, - ), - "x_context_receivers": struct( - flag = "-Xcontext-receivers", - args = dict( - default = False, - doc = "Enable experimental context receivers.", - ), - type = attr.bool, - value_to_flag = { - True: ["-Xcontext-receivers"], - }, - ), - "x_suppress_version_warnings": struct( - flag = "-Xsuppress-version-warnings", - args = dict( - default = False, - doc = "Suppress warnings about outdated, inconsistent, or experimental language or API versions.", - ), - type = attr.bool, - value_to_flag = { - True: ["-Xsuppress-version-warnings"], - }, - ), - "x_inline_classes": struct( - flag = "-Xinline-classes", - args = dict( - default = False, - doc = "Enable experimental inline classes", - ), - type = attr.bool, - value_to_flag = { - True: ["-Xinline-classes"], - }, - ), - "x_allow_result_return_type": struct( - flag = "-Xallow-result-return-type", - args = dict( - default = False, - doc = "Enable kotlin.Result as a return type", - ), - type = attr.bool, - value_to_flag = { - True: ["-Xallow-result-return-type"], - }, - ), - "x_jvm_default": struct( - flag = "-Xjvm-default", - args = dict( - default = "off", - doc = "Specifies that a JVM default method should be generated for non-abstract Kotlin interface member.", - values = ["off", "enable", "disable", "compatibility", "all-compatibility", "all"], - ), - type = attr.string, - value_to_flag = { - "off": None, - "enable": ["-Xjvm-default=enable"], - "disable": ["-Xjvm-default=disable"], - "compatibility": ["-Xjvm-default=compatibility"], - "all-compatibility": ["-Xjvm-default=all-compatibility"], - "all": ["-Xjvm-default=all"], - }, - ), - "x_no_call_assertions": struct( - flag = "-Xno-call-assertions", - args = dict( - default = False, - doc = "Don't generate not-null assertions for arguments of platform types", - ), - type = attr.bool, - value_to_flag = { - True: ["-Xno-call-assertions"], - }, - ), - "x_no_param_assertions": struct( - flag = "-Xno-param-assertions", - args = dict( - default = False, - doc = "Don't generate not-null assertions on parameters of methods accessible from Java", - ), - type = attr.bool, - value_to_flag = { - True: ["-Xno-param-assertions"], - }, - ), - "x_no_receiver_assertions": struct( - flag = "-Xno-receiver-assertions", - args = dict( - default = False, - doc = "Don't generate not-null assertion for extension receiver arguments of platform types", - ), - type = attr.bool, - value_to_flag = { - True: ["-Xno-receiver-assertions"], - }, - ), - "x_no_optimized_callable_references": struct( - flag = "-Xno-optimized-callable-references", - args = dict( - default = False, - doc = "Do not use optimized callable reference superclasses. Available from 1.4.", - ), - type = attr.bool, - value_to_flag = { - True: ["-Xno-optimized-callable-references"], - }, - ), - "x_explicit_api_mode": struct( - flag = "-Xexplicit-api", - args = dict( - default = "off", - doc = "Enable explicit API mode for Kotlin libraries.", - values = ["off", "warning", "strict"], - ), - type = attr.string, - value_to_flag = { - "off": None, - "warning": ["-Xexplicit-api=warning"], - "strict": ["-Xexplicit-api=strict"], - }, - ), - "x_annotation_default_target": struct( - args = dict( - default = "off", - doc = """Change the default annotation targets for constructor properties: --Xannotation-default-target=first-only: use the first of the following allowed targets: '@param:', '@property:', '@field:'; --Xannotation-default-target=first-only-warn: same as first-only, and raise warnings when both '@param:' and either '@property:' or '@field:' are allowed; --Xannotation-default-target=param-property: use '@param:' target if applicable, and also use the first of either '@property:' or '@field:'; -default: 'first-only-warn' in language version 2.2+, 'first-only' in version 2.1 and before.""", - values = ["off", "first-only", "first-only-warn", "param-property"], - ), - type = attr.string, - value_to_flag = { - "off": None, - "first-only": ["-Xannotation-default-target=first-only"], - "first-only-warn": ["-Xannotation-default-target=first-only-warn"], - "param-property": ["-Xannotation-default-target=param-property"], - }, - ), - "java_parameters": struct( - args = dict( - default = False, - doc = "Generate metadata for Java 1.8+ reflection on method parameters.", - ), - type = attr.bool, - value_to_flag = { - True: ["-java-parameters"], - }, - ), - "x_multi_platform": struct( - flag = "-Xmulti-platform", - args = dict( - default = False, - doc = "Enable experimental language support for multi-platform projects", - ), - type = attr.bool, - value_to_flag = { - True: ["-Xmulti-platform"], - }, - ), - "x_sam_conversions": struct( - flag = "-Xsam-conversions", - args = dict( - default = "class", - doc = "Change codegen behavior of SAM/functional interfaces", - values = ["class", "indy"], - ), - type = attr.string, - value_to_flag = { - "class": ["-Xsam-conversions=class"], - "indy": ["-Xsam-conversions=indy"], - }, - ), - "x_lambdas": struct( - flag = "-Xlambdas", - args = dict( - default = "class", - doc = "Change codegen behavior of lambdas", - values = ["class", "indy"], - ), - type = attr.string, - value_to_flag = { - "class": ["-Xlambdas=class"], - "indy": ["-Xlambdas=indy"], - }, - ), - "x_emit_jvm_type_annotations": struct( - flag = "-Xemit-jvm-type-annotations", - args = dict( - default = False, - doc = "Basic support for type annotations in JVM bytecode.", - ), - type = attr.bool, - value_to_flag = { - True: ["-Xemit-jvm-type-annotations"], - }, - ), - "x_optin": struct( - args = dict( - default = [], - doc = "Define APIs to opt-in to.", - ), - type = attr.string_list, - value_to_flag = None, - map_value_to_flag = _map_optin_class_to_flag, - ), - "x_use_fir": struct( - # 1.6 - flag = "-Xuse-fir", - args = dict( - default = False, - doc = "Compile using the experimental Kotlin Front-end IR. Available from 1.6.", - ), - type = attr.bool, - value_to_flag = { - True: ["-Xuse-fir"], - }, - ), - "x_use_k2": struct( - # 1.7 - flag = "-Xuse-k2", - args = dict( - default = False, - doc = "Compile using experimental K2. K2 is a new compiler pipeline, no compatibility guarantees are yet provided", - ), - type = attr.bool, - value_to_flag = { - True: ["-Xuse-k2"], - }, - ), - "x_no_optimize": struct( - flag = "-Xno-optimize", - args = dict( - default = False, - doc = "Disable optimizations", - ), - type = attr.bool, - value_to_flag = { - True: ["-Xno-optimize"], - }, - ), - "x_backend_threads": struct( - # 1.6.20, 1.7 - flag = "-Xbackend-threads", - args = dict( - default = 1, - doc = "When using the IR backend, run lowerings by file in N parallel threads. 0 means use a thread per processor core. Default value is 1.", - ), - type = attr.int, - value_to_flag = None, - map_value_to_flag = _map_backend_threads_to_flag, - ), - "x_enable_incremental_compilation": struct( - args = dict( - default = False, - doc = "Enable incremental compilation", - ), - type = attr.bool, - value_to_flag = { - True: ["-Xenable-incremental-compilation"], - }, - ), - "x_report_perf": struct( - flag = "-Xreport-perf", - args = dict( - default = False, - doc = "Report detailed performance statistics", - ), - type = attr.bool, - value_to_flag = { - True: ["-Xreport-perf"], - }, - ), - "x_use_fir_lt": struct( - args = dict( - default = False, - doc = "Compile using LightTree parser with Front-end IR. Warning: this feature is far from being production-ready", - ), - type = attr.bool, - value_to_flag = { - True: ["-Xuse-fir-lt"], - }, - ), - "x_no_source_debug_extension": struct( - args = dict( - default = False, - doc = "Do not generate @kotlin.jvm.internal.SourceDebugExtension annotation on a class with the copy of SMAP", - ), - type = attr.bool, - value_to_flag = { - True: ["-Xno-source-debug-extension"], - }, - ), - "x_type_enhancement_improvements_strict_mode": struct( - args = dict( - default = False, - doc = "Enables strict mode for type enhancement improvements, enforcing stricter type checking and enhancements.", - ), - type = attr.bool, - value_to_flag = { - True: ["-Xtype-enhancement-improvements-strict-mode"], - }, - ), - "x_jsr_305": struct( - args = dict( - default = "", - doc = "Specifies how to handle JSR-305 annotations in Kotlin code. Options are 'default', 'ignore', 'warn', and 'strict'.", - values = ["default", "ignore", "warn", "strict"], - ), - type = attr.string, - value_to_flag = { - "default": None, - "ignore": ["-Xjsr305=ignore"], - "warn": ["-Xjsr305=warn"], - "strict": ["-Xjsr305=strict"], - }, - map_value_to_flag = None, - ), - "x_assertions": struct( - args = dict( - default = "", - doc = "Configures how assertions are handled. The 'jvm' option enables assertions in JVM code.", - values = ["jvm"], - ), - type = attr.string, - value_to_flag = { - "default": None, - "jvm": ["-Xassertions=jvm"], - }, - map_value_to_flag = None, - ), - "x_jspecify_annotations": struct( - args = dict( - default = "", - doc = "Controls how JSpecify annotations are treated. Options are 'default', 'ignore', 'warn', and 'strict'.", - values = ["default", "ignore", "warn", "strict"], - ), - type = attr.string, - value_to_flag = { - "default": None, - "ignore": ["-Xjspecify-annotations=ignore"], - "warn": ["-Xjspecify-annotations=warn"], - "strict": ["-Xjspecify-annotations=strict"], - }, - map_value_to_flag = None, - ), - "x_consistent_data_class_copy_visibility": struct( - args = dict( - default = False, - doc = "The effect of this compiler flag is the same as applying @ConsistentCopyVisibility annotation to all data classes in the module. See https://youtrack.jetbrains.com/issue/KT-11914", - ), - type = attr.bool, - value_to_flag = { - True: ["-Xconsistent-data-class-copy-visibility"], - }, - ), - "jvm_target": struct( - args = dict( - default = "", - doc = "The target version of the generated JVM bytecode", - values = ["1.6", "1.8", "9", "10", "11", "12", "13", "15", "16", "17"], - ), - type = attr.string, - value_to_flag = None, - map_value_to_flag = _map_jvm_target_to_flag, - ), - "x_jdk_release": struct( - args = dict( - default = "", - doc = """Compile against the specified JDK API version, similarly to javac's '-release'. This requires JDK 9 or newer. - The supported versions depend on the JDK used; for JDK 17+, the supported versions are 1.8 and 9–21. - This also sets the value of '-jvm-target' to be equal to the selected JDK version.""", - values = ["1.6", "1.8", "9", "10", "11", "12", "13", "15", "16", "17"], - ), - type = attr.string, - value_to_flag = None, - map_value_to_flag = _map_jdk_release_to_flag, - ), - "x_suppress_warning": struct( - args = dict( - default = [], - doc = "Suppress specific warnings globally", - ), - type = attr.string_list, - value_to_flag = { - derive.info: derive.repeated_values_for("-Xsuppress-warning="), - }, - ), -} - -def _merge(key, rule_defined): - """Merges rule option with compiler option.""" - if key not in _KOTLIN_OPTS: - # No flag associated with option. - return rule_defined - generated = _KOTLIN_OPTS[key] - merged = {k: getattr(k, rule_defined) for k in dir(rule_defined)} - merged["doc"] = generated.doc - merged["default"] = generated.default - return struct(**merged) - -def _no_merge(_, definition): - return definition - -_maybe_merge_definition = _merge if hasattr(_KOTLIN_OPTS, "get") else _no_merge - -# Filters out options that are not available in current compiler release -_KOPTS = { - attr: _maybe_merge_definition(attr, defn) - for (attr, defn) in _KOPTS_ALL.items() - if not hasattr(defn, "flag") or defn.flag in _KOTLIN_OPTS -} - -KotlincOptions = provider( - fields = { - name: o.args["doc"] - for name, o in _KOPTS.items() - }, -) - -def _kotlinc_options_impl(ctx): - return [KotlincOptions(**{n: getattr(ctx.attr, n, None) for n in _KOPTS})] From 5d6557abc1663a7de553df4fc8d5a16da6333655 Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Sun, 13 Jul 2025 20:12:01 -0400 Subject: [PATCH 08/40] Fix builder tests --- src/test/kotlin/io/bazel/kotlin/builder/BUILD | 1 + src/test/kotlin/io/bazel/kotlin/defs.bzl | 1 + 2 files changed, 2 insertions(+) diff --git a/src/test/kotlin/io/bazel/kotlin/builder/BUILD b/src/test/kotlin/io/bazel/kotlin/builder/BUILD index 010f6a407..35f8cf733 100644 --- a/src/test/kotlin/io/bazel/kotlin/builder/BUILD +++ b/src/test/kotlin/io/bazel/kotlin/builder/BUILD @@ -39,6 +39,7 @@ java_library( "KotlinJvmTestBuilder.java", ], data = [ + "//kotlin/compiler:kotlin-native", "//src/main/kotlin/io/bazel/kotlin/compiler", "@com_github_jetbrains_kotlin//:home", ], 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", From fa6291e9c01c9bb8faf735b8456f5271a929d53b Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Sun, 13 Jul 2025 22:44:25 -0400 Subject: [PATCH 09/40] Add capabilties.bzl to release archive --- src/main/starlark/core/repositories/BUILD | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/starlark/core/repositories/BUILD b/src/main/starlark/core/repositories/BUILD index aa441ab31..6d4e716bf 100644 --- a/src/main/starlark/core/repositories/BUILD +++ b/src/main/starlark/core/repositories/BUILD @@ -22,6 +22,7 @@ release_archive( "BUILD.com_github_jetbrains_kotlin_native.bazel", "BUILD.kotlin_capabilities.bazel", "bzlmod_impl.bzl", + "capabilities.bzl", "compiler.bzl", "ksp.bzl", "native.bzl", From 685e4d7cb1495beb1d2709301f5c56696d6570e2 Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Sun, 13 Jul 2025 22:46:51 -0400 Subject: [PATCH 10/40] Add BUILD.kotlin-native_capabilities.bazel to release archive --- src/main/starlark/core/repositories/BUILD | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/starlark/core/repositories/BUILD b/src/main/starlark/core/repositories/BUILD index 6d4e716bf..550ebae31 100644 --- a/src/main/starlark/core/repositories/BUILD +++ b/src/main/starlark/core/repositories/BUILD @@ -20,6 +20,7 @@ release_archive( "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", From 126931f92f8783118bf39ab72ed342c502aeb67d Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Sat, 2 Aug 2025 18:55:05 -0400 Subject: [PATCH 11/40] Feedback: Remove duplicate code and pass transitive klibs --- kotlin/internal/klib/klib.bzl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/kotlin/internal/klib/klib.bzl b/kotlin/internal/klib/klib.bzl index 46117b766..b5f7a282a 100644 --- a/kotlin/internal/klib/klib.bzl +++ b/kotlin/internal/klib/klib.bzl @@ -10,8 +10,12 @@ def _kt_klib_library(ctx): toolchains = ctx.toolchains[_TOOLCHAIN_TYPE] deps_klibs = [] + transitive_klibs = [] for dep in ctx.attr.deps: deps_klibs.append(dep[_KtKlibInfo].klibs) + deps_klibs.append(dep[_KtKlibInfo].transitive_klibs) + transitive_klibs.append(dep[_KtKlibInfo].transitive_klibs) + libraries = depset(transitive = deps_klibs) builder_args.add_all("--sources", ctx.files.srcs) builder_inputs, _, input_manifests = ctx.resolve_command(tools = [toolchains.kotlinbuilder, toolchains.konan_home]) @@ -20,9 +24,6 @@ def _kt_klib_library(ctx): builder_args.add("--reduced_classpath_mode", "off") builder_args.add("--output_klib", klib.path) - deps_klibs = [] - for dep in ctx.attr.deps: - deps_klibs.append(dep[_KtKlibInfo].klibs) libraries = depset(transitive = deps_klibs) builder_args.add_all("--klibs", libraries, omit_if_empty = False) @@ -54,6 +55,7 @@ def _kt_klib_library(ctx): DefaultInfo(files = depset(outputs)), _KtKlibInfo( klibs = depset(outputs), + transitive_klibs = depset(transitive = transitive_klibs), ), ] From cefedcb0a6291c89d21c02d8c40b3d2cb99d2496 Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Sun, 3 Aug 2025 19:38:14 -0400 Subject: [PATCH 12/40] wip: Remove copy_to_directory and create a dedicated native toolchain --- MODULE.bazel | 4 +- kotlin/compiler/compiler.bzl | 8 +- kotlin/internal/defs.bzl | 1 + kotlin/internal/klib/BUILD.bazel | 3 + kotlin/internal/klib/klib.bzl | 19 +++-- kotlin/internal/klib/toolchains.bzl | 79 +++++++++++++++++++ kotlin/internal/toolchains.bzl | 6 -- src/main/starlark/core/compile/BUILD.bazel | 7 ++ src/main/starlark/core/compile/common.bzl | 1 + ...D.com_github_jetbrains_kotlin_native.bazel | 17 ++-- .../BUILD.kotlin-native_capabilities.bazel | 8 +- .../core/repositories/kotlin/artifacts.bzl | 78 ++++++++++++++++-- 12 files changed, 191 insertions(+), 40 deletions(-) create mode 100644 kotlin/internal/klib/toolchains.bzl diff --git a/MODULE.bazel b/MODULE.bazel index ee198325a..062536eca 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -19,8 +19,6 @@ bazel_dep(name = "rules_shell", version = "0.4.1") bazel_dep(name = "buildifier_prebuilt", version = "8.0.3", dev_dependency = True) -bazel_dep(name = "aspect_bazel_lib", version = "2.19.4") - rules_java_toolchains = use_extension("@rules_java//java:extensions.bzl", "toolchains") use_repo(rules_java_toolchains, "remote_java_tools") @@ -49,6 +47,8 @@ register_toolchains("//src/main/starlark/core/compile/cli") register_toolchains("//kotlin/internal:default_toolchain") +register_toolchains("//kotlin/internal/klib: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/kotlin/compiler/compiler.bzl b/kotlin/compiler/compiler.bzl index 5c65f39d2..339b05c5d 100644 --- a/kotlin/compiler/compiler.bzl +++ b/kotlin/compiler/compiler.bzl @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -load("@com_github_jetbrains_kotlin//:artifacts.bzl", "KOTLINC_ARTIFACTS", "KOTLIN_NATIVE_ARTIFACTS") +load("@com_github_jetbrains_kotlin//:artifacts.bzl", "KOTLINC_ARTIFACTS", "KOTLIN_NATIVE_ARTIFACTS_AND_TARGETS") load("//kotlin:jvm.bzl", "kt_jvm_import") load("//kotlin/internal:defs.bzl", _KT_COMPILER_REPO = "KT_COMPILER_REPO", _KT_NATIVE_COMPILER_REPO_PREFIX = "KT_NATIVE_COMPILER_REPO_PREFIX") @@ -63,10 +63,8 @@ def kt_configure_compiler(): _import_artifacts(KOTLINC_ARTIFACTS.jvm, kt_jvm_import) _import_artifacts(KOTLINC_ARTIFACTS.core, kt_jvm_import) - _import_artifacts(KOTLIN_NATIVE_ARTIFACTS.linux_x86_64, kt_jvm_import, compiler_repo = _KT_NATIVE_COMPILER_REPO_PREFIX + "_linux_x86_64") - _import_artifacts(KOTLIN_NATIVE_ARTIFACTS.macos_x86_64, kt_jvm_import, compiler_repo = _KT_NATIVE_COMPILER_REPO_PREFIX + "_macos_x86_64") - _import_artifacts(KOTLIN_NATIVE_ARTIFACTS.macos_aarch64, kt_jvm_import, compiler_repo = _KT_NATIVE_COMPILER_REPO_PREFIX + "_macos_aarch64") - _import_artifacts(KOTLIN_NATIVE_ARTIFACTS.windows_x86_64, kt_jvm_import, compiler_repo = _KT_NATIVE_COMPILER_REPO_PREFIX + "_windows_x86_64") + for platform in KOTLIN_NATIVE_ARTIFACTS_AND_TARGETS.keys(): + _import_artifacts(KOTLIN_NATIVE_ARTIFACTS_AND_TARGETS[platform], kt_jvm_import, compiler_repo = _KT_NATIVE_COMPILER_REPO_PREFIX + "_" + platform) # a convenience alias for kotlin-native to be referenced in other places native.alias( diff --git a/kotlin/internal/defs.bzl b/kotlin/internal/defs.bzl index 82b9ea89c..a98a656d8 100644 --- a/kotlin/internal/defs.bzl +++ b/kotlin/internal/defs.bzl @@ -28,6 +28,7 @@ load( # The Kotlin Toolchain type. TOOLCHAIN_TYPE = "%s" % Label("//kotlin/internal:kt_toolchain_type") +NATIVE_TOOLCHAIN_TYPE = "%s" % Label("//kotlin/internal/klib:kt_native_toolchain_type") # Java toolchains JAVA_TOOLCHAIN_TYPE = _JAVA_TOOLCHAIN_TYPE diff --git a/kotlin/internal/klib/BUILD.bazel b/kotlin/internal/klib/BUILD.bazel index e69de29bb..0f5dbd63e 100644 --- a/kotlin/internal/klib/BUILD.bazel +++ b/kotlin/internal/klib/BUILD.bazel @@ -0,0 +1,3 @@ +load("//kotlin/internal/klib:toolchains.bzl", "kt_configure_native_toolchains") + +kt_configure_native_toolchains() diff --git a/kotlin/internal/klib/klib.bzl b/kotlin/internal/klib/klib.bzl index b5f7a282a..43779898b 100644 --- a/kotlin/internal/klib/klib.bzl +++ b/kotlin/internal/klib/klib.bzl @@ -1,4 +1,4 @@ -load("//kotlin/internal:defs.bzl", _KtKlibInfo = "KtKlibInfo", _TOOLCHAIN_TYPE = "TOOLCHAIN_TYPE") +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_klib_library(ctx): @@ -9,6 +9,11 @@ def _kt_klib_library(ctx): 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 + deps_klibs = [] transitive_klibs = [] for dep in ctx.attr.deps: @@ -18,7 +23,7 @@ def _kt_klib_library(ctx): libraries = depset(transitive = deps_klibs) builder_args.add_all("--sources", ctx.files.srcs) - builder_inputs, _, input_manifests = ctx.resolve_command(tools = [toolchains.kotlinbuilder, toolchains.konan_home]) + builder_inputs, _, input_manifests = ctx.resolve_command(tools = [toolchains.kotlinbuilder]) builder_args.add("--strict_kotlin_deps", "off") builder_args.add("--reduced_classpath_mode", "off") @@ -27,19 +32,13 @@ def _kt_klib_library(ctx): libraries = depset(transitive = deps_klibs) builder_args.add_all("--klibs", libraries, omit_if_empty = False) - # This will be a directory we need to propagate to the compiler - konan_home = toolchains.konan_home[DefaultInfo].files.to_list()[0] - if not konan_home.is_directory: - fail("konan home must be a directory!") - ctx.actions.run( mnemonic = "KotlinKlibCompile", - inputs = depset(builder_inputs + ctx.files.srcs, transitive = [libraries]), + 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, - toolchains.konan_home[DefaultInfo].files_to_run, ], execution_requirements = {"supports-workers": "1"}, arguments = [ctx.actions.args().add_all(toolchains.builder_args), builder_args], @@ -75,6 +74,6 @@ to be shared between Kotlin code for different platforms (JS/JVM/WASM etc.). It providers = [_KtKlibInfo], ), }, - toolchains = [_TOOLCHAIN_TYPE], + toolchains = [_TOOLCHAIN_TYPE, _NATIVE_TOOLCHAIN_TYPE], provides = [_KtKlibInfo], ) diff --git a/kotlin/internal/klib/toolchains.bzl b/kotlin/internal/klib/toolchains.bzl new file mode 100644 index 000000000..9a41ae45d --- /dev/null +++ b/kotlin/internal/klib/toolchains.bzl @@ -0,0 +1,79 @@ +load("@bazel_skylib//rules/directory:providers.bzl", "DirectoryInfo") +load("//src/main/starlark/core/repositories/kotlin:artifacts.bzl", "KOTLIN_NATIVE_ARTIFACTS_AND_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", +}) + +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.get_subdirectory("konan") + + return [ + platform_common.ToolchainInfo( + kotlin_native_info = KotlinNativeToolchainInfo( + konan_home = konan_home, + konan_home_files = depset(direct = ctx.files.klib_cache_marker_files, transitive = [konan_home_info.transitive_files]), + konan_properties = konan_properties, + targets = ctx.attr.targets, + ), + ), + ] + +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 = [], + ), + "klib_cache_marker_files": attr.label( + doc = "Marker files generated to trick the Kotlin Native compiler to assume the local cache already exists. Without this, it fails to bootstrap the compiler because it expects the directory to exist.", + allow_files = True, + ), + }, + provides = [platform_common.ToolchainInfo], +) + +def kt_configure_native_toolchains(): + native.toolchain_type( + name = "kt_native_toolchain_type", + visibility = ["//visibility:public"], + ) + + # Create toolchains for each exec platform and their supported targets + for exec_platform, artifacts_and_targets in KOTLIN_NATIVE_ARTIFACTS_AND_TARGETS.items(): + for target_constraint_tuple, kotlin_native_targets in artifacts_and_targets.targets.items(): + target_os, target_cpu = target_constraint_tuple + + # Create a unique name for this toolchain + toolchain_name = "default_kt_native_toolchain_{}_to_{}_{}".format( + exec_platform, + target_os.split("//")[1].replace(":", "_").replace("/", "_"), + target_cpu.split("//")[1].replace(":", "_").replace("/", "_"), + ) + + # Create the toolchain implementation + kt_native_toolchain( + name = toolchain_name + "_impl", + konan_home = "@com_github_jetbrains_kotlin_native_{}//:konan_home".format(exec_platform), + targets = kotlin_native_targets, + klib_cache_marker_files = "@com_github_jetbrains_kotlin_native_{}//:klib_cache_marker_files".format(exec_platform), + ) + + # Register the toolchain + native.toolchain( + name = toolchain_name, + exec_compatible_with = artifacts_and_targets.exec_compatible_with, + target_compatible_with = [target_os, target_cpu], + toolchain = ":" + toolchain_name + "_impl", + toolchain_type = ":kt_native_toolchain_type", + ) diff --git a/kotlin/internal/toolchains.bzl b/kotlin/internal/toolchains.bzl index 24e6d2e58..d2196b73b 100644 --- a/kotlin/internal/toolchains.bzl +++ b/kotlin/internal/toolchains.bzl @@ -385,12 +385,6 @@ def define_kt_toolchain( jvm_runtime = jvm_runtime if jvm_runtime != None else [ Label("//kotlin/compiler:kotlin-stdlib"), ], - konan_home = select({ - "@bazel_tools//src/conditions:linux_x86_64": Label("@" + _KT_NATIVE_COMPILER_REPO_PREFIX + "_linux_x86_64//:konan_home"), - "@bazel_tools//src/conditions:darwin_arm64": Label("@" + _KT_NATIVE_COMPILER_REPO_PREFIX + "_macos_aarch64//:konan_home"), - "@bazel_tools//src/conditions:darwin_x86_64": Label("@" + _KT_NATIVE_COMPILER_REPO_PREFIX + "_macos_x86_64//:konan_home"), - "@bazel_tools//src/conditions:windows": Label("@" + _KT_NATIVE_COMPILER_REPO_PREFIX + "_windows_x86_64//:konan_home"), - }), ) native.toolchain( name = name, 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/common.bzl b/src/main/starlark/core/compile/common.bzl index 71791f086..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") 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 index d3aa621da..c8488a18d 100644 --- 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 @@ -11,11 +11,12 @@ # 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("@aspect_bazel_lib//lib:copy_to_directory.bzl", "copy_to_directory") load("@bazel_skylib//rules:write_file.bzl", "write_file") +load("@bazel_skylib//rules/directory:directory.bzl", "directory") package(default_visibility = ["//visibility:public"]) + filegroup( name = "bin", srcs = glob(["bin/**"]), @@ -48,17 +49,17 @@ write_file( ], ) -copy_to_directory( +directory( name = "konan_home", - # TODO: figure out if all files are needed srcs = glob([ "konan/**", "klib/**", - ]) + [ - ":klib_system_cache_marker_linux_x64", - ":klib_system_cache_marker_macos_arm64", - ":klib_system_cache_marker_macos_x64", - ], + ]), +) + +filegroup( + name = "klib_cache_marker_files", + srcs = [":klib_system_cache_marker_macos_arm64"], ) filegroup( diff --git a/src/main/starlark/core/repositories/BUILD.kotlin-native_capabilities.bazel b/src/main/starlark/core/repositories/BUILD.kotlin-native_capabilities.bazel index 9ee1911fd..27eccb7ec 100644 --- a/src/main/starlark/core/repositories/BUILD.kotlin-native_capabilities.bazel +++ b/src/main/starlark/core/repositories/BUILD.kotlin-native_capabilities.bazel @@ -31,10 +31,16 @@ alias( actual = "@$git_repo$//:konan_properties", ) +# TODO: figure out a way to avoid having these +alias( + name = "klib_cache_marker_files", + actual = "@$git_repo$//:klib_cache_marker_files", +) + [ alias( name = label, actual = "@$git_repo$//:%s" % file.replace(".", "_"), ) for (label, file) in KOTLIN_NATIVE_ARTIFACT_LIST.items() -] +] \ No newline at end of file diff --git a/src/main/starlark/core/repositories/kotlin/artifacts.bzl b/src/main/starlark/core/repositories/kotlin/artifacts.bzl index 3bb9a152f..328a8aaf3 100644 --- a/src/main/starlark/core/repositories/kotlin/artifacts.bzl +++ b/src/main/starlark/core/repositories/kotlin/artifacts.bzl @@ -70,40 +70,102 @@ KOTLINC_ARTIFACTS = struct( ), ) -KOTLIN_NATIVE_ARTIFACTS = struct( - linux_x86_64 = struct( +KOTLIN_NATIVE_ARTIFACTS_AND_TARGETS = { + "linux_x86_64": struct( plugin = {}, compile = { "kotlin-native-linux-x86_64": "konan/lib/kotlin-native.jar", "trove4j-linux-x86_64": "konan/lib/trove4j.jar", }, runtime = {}, + 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_64"], + ("@platforms//os:windows", "@platforms//cpu:x86_64"): ["mingw_x64"], + }, ), - macos_x86_64 = struct( + "macos_x86_64": struct( plugin = {}, compile = { "kotlin-native-macos-x86_64": "konan/lib/kotlin-native.jar", "trove4j-macos-x86_64": "konan/lib/trove4j.jar", }, runtime = {}, + 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( + "macos_aarch64": struct( plugin = {}, compile = { "kotlin-native-macos_aarch64": "konan/lib/kotlin-native.jar", "trove4j-macos_aarch64": "konan/lib/trove4j.jar", }, runtime = {}, + 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( + "windows_x86_64": struct( plugin = {}, compile = { "kotlin-native-windows_x86_64": "konan/lib/kotlin-native.jar", "trove4j-windows_x86_64": "konan/lib/trove4j.jar", }, runtime = {}, + 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 @@ -114,7 +176,7 @@ KOTLINC_ARTIFACT_LIST = { KOTLIN_NATIVE_ARTIFACT_LIST = { label: file - for platform in ["linux_x86_64", "macos_x86_64", "macos_aarch64", "windows_x86_64"] + for platform in KOTLIN_NATIVE_ARTIFACTS_AND_TARGETS.keys() for type in ["compile", "plugin", "runtime"] - for (label, file) in getattr(getattr(KOTLIN_NATIVE_ARTIFACTS, platform), type).items() + for (label, file) in getattr(KOTLIN_NATIVE_ARTIFACTS_AND_TARGETS[platform], type).items() } From a5643558741606e55ceb132414594ff65bc60a4f Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Sun, 3 Aug 2025 20:51:43 -0400 Subject: [PATCH 13/40] Feedback: Pass konan_home as an arg, and attempt to remove marker files --- kotlin/internal/klib/klib.bzl | 2 +- kotlin/internal/klib/toolchains.bzl | 7 +--- .../kotlin/builder/tasks/KotlinBuilder.kt | 6 +++- .../tasks/klib/KotlinKlibTaskExecutor.kt | 12 ++++--- .../kotlin/compiler/BazelK2NativeCompiler.kt | 5 --- src/main/protobuf/kotlin_model.proto | 9 ++++++ ...D.com_github_jetbrains_kotlin_native.bazel | 32 ------------------- .../BUILD.kotlin-native_capabilities.bazel | 6 ---- 8 files changed, 24 insertions(+), 55 deletions(-) diff --git a/kotlin/internal/klib/klib.bzl b/kotlin/internal/klib/klib.bzl index 43779898b..8011e74f8 100644 --- a/kotlin/internal/klib/klib.bzl +++ b/kotlin/internal/klib/klib.bzl @@ -31,6 +31,7 @@ def _kt_klib_library(ctx): libraries = depset(transitive = deps_klibs) builder_args.add_all("--klibs", libraries, omit_if_empty = False) + builder_args.add("--konan_home", konan_home.path) ctx.actions.run( mnemonic = "KotlinKlibCompile", @@ -46,7 +47,6 @@ def _kt_klib_library(ctx): input_manifests = input_manifests, env = { "REPOSITORY_NAME": utils.builder_workspace_name(ctx), - "KONAN_HOME": konan_home.path, }, ) diff --git a/kotlin/internal/klib/toolchains.bzl b/kotlin/internal/klib/toolchains.bzl index 9a41ae45d..4ae50195b 100644 --- a/kotlin/internal/klib/toolchains.bzl +++ b/kotlin/internal/klib/toolchains.bzl @@ -17,7 +17,7 @@ def _kt_native_toolchain_impl(ctx): platform_common.ToolchainInfo( kotlin_native_info = KotlinNativeToolchainInfo( konan_home = konan_home, - konan_home_files = depset(direct = ctx.files.klib_cache_marker_files, transitive = [konan_home_info.transitive_files]), + konan_home_files = depset(transitive = [konan_home_info.transitive_files]), konan_properties = konan_properties, targets = ctx.attr.targets, ), @@ -35,10 +35,6 @@ kt_native_toolchain = rule( doc = "The list of targets supported by this toolchain. Each target can be passed to kotlinc-native with -target option", default = [], ), - "klib_cache_marker_files": attr.label( - doc = "Marker files generated to trick the Kotlin Native compiler to assume the local cache already exists. Without this, it fails to bootstrap the compiler because it expects the directory to exist.", - allow_files = True, - ), }, provides = [platform_common.ToolchainInfo], ) @@ -66,7 +62,6 @@ def kt_configure_native_toolchains(): name = toolchain_name + "_impl", konan_home = "@com_github_jetbrains_kotlin_native_{}//:konan_home".format(exec_platform), targets = kotlin_native_targets, - klib_cache_marker_files = "@com_github_jetbrains_kotlin_native_{}//:klib_cache_marker_files".format(exec_platform), ) # Register the toolchain 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 0f160ae3b..80c46d287 100644 --- a/src/main/kotlin/io/bazel/kotlin/builder/tasks/KotlinBuilder.kt +++ b/src/main/kotlin/io/bazel/kotlin/builder/tasks/KotlinBuilder.kt @@ -94,6 +94,7 @@ class KotlinBuilder BUILD_TOOLS_API("--build_tools_api"), KLIBS("--klibs"), OUTPUT_KLIB("--output_klib"), + KONAN_HOME("--konan_home") } } @@ -202,7 +203,6 @@ class KotlinBuilder ) { val task = buildKlibTask(context.info, workingDir, argMap) context.whenTracing { printProto("klib common task input", task) } - buildKlibTask(context.info, workingDir, argMap) klibTaskExecutor.execute(context, task) } @@ -217,6 +217,10 @@ class KotlinBuilder temp = workingDir.toString() } + with(infoBuilder.toolchainInfoBuilder.nativeBuilder) { + this.setKonanHome(argMap.mandatorySingle(KotlinBuilderFlags.KONAN_HOME)) + } + with(inputsBuilder) { argMap.optional(KotlinBuilderFlags.KLIBS)?.let { addAllLibraries(it) diff --git a/src/main/kotlin/io/bazel/kotlin/builder/tasks/klib/KotlinKlibTaskExecutor.kt b/src/main/kotlin/io/bazel/kotlin/builder/tasks/klib/KotlinKlibTaskExecutor.kt index dba7542b8..065a2530d 100644 --- a/src/main/kotlin/io/bazel/kotlin/builder/tasks/klib/KotlinKlibTaskExecutor.kt +++ b/src/main/kotlin/io/bazel/kotlin/builder/tasks/klib/KotlinKlibTaskExecutor.kt @@ -4,10 +4,7 @@ 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.KlibCompilationTask -import java.nio.file.FileSystem -import java.nio.file.FileSystems -import java.nio.file.Files -import java.nio.file.Path +import java.nio.file.* import java.util.stream.Collectors import javax.inject.Inject import javax.inject.Singleton @@ -39,6 +36,13 @@ class KotlinKlibTaskExecutor 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() diff --git a/src/main/kotlin/io/bazel/kotlin/compiler/BazelK2NativeCompiler.kt b/src/main/kotlin/io/bazel/kotlin/compiler/BazelK2NativeCompiler.kt index 41f02024b..aabc0bd83 100644 --- a/src/main/kotlin/io/bazel/kotlin/compiler/BazelK2NativeCompiler.kt +++ b/src/main/kotlin/io/bazel/kotlin/compiler/BazelK2NativeCompiler.kt @@ -28,11 +28,6 @@ class BazelK2NativeCompiler { vararg args: String, ): ExitCode { System.setProperty("zip.handler.uses.crc.instead.of.timestamp", "true") - val konanHome = System.getenv("KONAN_HOME") - requireNotNull(konanHome) { "KONAN_HOME env var must be set!" } - - System.setProperty("konan.home", konanHome) - val delegate = K2Native() val arguments = delegate.createArguments().also { delegate.parseArguments(args, it) } val collector = diff --git a/src/main/protobuf/kotlin_model.proto b/src/main/protobuf/kotlin_model.proto index 1d1fc8c21..d06003b39 100644 --- a/src/main/protobuf/kotlin_model.proto +++ b/src/main/protobuf/kotlin_model.proto @@ -41,8 +41,15 @@ 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; + } + Common common = 1; Jvm jvm = 2; + Native native = 3; } enum RuleKind { @@ -183,6 +190,8 @@ message KlibCompilationTask { 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 { 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 index c8488a18d..818a150ea 100644 --- 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 @@ -22,33 +22,6 @@ filegroup( srcs = glob(["bin/**"]), ) -write_file( - name = "klib_system_cache_marker_macos_arm64", - out = "klib/cache/macos_arm64STATIC/klib_cache_marker", - content = [ - "Marker file intended to create the klib system cache placeholder even if we don't use it. The native compiler errors out otherwise", - "See See https://github.com/JetBrains/kotlin/blob/v2.1.21/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt#L567", - ], -) - -write_file( - name = "klib_system_cache_marker_linux_x64", - out = "klib/cache/linux_x64STATIC/klib_cache_marker", - content = [ - "Marker file intended to create the klib system cache placeholder even if we don't use it. The native compiler errors out otherwise", - "See See https://github.com/JetBrains/kotlin/blob/v2.1.21/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt#L567", - ], -) - -write_file( - name = "klib_system_cache_marker_macos_x64", - out = "klib/cache/macos_x64STATIC/klib_cache_marker", - content = [ - "Marker file intended to create the klib system cache placeholder even if we don't use it. The native compiler errors out otherwise", - "See See https://github.com/JetBrains/kotlin/blob/v2.1.21/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt#L567", - ], -) - directory( name = "konan_home", srcs = glob([ @@ -57,11 +30,6 @@ directory( ]), ) -filegroup( - name = "klib_cache_marker_files", - srcs = [":klib_system_cache_marker_macos_arm64"], -) - filegroup( name = "konan_properties", srcs = ["konan/konan.properties"], diff --git a/src/main/starlark/core/repositories/BUILD.kotlin-native_capabilities.bazel b/src/main/starlark/core/repositories/BUILD.kotlin-native_capabilities.bazel index 27eccb7ec..e55385d96 100644 --- a/src/main/starlark/core/repositories/BUILD.kotlin-native_capabilities.bazel +++ b/src/main/starlark/core/repositories/BUILD.kotlin-native_capabilities.bazel @@ -31,12 +31,6 @@ alias( actual = "@$git_repo$//:konan_properties", ) -# TODO: figure out a way to avoid having these -alias( - name = "klib_cache_marker_files", - actual = "@$git_repo$//:klib_cache_marker_files", -) - [ alias( name = label, From a0c22843fbcaba9f3029d96d5996d838df6c7db9 Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Sun, 3 Aug 2025 21:37:24 -0400 Subject: [PATCH 14/40] Remove some flags that don't seem needed and don't link with stdlib --- kotlin/internal/klib/klib.bzl | 3 +-- .../kotlin/builder/tasks/klib/KotlinKlibTaskExecutor.kt | 8 +++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/kotlin/internal/klib/klib.bzl b/kotlin/internal/klib/klib.bzl index 8011e74f8..00ae8a4bc 100644 --- a/kotlin/internal/klib/klib.bzl +++ b/kotlin/internal/klib/klib.bzl @@ -18,7 +18,6 @@ def _kt_klib_library(ctx): transitive_klibs = [] for dep in ctx.attr.deps: deps_klibs.append(dep[_KtKlibInfo].klibs) - deps_klibs.append(dep[_KtKlibInfo].transitive_klibs) transitive_klibs.append(dep[_KtKlibInfo].transitive_klibs) libraries = depset(transitive = deps_klibs) @@ -30,7 +29,7 @@ def _kt_klib_library(ctx): builder_args.add("--output_klib", klib.path) libraries = depset(transitive = deps_klibs) - builder_args.add_all("--klibs", libraries, omit_if_empty = False) + builder_args.add_all("--klibs", libraries) builder_args.add("--konan_home", konan_home.path) ctx.actions.run( diff --git a/src/main/kotlin/io/bazel/kotlin/builder/tasks/klib/KotlinKlibTaskExecutor.kt b/src/main/kotlin/io/bazel/kotlin/builder/tasks/klib/KotlinKlibTaskExecutor.kt index 065a2530d..7d0995f5b 100644 --- a/src/main/kotlin/io/bazel/kotlin/builder/tasks/klib/KotlinKlibTaskExecutor.kt +++ b/src/main/kotlin/io/bazel/kotlin/builder/tasks/klib/KotlinKlibTaskExecutor.kt @@ -56,12 +56,10 @@ class KotlinKlibTaskExecutor val execRoot = fileSystem.getPath(".").absolute() return mutableListOf().apply { addAll(passThroughFlagsList) - // kotlin-native klib compilation requires caching and no way to disable, so pass a temp directory - // within the current working directory to isolate its cache (which is unique to this worker anyway) - // Ideally we disable caching though and rely only on Bazel - add("-Xauto-cache-dir=${autoCacheDirectory.absolutePathString()}") - add("-Xauto-cache-from=${autoCacheFromDirectory.absolutePathString()}") add("-Xklib-normalize-absolute-path") + // Avoid downloading any dependencies during the build + add("-Xoverride-konan-properties=airplaneMode=true") + add("-nostdlib") addAll("-module-name=${info.moduleName}") addAll(inputs.kotlinSourcesList.map { execRoot.resolve(it).absolutePathString() }) } From a57be2eeeb41eb74d1c34d6087654a6db33da06f Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Sun, 3 Aug 2025 21:42:18 -0400 Subject: [PATCH 15/40] Fix path to konan_home in toolchain --- kotlin/internal/klib/toolchains.bzl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kotlin/internal/klib/toolchains.bzl b/kotlin/internal/klib/toolchains.bzl index 4ae50195b..1c62b1534 100644 --- a/kotlin/internal/klib/toolchains.bzl +++ b/kotlin/internal/klib/toolchains.bzl @@ -11,7 +11,7 @@ KotlinNativeToolchainInfo = provider(fields = { 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.get_subdirectory("konan") + konan_home = konan_home_info return [ platform_common.ToolchainInfo( From 809270e1d59644c9ec7a35c4cdef01f2a8bfec80 Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Sun, 3 Aug 2025 23:08:43 -0400 Subject: [PATCH 16/40] lint and fix starlark tests --- .../io/bazel/kotlin/builder/tasks/KotlinBuilder.kt | 2 +- .../builder/tasks/klib/KotlinKlibTaskExecutor.kt | 10 +++++++--- src/test/starlark/internal/klib/klib_tests.bzl | 3 +-- 3 files changed, 9 insertions(+), 6 deletions(-) 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 80c46d287..49e110d02 100644 --- a/src/main/kotlin/io/bazel/kotlin/builder/tasks/KotlinBuilder.kt +++ b/src/main/kotlin/io/bazel/kotlin/builder/tasks/KotlinBuilder.kt @@ -94,7 +94,7 @@ class KotlinBuilder BUILD_TOOLS_API("--build_tools_api"), KLIBS("--klibs"), OUTPUT_KLIB("--output_klib"), - KONAN_HOME("--konan_home") + KONAN_HOME("--konan_home"), } } diff --git a/src/main/kotlin/io/bazel/kotlin/builder/tasks/klib/KotlinKlibTaskExecutor.kt b/src/main/kotlin/io/bazel/kotlin/builder/tasks/klib/KotlinKlibTaskExecutor.kt index 7d0995f5b..8cf663932 100644 --- a/src/main/kotlin/io/bazel/kotlin/builder/tasks/klib/KotlinKlibTaskExecutor.kt +++ b/src/main/kotlin/io/bazel/kotlin/builder/tasks/klib/KotlinKlibTaskExecutor.kt @@ -4,7 +4,11 @@ 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.KlibCompilationTask -import java.nio.file.* +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 @@ -37,11 +41,11 @@ class KotlinKlibTaskExecutor } val konanHome = this.info.toolchainInfo.native.konanHome - if(!Paths.get(konanHome).exists()) { + if (!Paths.get(konanHome).exists()) { throw IllegalArgumentException("$konanHome doesn't point to konan.home or doesn't exist.") } - System.setProperty("konan.home", konanHome); + System.setProperty("konan.home", konanHome) val autoCacheDirectory = workingDirectory().resolve("native_auto_cache") if (!autoCacheDirectory.exists()) { diff --git a/src/test/starlark/internal/klib/klib_tests.bzl b/src/test/starlark/internal/klib/klib_tests.bzl index 2d47f4ea2..f5ed55a73 100644 --- a/src/test/starlark/internal/klib/klib_tests.bzl +++ b/src/test/starlark/internal/klib/klib_tests.bzl @@ -9,8 +9,7 @@ def _common_assertions(env, target): target_subject.has_provider(KtKlibInfo) action_subject = target_subject.action_named("KotlinKlibCompile") - action_subject.env().keys().contains("KONAN_HOME") - action_subject.argv().contains_at_least(["--rule_kind", "kt_klib_library", "--output_klib"]) + action_subject.argv().contains_at_least(["--rule_kind", "kt_klib_library", "--output_klib", "--konan_home"]) def _test_kt_klib_basic_impl(env, target): _common_assertions(env, target) From 59b64c69757a51494678f6d6c3bebd86fed98ee8 Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Mon, 4 Aug 2025 08:46:07 -0400 Subject: [PATCH 17/40] Rename klib package to native under kotlin/internal --- kotlin/internal/defs.bzl | 2 +- kotlin/internal/klib/BUILD.bazel | 3 --- kotlin/internal/native/BUILD.bazel | 3 +++ kotlin/internal/{klib => native}/klib.bzl | 0 kotlin/internal/{klib => native}/toolchains.bzl | 0 kotlin/internal/toolchains.bzl | 1 - src/test/data/{klib => native}/BUILD.bazel | 2 +- src/test/data/{klib => native}/basic/Hello.kt | 0 src/test/data/{klib => native}/deps/Main.kt | 0 src/test/data/{klib => native}/deps/data/Greeting.kt | 0 src/test/starlark/internal/{klib => native}/BUILD.bazel | 0 src/test/starlark/internal/{klib => native}/klib_tests.bzl | 0 12 files changed, 5 insertions(+), 6 deletions(-) delete mode 100644 kotlin/internal/klib/BUILD.bazel create mode 100644 kotlin/internal/native/BUILD.bazel rename kotlin/internal/{klib => native}/klib.bzl (100%) rename kotlin/internal/{klib => native}/toolchains.bzl (100%) rename src/test/data/{klib => native}/BUILD.bazel (86%) rename src/test/data/{klib => native}/basic/Hello.kt (100%) rename src/test/data/{klib => native}/deps/Main.kt (100%) rename src/test/data/{klib => native}/deps/data/Greeting.kt (100%) rename src/test/starlark/internal/{klib => native}/BUILD.bazel (100%) rename src/test/starlark/internal/{klib => native}/klib_tests.bzl (100%) diff --git a/kotlin/internal/defs.bzl b/kotlin/internal/defs.bzl index a98a656d8..eca7ca9a8 100644 --- a/kotlin/internal/defs.bzl +++ b/kotlin/internal/defs.bzl @@ -28,7 +28,7 @@ load( # The Kotlin Toolchain type. TOOLCHAIN_TYPE = "%s" % Label("//kotlin/internal:kt_toolchain_type") -NATIVE_TOOLCHAIN_TYPE = "%s" % Label("//kotlin/internal/klib:kt_native_toolchain_type") +NATIVE_TOOLCHAIN_TYPE = "%s" % Label("//kotlin/internal/native:kt_native_toolchain_type") # Java toolchains JAVA_TOOLCHAIN_TYPE = _JAVA_TOOLCHAIN_TYPE diff --git a/kotlin/internal/klib/BUILD.bazel b/kotlin/internal/klib/BUILD.bazel deleted file mode 100644 index 0f5dbd63e..000000000 --- a/kotlin/internal/klib/BUILD.bazel +++ /dev/null @@ -1,3 +0,0 @@ -load("//kotlin/internal/klib:toolchains.bzl", "kt_configure_native_toolchains") - -kt_configure_native_toolchains() diff --git a/kotlin/internal/native/BUILD.bazel b/kotlin/internal/native/BUILD.bazel new file mode 100644 index 000000000..2c8067ce6 --- /dev/null +++ b/kotlin/internal/native/BUILD.bazel @@ -0,0 +1,3 @@ +load("//kotlin/internal/native:toolchains.bzl", "kt_configure_native_toolchains") + +kt_configure_native_toolchains() diff --git a/kotlin/internal/klib/klib.bzl b/kotlin/internal/native/klib.bzl similarity index 100% rename from kotlin/internal/klib/klib.bzl rename to kotlin/internal/native/klib.bzl diff --git a/kotlin/internal/klib/toolchains.bzl b/kotlin/internal/native/toolchains.bzl similarity index 100% rename from kotlin/internal/klib/toolchains.bzl rename to kotlin/internal/native/toolchains.bzl diff --git a/kotlin/internal/toolchains.bzl b/kotlin/internal/toolchains.bzl index d2196b73b..85d10e744 100644 --- a/kotlin/internal/toolchains.bzl +++ b/kotlin/internal/toolchains.bzl @@ -16,7 +16,6 @@ load("@rules_java//java:defs.bzl", "JavaInfo", "java_common") load( "//kotlin/internal:defs.bzl", _KT_COMPILER_REPO = "KT_COMPILER_REPO", - _KT_NATIVE_COMPILER_REPO_PREFIX = "KT_NATIVE_COMPILER_REPO_PREFIX", _TOOLCHAIN_TYPE = "TOOLCHAIN_TYPE", ) load( diff --git a/src/test/data/klib/BUILD.bazel b/src/test/data/native/BUILD.bazel similarity index 86% rename from src/test/data/klib/BUILD.bazel rename to src/test/data/native/BUILD.bazel index 0bdcd940d..e34061d4d 100644 --- a/src/test/data/klib/BUILD.bazel +++ b/src/test/data/native/BUILD.bazel @@ -1,4 +1,4 @@ -load("//kotlin/internal/klib:klib.bzl", "kt_klib_library") +load("//kotlin/internal/native:klib.bzl", "kt_klib_library") kt_klib_library( name = "basic", diff --git a/src/test/data/klib/basic/Hello.kt b/src/test/data/native/basic/Hello.kt similarity index 100% rename from src/test/data/klib/basic/Hello.kt rename to src/test/data/native/basic/Hello.kt diff --git a/src/test/data/klib/deps/Main.kt b/src/test/data/native/deps/Main.kt similarity index 100% rename from src/test/data/klib/deps/Main.kt rename to src/test/data/native/deps/Main.kt diff --git a/src/test/data/klib/deps/data/Greeting.kt b/src/test/data/native/deps/data/Greeting.kt similarity index 100% rename from src/test/data/klib/deps/data/Greeting.kt rename to src/test/data/native/deps/data/Greeting.kt diff --git a/src/test/starlark/internal/klib/BUILD.bazel b/src/test/starlark/internal/native/BUILD.bazel similarity index 100% rename from src/test/starlark/internal/klib/BUILD.bazel rename to src/test/starlark/internal/native/BUILD.bazel diff --git a/src/test/starlark/internal/klib/klib_tests.bzl b/src/test/starlark/internal/native/klib_tests.bzl similarity index 100% rename from src/test/starlark/internal/klib/klib_tests.bzl rename to src/test/starlark/internal/native/klib_tests.bzl From ce96a95bebacc60ce3de7cf91c25da0ebb68e8e8 Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Mon, 4 Aug 2025 08:46:46 -0400 Subject: [PATCH 18/40] Update docs --- MODULE.bazel | 2 +- docs/kotlin.md | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 062536eca..d10e09bfd 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -47,7 +47,7 @@ register_toolchains("//src/main/starlark/core/compile/cli") register_toolchains("//kotlin/internal:default_toolchain") -register_toolchains("//kotlin/internal/klib:all") +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 diff --git a/docs/kotlin.md b/docs/kotlin.md index 1c96221eb..da3efba5e 100755 --- a/docs/kotlin.md +++ b/docs/kotlin.md @@ -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 = "8df16175b962bc4264a5c3b32cb042d91458babbd093c0f36194dc4645f5fe2", 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")` | From e902025224009bc59d739472b26a84d754fe727a Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Mon, 4 Aug 2025 08:51:57 -0400 Subject: [PATCH 19/40] Make toolchain names and impl names consistent --- kotlin/internal/native/toolchains.bzl | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/kotlin/internal/native/toolchains.bzl b/kotlin/internal/native/toolchains.bzl index 1c62b1534..085b3563d 100644 --- a/kotlin/internal/native/toolchains.bzl +++ b/kotlin/internal/native/toolchains.bzl @@ -40,6 +40,7 @@ kt_native_toolchain = rule( ) 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"], @@ -57,9 +58,15 @@ def kt_configure_native_toolchains(): target_cpu.split("//")[1].replace(":", "_").replace("/", "_"), ) + toolchain_impl = "default_kt_native_{}_to_{}_{}".format( + exec_platform, + target_os.split("//")[1].replace(":", "_").replace("/", "_"), + target_cpu.split("//")[1].replace(":", "_").replace("/", "_"), + ) + # Create the toolchain implementation kt_native_toolchain( - name = toolchain_name + "_impl", + name = toolchain_impl, konan_home = "@com_github_jetbrains_kotlin_native_{}//:konan_home".format(exec_platform), targets = kotlin_native_targets, ) @@ -69,6 +76,6 @@ def kt_configure_native_toolchains(): name = toolchain_name, exec_compatible_with = artifacts_and_targets.exec_compatible_with, target_compatible_with = [target_os, target_cpu], - toolchain = ":" + toolchain_name + "_impl", + toolchain = ":" + toolchain_impl, toolchain_type = ":kt_native_toolchain_type", ) From de83c33f0bacc84edb4c889553f0f07bd6b62097 Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Mon, 4 Aug 2025 08:57:57 -0400 Subject: [PATCH 20/40] Fix starlark tests --- src/test/starlark/internal/native/klib_tests.bzl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/starlark/internal/native/klib_tests.bzl b/src/test/starlark/internal/native/klib_tests.bzl index f5ed55a73..b69280a84 100644 --- a/src/test/starlark/internal/native/klib_tests.bzl +++ b/src/test/starlark/internal/native/klib_tests.bzl @@ -1,7 +1,7 @@ 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/klib:klib.bzl", "kt_klib_library") +load("//kotlin/internal/native:klib.bzl", "kt_klib_library") def _common_assertions(env, target): # Assertions common to all kt_klib_library tests From 3d06d5353c56e5bd3cf89667824b4b8e0261420a Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Mon, 4 Aug 2025 09:43:09 -0400 Subject: [PATCH 21/40] Fix more references --- .../repositories/BUILD.com_github_jetbrains_kotlin_native.bazel | 1 - .../core/repositories/BUILD.kotlin-native_capabilities.bazel | 2 +- src/test/kotlin/io/bazel/kotlin/BUILD | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) 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 index 818a150ea..61454ce6a 100644 --- 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 @@ -16,7 +16,6 @@ load("@bazel_skylib//rules/directory:directory.bzl", "directory") package(default_visibility = ["//visibility:public"]) - filegroup( name = "bin", srcs = glob(["bin/**"]), diff --git a/src/main/starlark/core/repositories/BUILD.kotlin-native_capabilities.bazel b/src/main/starlark/core/repositories/BUILD.kotlin-native_capabilities.bazel index e55385d96..9ee1911fd 100644 --- a/src/main/starlark/core/repositories/BUILD.kotlin-native_capabilities.bazel +++ b/src/main/starlark/core/repositories/BUILD.kotlin-native_capabilities.bazel @@ -37,4 +37,4 @@ alias( actual = "@$git_repo$//:%s" % file.replace(".", "_"), ) for (label, file) in KOTLIN_NATIVE_ARTIFACT_LIST.items() -] \ No newline at end of file +] diff --git a/src/test/kotlin/io/bazel/kotlin/BUILD b/src/test/kotlin/io/bazel/kotlin/BUILD index 0a9fa3ebe..35d684395 100644 --- a/src/test/kotlin/io/bazel/kotlin/BUILD +++ b/src/test/kotlin/io/bazel/kotlin/BUILD @@ -72,7 +72,7 @@ kt_rules_e2e_test( name = "KotlinKlibAssertionTest", srcs = ["KotlinKlibAssertionTest.kt"], data = [ - "//src/test/data/klib:klib_tests", + "//src/test/data/native:klib_tests", ], ) From e940430c42879e7a5a78ebb4921dd63ea1be9d6c Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Mon, 4 Aug 2025 09:54:03 -0400 Subject: [PATCH 22/40] Fix more tests and buildifier --- .../BUILD.com_github_jetbrains_kotlin_native.bazel | 1 - src/test/kotlin/io/bazel/kotlin/KotlinKlibAssertionTest.kt | 2 +- src/test/starlark/internal/native/klib_tests.bzl | 6 +++--- 3 files changed, 4 insertions(+), 5 deletions(-) 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 index 61454ce6a..fc2851223 100644 --- 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 @@ -11,7 +11,6 @@ # 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:write_file.bzl", "write_file") load("@bazel_skylib//rules/directory:directory.bzl", "directory") package(default_visibility = ["//visibility:public"]) diff --git a/src/test/kotlin/io/bazel/kotlin/KotlinKlibAssertionTest.kt b/src/test/kotlin/io/bazel/kotlin/KotlinKlibAssertionTest.kt index 3d14a303c..978d9fb0d 100644 --- a/src/test/kotlin/io/bazel/kotlin/KotlinKlibAssertionTest.kt +++ b/src/test/kotlin/io/bazel/kotlin/KotlinKlibAssertionTest.kt @@ -5,7 +5,7 @@ import org.junit.runner.RunWith import org.junit.runners.JUnit4 @RunWith(JUnit4::class) -class KotlinKlibAssertionTest : KotlinAssertionTestCase("src/test/data/klib") { +class KotlinKlibAssertionTest : KotlinAssertionTestCase("src/test/data/native") { @Test fun testBasicKlibIsProduced() { klibTestCase("basic.klib", "kt_lib_library produces klib with stdlib usage") { diff --git a/src/test/starlark/internal/native/klib_tests.bzl b/src/test/starlark/internal/native/klib_tests.bzl index b69280a84..a18eadf37 100644 --- a/src/test/starlark/internal/native/klib_tests.bzl +++ b/src/test/starlark/internal/native/klib_tests.bzl @@ -15,7 +15,7 @@ def _test_kt_klib_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/klib/Basic.kt") + action_subject.inputs().contains("src/test/starlark/internal/native/Basic.kt") def _test_kt_klib_basic(name): kt_klib_library(name = "basic", srcs = ["Basic.kt"], tags = ["manual"]) @@ -27,10 +27,10 @@ def _test_kt_klib_deps_impl(env, target): target_subject = env.expect.that_target(target) action_subject = target_subject.action_named("KotlinKlibCompile") - action_subject.inputs().contains("src/test/starlark/internal/klib/Second.kt") + 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/klib/first.klib") + 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"]) From f5b6641cd49f016f0177d2bf68e0c6b0f028020f Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Mon, 4 Aug 2025 13:38:48 -0400 Subject: [PATCH 23/40] Add -Xklib-relative-path-base and -Xdebug-prefix-map --- .../kotlin/builder/tasks/klib/KotlinKlibTaskExecutor.kt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/io/bazel/kotlin/builder/tasks/klib/KotlinKlibTaskExecutor.kt b/src/main/kotlin/io/bazel/kotlin/builder/tasks/klib/KotlinKlibTaskExecutor.kt index 8cf663932..0b6e319be 100644 --- a/src/main/kotlin/io/bazel/kotlin/builder/tasks/klib/KotlinKlibTaskExecutor.kt +++ b/src/main/kotlin/io/bazel/kotlin/builder/tasks/klib/KotlinKlibTaskExecutor.kt @@ -12,7 +12,6 @@ import java.nio.file.Paths import java.util.stream.Collectors import javax.inject.Inject import javax.inject.Singleton -import kotlin.io.path.absolute import kotlin.io.path.absolutePathString import kotlin.io.path.exists import kotlin.io.path.pathString @@ -57,13 +56,18 @@ class KotlinKlibTaskExecutor autoCacheFromDirectory.toFile().mkdirs() } - val execRoot = fileSystem.getPath(".").absolute() + 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") + + // 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() }) } From 3def59ab913ff9d476008fae7fcec288478e2154 Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Mon, 4 Aug 2025 16:59:13 -0400 Subject: [PATCH 24/40] Rename to kt_library and structure accordingly --- .../internal/native/{klib.bzl => library.bzl} | 8 ++--- .../builder/KotlinBuilderComponent.java | 3 ++ .../kotlin/builder/tasks/KotlinBuilder.kt | 34 ++++++++++++------- .../KotlinNativeTaskExecutor.kt} | 15 ++++---- src/main/protobuf/kotlin_model.proto | 4 +-- src/test/data/native/BUILD.bazel | 8 ++--- src/test/starlark/internal/native/BUILD.bazel | 4 +-- .../{klib_tests.bzl => kt_library_tests.bzl} | 30 ++++++++-------- 8 files changed, 60 insertions(+), 46 deletions(-) rename kotlin/internal/native/{klib.bzl => library.bzl} (94%) rename src/main/kotlin/io/bazel/kotlin/builder/tasks/{klib/KotlinKlibTaskExecutor.kt => knative/KotlinNativeTaskExecutor.kt} (86%) rename src/test/starlark/internal/native/{klib_tests.bzl => kt_library_tests.bzl} (60%) diff --git a/kotlin/internal/native/klib.bzl b/kotlin/internal/native/library.bzl similarity index 94% rename from kotlin/internal/native/klib.bzl rename to kotlin/internal/native/library.bzl index 00ae8a4bc..20a59cbbe 100644 --- a/kotlin/internal/native/klib.bzl +++ b/kotlin/internal/native/library.bzl @@ -1,9 +1,9 @@ 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_klib_library(ctx): +def _kt_library_impl(ctx): module_name = utils.derive_module_name(ctx) - builder_args = utils.init_args(ctx, "kt_klib_library", module_name) + builder_args = utils.init_args(ctx, "kt_library", module_name) klib = ctx.actions.declare_file("{}.klib".format(ctx.label.name)) outputs = [klib] @@ -57,8 +57,8 @@ def _kt_klib_library(ctx): ), ] -kt_klib_library = rule( - implementation = _kt_klib_library, +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. 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/tasks/KotlinBuilder.kt b/src/main/kotlin/io/bazel/kotlin/builder/tasks/KotlinBuilder.kt index 49e110d02..b70d1efd1 100644 --- a/src/main/kotlin/io/bazel/kotlin/builder/tasks/KotlinBuilder.kt +++ b/src/main/kotlin/io/bazel/kotlin/builder/tasks/KotlinBuilder.kt @@ -17,7 +17,7 @@ package io.bazel.kotlin.builder.tasks import io.bazel.kotlin.builder.tasks.jvm.KotlinJvmTaskExecutor -import io.bazel.kotlin.builder.tasks.klib.KotlinKlibTaskExecutor +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 @@ -27,7 +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.KlibCompilationTask +import io.bazel.kotlin.model.KotlinNativeCompilationTask import io.bazel.kotlin.model.Platform import io.bazel.kotlin.model.RuleKind import io.bazel.worker.WorkerContext @@ -45,7 +45,7 @@ class KotlinBuilder @Inject internal constructor( private val jvmTaskExecutor: KotlinJvmTaskExecutor, - private val klibTaskExecutor: KotlinKlibTaskExecutor, + private val nativeTaskExecutor: KotlinNativeTaskExecutor, ) { companion object { @JvmStatic @@ -111,7 +111,12 @@ class KotlinBuilder Platform.JVM, Platform.ANDROID, -> executeJvmTask(compileContext, taskContext.directory, argMap) - Platform.KLIB -> executeKlibTask(compileContext, taskContext.directory, argMap) + Platform.NATIVE_LIBRARY -> + executeKotlinNativeTask( + compileContext, + taskContext.directory, + argMap, + ) Platform.UNRECOGNIZED -> throw IllegalStateException( "unrecognized platform: ${compileContext.info}", ) @@ -153,8 +158,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 { @@ -196,22 +206,22 @@ class KotlinBuilder jvmTaskExecutor.execute(context, task) } - private fun executeKlibTask( + private fun executeKotlinNativeTask( context: CompilationTaskContext, workingDir: Path, argMap: ArgMap, ) { - val task = buildKlibTask(context.info, workingDir, argMap) - context.whenTracing { printProto("klib common task input", task) } - klibTaskExecutor.execute(context, task) + val task = buildKotlinNativeTask(context.info, workingDir, argMap) + context.whenTracing { printProto("kotlin native compile task input", task) } + nativeTaskExecutor.execute(context, task) } - private fun buildKlibTask( + private fun buildKotlinNativeTask( info: CompilationTaskInfo, workingDir: Path, argMap: ArgMap, - ): KlibCompilationTask = - with(KlibCompilationTask.newBuilder()) { + ): KotlinNativeCompilationTask = + with(KotlinNativeCompilationTask.newBuilder()) { this.info = info with(directoriesBuilder) { temp = workingDir.toString() diff --git a/src/main/kotlin/io/bazel/kotlin/builder/tasks/klib/KotlinKlibTaskExecutor.kt b/src/main/kotlin/io/bazel/kotlin/builder/tasks/knative/KotlinNativeTaskExecutor.kt similarity index 86% rename from src/main/kotlin/io/bazel/kotlin/builder/tasks/klib/KotlinKlibTaskExecutor.kt rename to src/main/kotlin/io/bazel/kotlin/builder/tasks/knative/KotlinNativeTaskExecutor.kt index 0b6e319be..578ba1c06 100644 --- a/src/main/kotlin/io/bazel/kotlin/builder/tasks/klib/KotlinKlibTaskExecutor.kt +++ b/src/main/kotlin/io/bazel/kotlin/builder/tasks/knative/KotlinNativeTaskExecutor.kt @@ -1,9 +1,9 @@ -package io.bazel.kotlin.builder.tasks.klib +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.KlibCompilationTask +import io.bazel.kotlin.model.KotlinNativeCompilationTask import java.nio.file.FileSystem import java.nio.file.FileSystems import java.nio.file.Files @@ -17,7 +17,7 @@ import kotlin.io.path.exists import kotlin.io.path.pathString @Singleton -class KotlinKlibTaskExecutor +class KotlinNativeTaskExecutor @Inject constructor( private val invoker: KotlinToolchain.K2NativeCompilerInvoker, @@ -26,14 +26,15 @@ class KotlinKlibTaskExecutor fun execute( context: CompilationTaskContext, - task: KlibCompilationTask, + task: KotlinNativeCompilationTask, ) { task.compile(context) } - private fun KlibCompilationTask.workingDirectory(): Path = fileSystem.getPath(directories.temp) + private fun KotlinNativeCompilationTask.workingDirectory(): Path = + fileSystem.getPath(directories.temp) - private fun KlibCompilationTask.commonArgs(): MutableList { + private fun KotlinNativeCompilationTask.commonArgs(): MutableList { val workDir = workingDirectory() if (!workDir.exists()) { workDir.toFile().mkdirs() @@ -73,7 +74,7 @@ class KotlinKlibTaskExecutor } } - private fun KlibCompilationTask.compile(context: CompilationTaskContext) { + private fun KotlinNativeCompilationTask.compile(context: CompilationTaskContext) { val args = commonArgs() val klibOut = fileSystem.getPath(outputs.klib) inputs.librariesList.forEach { library -> diff --git a/src/main/protobuf/kotlin_model.proto b/src/main/protobuf/kotlin_model.proto index d06003b39..164acc269 100644 --- a/src/main/protobuf/kotlin_model.proto +++ b/src/main/protobuf/kotlin_model.proto @@ -62,7 +62,7 @@ enum RuleKind { enum Platform { JVM = 0; ANDROID = 1; - KLIB = 3; + NATIVE_LIBRARY = 3; } // Common info about a Kotlin compilation task, this message is shared by all compilation tasks. @@ -185,7 +185,7 @@ message JvmCompilationTask { } -message KlibCompilationTask { +message KotlinNativeCompilationTask { // Directories used by the builder. message Directories { // A temp directory that the compiler may use. diff --git a/src/test/data/native/BUILD.bazel b/src/test/data/native/BUILD.bazel index e34061d4d..a152999a8 100644 --- a/src/test/data/native/BUILD.bazel +++ b/src/test/data/native/BUILD.bazel @@ -1,16 +1,16 @@ -load("//kotlin/internal/native:klib.bzl", "kt_klib_library") +load("//kotlin/internal/native:library.bzl", "kt_library") -kt_klib_library( +kt_library( name = "basic", srcs = ["basic/Hello.kt"], ) -kt_klib_library( +kt_library( name = "deps_greeting", srcs = ["deps/data/Greeting.kt"], ) -kt_klib_library( +kt_library( name = "deps_main", srcs = ["deps/Main.kt"], deps = [":deps_greeting"], diff --git a/src/test/starlark/internal/native/BUILD.bazel b/src/test/starlark/internal/native/BUILD.bazel index 137d2d61d..ebf6e36ba 100644 --- a/src/test/starlark/internal/native/BUILD.bazel +++ b/src/test/starlark/internal/native/BUILD.bazel @@ -1,3 +1,3 @@ -load(":klib_tests.bzl", "kt_klib_test_suite") +load(":kt_library_tests.bzl", "kt_library_test_suite") -kt_klib_test_suite(name = "klib_tests") +kt_library_test_suite(name = "library_tests") diff --git a/src/test/starlark/internal/native/klib_tests.bzl b/src/test/starlark/internal/native/kt_library_tests.bzl similarity index 60% rename from src/test/starlark/internal/native/klib_tests.bzl rename to src/test/starlark/internal/native/kt_library_tests.bzl index a18eadf37..bdd1d75f0 100644 --- a/src/test/starlark/internal/native/klib_tests.bzl +++ b/src/test/starlark/internal/native/kt_library_tests.bzl @@ -1,28 +1,28 @@ 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:klib.bzl", "kt_klib_library") +load("//kotlin/internal/native:library.bzl", "kt_library") def _common_assertions(env, target): - # Assertions common to all kt_klib_library tests + # 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_klib_library", "--output_klib", "--konan_home"]) + action_subject.argv().contains_at_least(["--rule_kind", "kt_library", "--output_klib", "--konan_home"]) -def _test_kt_klib_basic_impl(env, target): +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") -def _test_kt_klib_basic(name): - kt_klib_library(name = "basic", srcs = ["Basic.kt"], tags = ["manual"]) +def _test_kt_library_basic(name): + kt_library(name = "basic", srcs = ["Basic.kt"], tags = ["manual"]) - analysis_test(name, target = "basic", impl = _test_kt_klib_basic_impl) + analysis_test(name, target = "basic", impl = _test_kt_library_basic_impl) -def _test_kt_klib_deps_impl(env, target): +def _test_kt_library_deps_impl(env, target): _common_assertions(env, target) target_subject = env.expect.that_target(target) @@ -35,18 +35,18 @@ def _test_kt_klib_deps_impl(env, target): # and it's passed through the arguments action_subject.argv().contains_at_least(["--klibs"]) -def _test_kt_klib_deps(name): - kt_klib_library(name = "first", srcs = ["First.kt"], tags = ["manual"]) +def _test_kt_library_deps(name): + kt_library(name = "first", srcs = ["First.kt"], tags = ["manual"]) - kt_klib_library(name = "second", srcs = ["Second.kt"], deps = [":first"], tags = ["manual"]) + kt_library(name = "second", srcs = ["Second.kt"], deps = [":first"], tags = ["manual"]) - analysis_test(name, target = "second", impl = _test_kt_klib_deps_impl) + analysis_test(name, target = "second", impl = _test_kt_library_deps_impl) -def kt_klib_test_suite(name): +def kt_library_test_suite(name): test_suite( name = name, tests = [ - _test_kt_klib_basic, - _test_kt_klib_deps, + _test_kt_library_basic, + _test_kt_library_deps, ], ) From bc060d467a7f4b3406c324ba10e3092b6972b7a9 Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Mon, 4 Aug 2025 17:14:11 -0400 Subject: [PATCH 25/40] Remove konan_home attribute on the JVM toolchain --- kotlin/internal/toolchains.bzl | 5 ----- 1 file changed, 5 deletions(-) diff --git a/kotlin/internal/toolchains.bzl b/kotlin/internal/toolchains.bzl index 85d10e744..b69a16a1b 100644 --- a/kotlin/internal/toolchains.bzl +++ b/kotlin/internal/toolchains.bzl @@ -79,7 +79,6 @@ def _kotlin_toolchain_impl(ctx): ], jdeps_merger = ctx.attr.jdeps_merger, kotlin_home = ctx.attr.kotlin_home, - konan_home = ctx.attr.konan_home, jvm_stdlibs = java_common.merge(compile_time_providers + runtime_providers), jvm_emit_jdeps = ctx.attr._jvm_emit_jdeps[BuildSettingInfo].value, execution_requirements = { @@ -116,10 +115,6 @@ _kt_toolchain = rule( default = Label("@" + _KT_COMPILER_REPO + "//:home"), allow_files = True, ), - "konan_home": attr.label( - doc = "the filegroup defining the konan/kotlin-native home", - allow_files = True, - ), "kotlinbuilder": attr.label( doc = "the kotlin builder executable", default = Label("//src/main/kotlin:build"), From eda99306e3e5ca65cddcd7887eee44d398b0b686 Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Sun, 10 Aug 2025 11:38:30 -0400 Subject: [PATCH 26/40] Add runfiles support with tests --- kotlin/internal/native/library.bzl | 12 +++++- .../internal/native/kt_library_tests.bzl | 38 +++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/kotlin/internal/native/library.bzl b/kotlin/internal/native/library.bzl index 20a59cbbe..67fddae3a 100644 --- a/kotlin/internal/native/library.bzl +++ b/kotlin/internal/native/library.bzl @@ -16,9 +16,14 @@ def _kt_library_impl(ctx): deps_klibs = [] transitive_klibs = [] + runfiles = ctx.runfiles(files = 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) @@ -50,7 +55,7 @@ def _kt_library_impl(ctx): ) return [ - DefaultInfo(files = depset(outputs)), + DefaultInfo(files = depset(outputs), runfiles = runfiles), _KtKlibInfo( klibs = depset(outputs), transitive_klibs = depset(transitive = transitive_klibs), @@ -72,6 +77,11 @@ to be shared between Kotlin code for different platforms (JS/JVM/WASM etc.). It 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/src/test/starlark/internal/native/kt_library_tests.bzl b/src/test/starlark/internal/native/kt_library_tests.bzl index bdd1d75f0..6994ee91c 100644 --- a/src/test/starlark/internal/native/kt_library_tests.bzl +++ b/src/test/starlark/internal/native/kt_library_tests.bzl @@ -42,11 +42,49 @@ def _test_kt_library_deps(name): 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"], + ) + kt_library(name = "lib_with_data", srcs = ["First.kt"], data = [":runfiles1"]) + + 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"], + ) + kt_library(name = "lib2_with_data", srcs = ["First.kt"], data = [":runfiles2"]) + + kt_library(name = "final_lib", srcs = ["Second.kt"], deps = [":lib2_with_data"]) + + 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 _test_kt_library_deps, + # Assert runfiles are available + _test_kt_library_runfiles, + # Assert transitive runfiles are propagated + _test_kt_library_transitive_runfiles, ], ) From 3dafe36a0cff5571f1c2b31d274f36e6274a4cb0 Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Sun, 10 Aug 2025 11:44:01 -0400 Subject: [PATCH 27/40] Mark targets within starkark tests as manual --- src/test/starlark/internal/native/kt_library_tests.bzl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/test/starlark/internal/native/kt_library_tests.bzl b/src/test/starlark/internal/native/kt_library_tests.bzl index 6994ee91c..c53bc93a8 100644 --- a/src/test/starlark/internal/native/kt_library_tests.bzl +++ b/src/test/starlark/internal/native/kt_library_tests.bzl @@ -52,8 +52,9 @@ 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"]) + 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) @@ -67,10 +68,11 @@ 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"]) + 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"]) + 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) From 53bda707f971991acf6d9aed95abbe8b177624e0 Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Sun, 10 Aug 2025 12:35:50 -0400 Subject: [PATCH 28/40] Be explicit about --target and propagate it from toolchain to builder --- kotlin/internal/native/library.bzl | 2 ++ kotlin/internal/native/toolchains.bzl | 26 ++++++++++++------- .../kotlin/builder/tasks/KotlinBuilder.kt | 4 +++ .../tasks/knative/KotlinNativeTaskExecutor.kt | 3 +++ src/main/protobuf/kotlin_model.proto | 2 ++ .../core/repositories/kotlin/artifacts.bzl | 2 +- 6 files changed, 28 insertions(+), 11 deletions(-) diff --git a/kotlin/internal/native/library.bzl b/kotlin/internal/native/library.bzl index 67fddae3a..abbfc56d9 100644 --- a/kotlin/internal/native/library.bzl +++ b/kotlin/internal/native/library.bzl @@ -13,6 +13,7 @@ def _kt_library_impl(ctx): # 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 = [] @@ -32,6 +33,7 @@ def _kt_library_impl(ctx): 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) diff --git a/kotlin/internal/native/toolchains.bzl b/kotlin/internal/native/toolchains.bzl index 085b3563d..11b820203 100644 --- a/kotlin/internal/native/toolchains.bzl +++ b/kotlin/internal/native/toolchains.bzl @@ -1,3 +1,4 @@ +load("@bazel_skylib//rules:common_settings.bzl", "string_flag") load("@bazel_skylib//rules/directory:providers.bzl", "DirectoryInfo") load("//src/main/starlark/core/repositories/kotlin:artifacts.bzl", "KOTLIN_NATIVE_ARTIFACTS_AND_TARGETS") @@ -6,6 +7,7 @@ KotlinNativeToolchainInfo = provider(fields = { "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): @@ -20,6 +22,7 @@ def _kt_native_toolchain_impl(ctx): konan_home_files = depset(transitive = [konan_home_info.transitive_files]), konan_properties = konan_properties, targets = ctx.attr.targets, + target = ctx.attr.target, ), ), ] @@ -35,6 +38,9 @@ kt_native_toolchain = rule( 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], ) @@ -48,33 +54,33 @@ def kt_configure_native_toolchains(): # Create toolchains for each exec platform and their supported targets for exec_platform, artifacts_and_targets in KOTLIN_NATIVE_ARTIFACTS_AND_TARGETS.items(): + exec_compatible_with = artifacts_and_targets.exec_compatible_with + default_target = artifacts_and_targets.targets[tuple(exec_compatible_with)][0] for target_constraint_tuple, kotlin_native_targets in artifacts_and_targets.targets.items(): target_os, target_cpu = target_constraint_tuple # Create a unique name for this toolchain - toolchain_name = "default_kt_native_toolchain_{}_to_{}_{}".format( - exec_platform, - target_os.split("//")[1].replace(":", "_").replace("/", "_"), - target_cpu.split("//")[1].replace(":", "_").replace("/", "_"), - ) - - toolchain_impl = "default_kt_native_{}_to_{}_{}".format( + toolchain_suffix = "{}_to_{}_{}".format( exec_platform, - target_os.split("//")[1].replace(":", "_").replace("/", "_"), - target_cpu.split("//")[1].replace(":", "_").replace("/", "_"), + 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) # 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 = artifacts_and_targets.exec_compatible_with, + 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/src/main/kotlin/io/bazel/kotlin/builder/tasks/KotlinBuilder.kt b/src/main/kotlin/io/bazel/kotlin/builder/tasks/KotlinBuilder.kt index b70d1efd1..5dddf20a1 100644 --- a/src/main/kotlin/io/bazel/kotlin/builder/tasks/KotlinBuilder.kt +++ b/src/main/kotlin/io/bazel/kotlin/builder/tasks/KotlinBuilder.kt @@ -95,6 +95,7 @@ class KotlinBuilder KLIBS("--klibs"), OUTPUT_KLIB("--output_klib"), KONAN_HOME("--konan_home"), + KOTLIN_NATIVE_TARGET("--kotlin_native_target"), } } @@ -229,6 +230,9 @@ class KotlinBuilder with(infoBuilder.toolchainInfoBuilder.nativeBuilder) { this.setKonanHome(argMap.mandatorySingle(KotlinBuilderFlags.KONAN_HOME)) + this.setKotlinNativeTarget( + argMap.mandatorySingle(KotlinBuilderFlags.KOTLIN_NATIVE_TARGET), + ) } with(inputsBuilder) { 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 index 578ba1c06..af3a20d64 100644 --- a/src/main/kotlin/io/bazel/kotlin/builder/tasks/knative/KotlinNativeTaskExecutor.kt +++ b/src/main/kotlin/io/bazel/kotlin/builder/tasks/knative/KotlinNativeTaskExecutor.kt @@ -65,6 +65,9 @@ class KotlinNativeTaskExecutor 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 diff --git a/src/main/protobuf/kotlin_model.proto b/src/main/protobuf/kotlin_model.proto index 164acc269..ea6485747 100644 --- a/src/main/protobuf/kotlin_model.proto +++ b/src/main/protobuf/kotlin_model.proto @@ -45,6 +45,8 @@ message KotlinToolchainInfo { 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; diff --git a/src/main/starlark/core/repositories/kotlin/artifacts.bzl b/src/main/starlark/core/repositories/kotlin/artifacts.bzl index 328a8aaf3..121ee68d0 100644 --- a/src/main/starlark/core/repositories/kotlin/artifacts.bzl +++ b/src/main/starlark/core/repositories/kotlin/artifacts.bzl @@ -87,7 +87,7 @@ KOTLIN_NATIVE_ARTIFACTS_AND_TARGETS = { ("@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_64"], + ("@platforms//os:linux", "@platforms//cpu:x86_64"): ["linux_x64"], ("@platforms//os:windows", "@platforms//cpu:x86_64"): ["mingw_x64"], }, ), From 2e33d76f589acbb2037b67f50a212387c8872baf Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Sun, 10 Aug 2025 12:42:47 -0400 Subject: [PATCH 29/40] Set default target correctly --- kotlin/internal/native/toolchains.bzl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kotlin/internal/native/toolchains.bzl b/kotlin/internal/native/toolchains.bzl index 11b820203..c04a261c0 100644 --- a/kotlin/internal/native/toolchains.bzl +++ b/kotlin/internal/native/toolchains.bzl @@ -1,4 +1,3 @@ -load("@bazel_skylib//rules:common_settings.bzl", "string_flag") load("@bazel_skylib//rules/directory:providers.bzl", "DirectoryInfo") load("//src/main/starlark/core/repositories/kotlin:artifacts.bzl", "KOTLIN_NATIVE_ARTIFACTS_AND_TARGETS") @@ -55,7 +54,6 @@ def kt_configure_native_toolchains(): # Create toolchains for each exec platform and their supported targets for exec_platform, artifacts_and_targets in KOTLIN_NATIVE_ARTIFACTS_AND_TARGETS.items(): exec_compatible_with = artifacts_and_targets.exec_compatible_with - default_target = artifacts_and_targets.targets[tuple(exec_compatible_with)][0] for target_constraint_tuple, kotlin_native_targets in artifacts_and_targets.targets.items(): target_os, target_cpu = target_constraint_tuple @@ -67,6 +65,7 @@ def kt_configure_native_toolchains(): ) toolchain_name = "default_kt_native_toolchain_{}".format(toolchain_suffix) toolchain_impl = "default_kt_native_{}".format(toolchain_suffix) + default_target = artifacts_and_targets.targets[target_constraint_tuple][0] # Create the toolchain implementation kt_native_toolchain( From 0d6850e472b2a708fe2a3845ec29b1bc8afe355e Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Sun, 10 Aug 2025 14:29:49 -0400 Subject: [PATCH 30/40] Create CLI toolchain for kotlinc-native and use that for builder --- MODULE.bazel | 2 +- kotlin/compiler/compiler.bzl | 17 +--- kotlin/internal/native/toolchains.bzl | 10 +-- .../io/bazel/kotlin/builder/cmd/BUILD.bazel | 4 +- .../kotlin/builder/toolchain/BUILD.bazel | 1 - .../io/bazel/kotlin/compiler/BUILD.bazel | 1 - .../starlark/core/compile/cli/BUILD.bazel | 5 +- src/main/starlark/core/compile/cli/native.bzl | 87 +++++++++++++++++++ src/main/starlark/core/compile/rules.bzl | 16 +++- ...D.com_github_jetbrains_kotlin_native.bazel | 15 ++++ .../BUILD.kotlin-native_capabilities.bazel | 17 ++-- .../core/repositories/kotlin/artifacts.bzl | 33 +------ 12 files changed, 138 insertions(+), 70 deletions(-) create mode 100644 src/main/starlark/core/compile/cli/native.bzl diff --git a/MODULE.bazel b/MODULE.bazel index d10e09bfd..3915c7f64 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -43,7 +43,7 @@ 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") diff --git a/kotlin/compiler/compiler.bzl b/kotlin/compiler/compiler.bzl index 339b05c5d..c60135414 100644 --- a/kotlin/compiler/compiler.bzl +++ b/kotlin/compiler/compiler.bzl @@ -12,9 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -load("@com_github_jetbrains_kotlin//:artifacts.bzl", "KOTLINC_ARTIFACTS", "KOTLIN_NATIVE_ARTIFACTS_AND_TARGETS") +load("@com_github_jetbrains_kotlin//:artifacts.bzl", "KOTLINC_ARTIFACTS") load("//kotlin:jvm.bzl", "kt_jvm_import") -load("//kotlin/internal:defs.bzl", _KT_COMPILER_REPO = "KT_COMPILER_REPO", _KT_NATIVE_COMPILER_REPO_PREFIX = "KT_NATIVE_COMPILER_REPO_PREFIX") +load("//kotlin/internal:defs.bzl", _KT_COMPILER_REPO = "KT_COMPILER_REPO") KOTLIN_STDLIBS = [ "//kotlin/compiler:annotations", @@ -63,16 +63,3 @@ def kt_configure_compiler(): _import_artifacts(KOTLINC_ARTIFACTS.jvm, kt_jvm_import) _import_artifacts(KOTLINC_ARTIFACTS.core, kt_jvm_import) - for platform in KOTLIN_NATIVE_ARTIFACTS_AND_TARGETS.keys(): - _import_artifacts(KOTLIN_NATIVE_ARTIFACTS_AND_TARGETS[platform], kt_jvm_import, compiler_repo = _KT_NATIVE_COMPILER_REPO_PREFIX + "_" + platform) - - # a convenience alias for kotlin-native to be referenced in other places - native.alias( - actual = select({ - "@bazel_tools//src/conditions:linux_x86_64": "//kotlin/compiler:kotlin-native-linux-x86_64", - "@bazel_tools//src/conditions:darwin": "//kotlin/compiler:kotlin-native-macos-x86_64", - "@bazel_tools//src/conditions:windows": "//kotlin/compiler:kotlin-native-windows_x86_64", - "@bazel_tools//src/conditions:darwin_arm64": "//kotlin/compiler:kotlin-native-macos_aarch64", - }), - name = "kotlin-native", - ) diff --git a/kotlin/internal/native/toolchains.bzl b/kotlin/internal/native/toolchains.bzl index c04a261c0..49f16ff03 100644 --- a/kotlin/internal/native/toolchains.bzl +++ b/kotlin/internal/native/toolchains.bzl @@ -1,5 +1,5 @@ load("@bazel_skylib//rules/directory:providers.bzl", "DirectoryInfo") -load("//src/main/starlark/core/repositories/kotlin:artifacts.bzl", "KOTLIN_NATIVE_ARTIFACTS_AND_TARGETS") +load("//src/main/starlark/core/repositories/kotlin:artifacts.bzl", "KOTLIN_NATIVE_TARGETS") KotlinNativeToolchainInfo = provider(fields = { "konan_home": "The path to konan.home directory", @@ -52,9 +52,9 @@ def kt_configure_native_toolchains(): ) # Create toolchains for each exec platform and their supported targets - for exec_platform, artifacts_and_targets in KOTLIN_NATIVE_ARTIFACTS_AND_TARGETS.items(): - exec_compatible_with = artifacts_and_targets.exec_compatible_with - for target_constraint_tuple, kotlin_native_targets in artifacts_and_targets.targets.items(): + 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 @@ -65,7 +65,7 @@ def kt_configure_native_toolchains(): ) toolchain_name = "default_kt_native_toolchain_{}".format(toolchain_suffix) toolchain_impl = "default_kt_native_{}".format(toolchain_suffix) - default_target = artifacts_and_targets.targets[target_constraint_tuple][0] + default_target = targets.targets[target_constraint_tuple][0] # Create the toolchain implementation kt_native_toolchain( 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 c542f8a48..469587972 100644 --- a/src/main/kotlin/io/bazel/kotlin/builder/cmd/BUILD.bazel +++ b/src/main/kotlin/io/bazel/kotlin/builder/cmd/BUILD.bazel @@ -19,13 +19,13 @@ 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", "//src/main/kotlin:jdeps-gen", "//src/main/kotlin:skip-code-gen", "//src/main/kotlin/io/bazel/kotlin/compiler:compiler.jar", + "//src/main/starlark/core/compile/cli:kotlin-native", "@com_github_jetbrains_kotlin//:home", "@kotlin_build_tools_impl//jar", "@kotlinx_serialization_core_jvm//jar", @@ -39,13 +39,13 @@ kt_bootstrap_binary( "-D@com_github_jetbrains_kotlin...build-tools-impl=$(rlocationpath @kotlin_build_tools_impl//jar)", "-D@com_github_jetbrains_kotlin...jvm-abi-gen=$(rlocationpath //kotlin/compiler:jvm-abi-gen)", "-D@com_github_jetbrains_kotlin...kotlin-compiler=$(rlocationpath //kotlin/compiler:kotlin-compiler)", - "-D@com_github_jetbrains_kotlin_native...kotlin-native=$(rlocationpath //kotlin/compiler:kotlin-native)", "-D@com_github_jetbrains_kotlin...kapt=$(rlocationpath //kotlin/compiler:kotlin-annotation-processing)", "-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: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 //src/main/starlark/core/compile/cli: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/toolchain/BUILD.bazel b/src/main/kotlin/io/bazel/kotlin/builder/toolchain/BUILD.bazel index 81aa8b226..fe3390a58 100644 --- a/src/main/kotlin/io/bazel/kotlin/builder/toolchain/BUILD.bazel +++ b/src/main/kotlin/io/bazel/kotlin/builder/toolchain/BUILD.bazel @@ -24,7 +24,6 @@ kt_bootstrap_library( "//kotlin/compiler:symbol-processing-api", "//kotlin/compiler:symbol-processing-cmdline", "//kotlin/compiler:kotlin-preloader", - "//kotlin/compiler:kotlin-native", ], visibility = ["//src:__subpackages__"], deps = [ diff --git a/src/main/kotlin/io/bazel/kotlin/compiler/BUILD.bazel b/src/main/kotlin/io/bazel/kotlin/compiler/BUILD.bazel index ed6dae343..0372403ac 100644 --- a/src/main/kotlin/io/bazel/kotlin/compiler/BUILD.bazel +++ b/src/main/kotlin/io/bazel/kotlin/compiler/BUILD.bazel @@ -23,7 +23,6 @@ kt_bootstrap_library( "//kotlin/compiler:kotlin-compiler", "//kotlin/compiler:kotlin-annotation-processing", "//kotlin/compiler:kotlin-script-runtime", - "//kotlin/compiler:kotlin-native", ], visibility = ["//src:__subpackages__"], ) diff --git a/src/main/starlark/core/compile/cli/BUILD.bazel b/src/main/starlark/core/compile/cli/BUILD.bazel index 46ed8b78b..dc6790d75 100644 --- a/src/main/starlark/core/compile/cli/BUILD.bazel +++ b/src/main/starlark/core/compile/cli/BUILD.bazel @@ -1,8 +1,9 @@ load("@rules_java//java:java_binary.bzl", "java_binary") 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/compile:common.bzl", "NATIVE_TYPE", "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..fe7d77941 --- /dev/null +++ b/src/main/starlark/core/compile/cli/native.bzl @@ -0,0 +1,87 @@ +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(): + # Ideally this would not be needed and be available from the toolchain + # but the builder uses java_binary and jvm_flags are propagated 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/main:__subpackages__"], + ) + 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] + + 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/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.com_github_jetbrains_kotlin_native.bazel b/src/main/starlark/core/repositories/BUILD.com_github_jetbrains_kotlin_native.bazel index fc2851223..1241b2f5e 100644 --- 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 @@ -12,6 +12,7 @@ # 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"]) @@ -46,3 +47,17 @@ filegroup( ) 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" + ], +) \ No newline at end of file diff --git a/src/main/starlark/core/repositories/BUILD.kotlin-native_capabilities.bazel b/src/main/starlark/core/repositories/BUILD.kotlin-native_capabilities.bazel index 9ee1911fd..5c4c0d026 100644 --- a/src/main/starlark/core/repositories/BUILD.kotlin-native_capabilities.bazel +++ b/src/main/starlark/core/repositories/BUILD.kotlin-native_capabilities.bazel @@ -12,7 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. load("@bazel_skylib//:bzl_library.bzl", "bzl_library") -load(":artifacts.bzl", "KOTLIN_NATIVE_ARTIFACT_LIST") package(default_visibility = ["//visibility:public"]) @@ -31,10 +30,12 @@ alias( actual = "@$git_repo$//:konan_properties", ) -[ - alias( - name = label, - actual = "@$git_repo$//:%s" % file.replace(".", "_"), - ) - for (label, file) in KOTLIN_NATIVE_ARTIFACT_LIST.items() -] +alias( + name = "kotlin-native", + actual = "@$git_repo$//:kotlin-native", +) + +alias( + name = "trove4j", + actual = "@$git_repo$//:trove4j", +) diff --git a/src/main/starlark/core/repositories/kotlin/artifacts.bzl b/src/main/starlark/core/repositories/kotlin/artifacts.bzl index 121ee68d0..6c9ba1b8f 100644 --- a/src/main/starlark/core/repositories/kotlin/artifacts.bzl +++ b/src/main/starlark/core/repositories/kotlin/artifacts.bzl @@ -70,14 +70,8 @@ KOTLINC_ARTIFACTS = struct( ), ) -KOTLIN_NATIVE_ARTIFACTS_AND_TARGETS = { +KOTLIN_NATIVE_TARGETS = { "linux_x86_64": struct( - plugin = {}, - compile = { - "kotlin-native-linux-x86_64": "konan/lib/kotlin-native.jar", - "trove4j-linux-x86_64": "konan/lib/trove4j.jar", - }, - runtime = {}, 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 @@ -92,12 +86,6 @@ KOTLIN_NATIVE_ARTIFACTS_AND_TARGETS = { }, ), "macos_x86_64": struct( - plugin = {}, - compile = { - "kotlin-native-macos-x86_64": "konan/lib/kotlin-native.jar", - "trove4j-macos-x86_64": "konan/lib/trove4j.jar", - }, - runtime = {}, exec_compatible_with = ["@platforms//os:macos", "@platforms//cpu:x86_64"], targets = { ("@platforms//os:android", "@platforms//cpu:armv7"): ["android_arm32"], @@ -121,12 +109,6 @@ KOTLIN_NATIVE_ARTIFACTS_AND_TARGETS = { }, ), "macos_aarch64": struct( - plugin = {}, - compile = { - "kotlin-native-macos_aarch64": "konan/lib/kotlin-native.jar", - "trove4j-macos_aarch64": "konan/lib/trove4j.jar", - }, - runtime = {}, exec_compatible_with = ["@platforms//os:macos", "@platforms//cpu:arm64"], targets = { ("@platforms//os:linux", "@platforms//cpu:x86_64"): ["linux_x64"], @@ -149,12 +131,6 @@ KOTLIN_NATIVE_ARTIFACTS_AND_TARGETS = { }, ), "windows_x86_64": struct( - plugin = {}, - compile = { - "kotlin-native-windows_x86_64": "konan/lib/kotlin-native.jar", - "trove4j-windows_x86_64": "konan/lib/trove4j.jar", - }, - runtime = {}, exec_compatible_with = ["@platforms//os:windows", "@platforms//cpu:x86_64"], targets = { ("@platforms//os:windows", "@platforms//cpu:x86_64"): ["mingw_x64"], @@ -173,10 +149,3 @@ KOTLINC_ARTIFACT_LIST = { for type in ["compile", "plugin", "runtime"] for (label, file) in getattr(getattr(KOTLINC_ARTIFACTS, lang), type).items() } - -KOTLIN_NATIVE_ARTIFACT_LIST = { - label: file - for platform in KOTLIN_NATIVE_ARTIFACTS_AND_TARGETS.keys() - for type in ["compile", "plugin", "runtime"] - for (label, file) in getattr(KOTLIN_NATIVE_ARTIFACTS_AND_TARGETS[platform], type).items() -} From b1fba976601088ec2f779832f2a6beae21eb6acf Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Sun, 10 Aug 2025 14:42:32 -0400 Subject: [PATCH 31/40] Fix build/test failures due to stale references --- src/main/starlark/core/compile/cli/BUILD.bazel | 2 +- src/main/starlark/core/compile/cli/native.bzl | 6 +++--- .../BUILD.com_github_jetbrains_kotlin_native.bazel | 6 +++--- src/test/kotlin/io/bazel/kotlin/builder/BUILD | 1 - .../io/bazel/kotlin/builder/KotlinAbstractTestBuilder.java | 2 +- src/test/kotlin/io/bazel/kotlin/defs.bzl | 2 +- 6 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/main/starlark/core/compile/cli/BUILD.bazel b/src/main/starlark/core/compile/cli/BUILD.bazel index dc6790d75..b401255d6 100644 --- a/src/main/starlark/core/compile/cli/BUILD.bazel +++ b/src/main/starlark/core/compile/cli/BUILD.bazel @@ -1,7 +1,7 @@ load("@rules_java//java:java_binary.bzl", "java_binary") 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", "NATIVE_TYPE", "TYPE") +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") diff --git a/src/main/starlark/core/compile/cli/native.bzl b/src/main/starlark/core/compile/cli/native.bzl index fe7d77941..dea7083b2 100644 --- a/src/main/starlark/core/compile/cli/native.bzl +++ b/src/main/starlark/core/compile/cli/native.bzl @@ -1,3 +1,4 @@ +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") @@ -48,12 +49,12 @@ def define_native_cli_toolchains(): "@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/main:__subpackages__"], + visibility = ["//src:__subpackages__"], ) 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(): + for target_constraint_tuple in targets.targets.keys(): target_os, target_cpu = target_constraint_tuple # Create a unique name for this toolchain @@ -64,7 +65,6 @@ def define_native_cli_toolchains(): ) 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] kotlin_native = Label("@" + KT_NATIVE_COMPILER_REPO_PREFIX + "_" + exec_platform + "//:kotlin-native") 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 index 1241b2f5e..e04b88613 100644 --- 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 @@ -51,13 +51,13 @@ filegroup( kt_jvm_import( name = "kotlin-native", jars = [ - "konan/lib/kotlin-native.jar" + "konan/lib/kotlin-native.jar", ], ) kt_jvm_import( name = "trove4j", jars = [ - "konan/lib/trove4j.jar" + "konan/lib/trove4j.jar", ], -) \ No newline at end of file +) diff --git a/src/test/kotlin/io/bazel/kotlin/builder/BUILD b/src/test/kotlin/io/bazel/kotlin/builder/BUILD index 35f8cf733..010f6a407 100644 --- a/src/test/kotlin/io/bazel/kotlin/builder/BUILD +++ b/src/test/kotlin/io/bazel/kotlin/builder/BUILD @@ -39,7 +39,6 @@ java_library( "KotlinJvmTestBuilder.java", ], data = [ - "//kotlin/compiler:kotlin-native", "//src/main/kotlin/io/bazel/kotlin/compiler", "@com_github_jetbrains_kotlin//:home", ], diff --git a/src/test/kotlin/io/bazel/kotlin/builder/KotlinAbstractTestBuilder.java b/src/test/kotlin/io/bazel/kotlin/builder/KotlinAbstractTestBuilder.java index b4278df49..567606819 100644 --- a/src/test/kotlin/io/bazel/kotlin/builder/KotlinAbstractTestBuilder.java +++ b/src/test/kotlin/io/bazel/kotlin/builder/KotlinAbstractTestBuilder.java @@ -235,7 +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("//src/main/starlark/core/compile/cli: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/defs.bzl b/src/test/kotlin/io/bazel/kotlin/defs.bzl index 4252c8e99..1600fd624 100644 --- a/src/test/kotlin/io/bazel/kotlin/defs.bzl +++ b/src/test/kotlin/io/bazel/kotlin/defs.bzl @@ -39,7 +39,7 @@ def kt_rules_test(name, **kwargs): "//kotlin/compiler:annotations", "//kotlin/compiler:jvm-abi-gen", "//kotlin/compiler:kotlin-compiler", - "//kotlin/compiler:kotlin-native", + "//src/main/starlark/core/compile/cli:kotlin-native", "//kotlin/compiler:kotlin-stdlib", "//kotlin/compiler:kotlin-stdlib-jdk7", "//kotlin/compiler:kotlin-stdlib-jdk8", From cd605524900810141b5ba5c87a3080336f478d7f Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Sun, 10 Aug 2025 14:48:37 -0400 Subject: [PATCH 32/40] Fix checksum for windows --- src/main/starlark/core/repositories/versions.bzl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/starlark/core/repositories/versions.bzl b/src/main/starlark/core/repositories/versions.bzl index 92f74d3ba..4f80685a9 100644 --- a/src/main/starlark/core/repositories/versions.bzl +++ b/src/main/starlark/core/repositories/versions.bzl @@ -111,7 +111,7 @@ versions = struct( url_templates = [ "https://github.com/JetBrains/kotlin/releases/download/v{version}/kotlin-native-prebuilt-windows-x86_64-{version}.zip", ], - sha256 = "8df16175b962bc4264a5c3b32cb042d91458babbd093c0f36194dc4645f5fe2", + sha256 = "03301473bb9e68dadfdd265857a2a5913a147e700e345d32db73e0a21a2ffbfa", strip_prefix_template = "kotlin-native-prebuilt-windows-x86_64-{version}", ), KSP_CURRENT_COMPILER_PLUGIN_RELEASE = version( From bba1ea478416db8dfe6ea6572f28a78c0717571e Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Sun, 10 Aug 2025 14:54:50 -0400 Subject: [PATCH 33/40] Regen docs --- docs/kotlin.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/kotlin.md b/docs/kotlin.md index da3efba5e..b0f9dd387 100755 --- a/docs/kotlin.md +++ b/docs/kotlin.md @@ -598,7 +598,7 @@ Call this in the WORKSPACE file to setup the Kotlin rules. | 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 = "8df16175b962bc4264a5c3b32cb042d91458babbd093c0f36194dc4645f5fe2", 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")` | +| 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")` | From 96eb77a893ae6197ec762d103606289c18de86b9 Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Sun, 10 Aug 2025 15:12:14 -0400 Subject: [PATCH 34/40] Need an alias target in kotlin/compiler sadly to make runfiles work --- kotlin/compiler/BUILD | 4 ++++ kotlin/compiler/BUILD.release.bazel | 4 ++++ kotlin/compiler/native.bzl | 17 +++++++++++++++++ src/main/kotlin/BUILD.release.bazel | 2 ++ .../io/bazel/kotlin/builder/cmd/BUILD.bazel | 4 ++-- src/main/starlark/core/compile/cli/native.bzl | 14 -------------- .../builder/KotlinAbstractTestBuilder.java | 2 +- 7 files changed, 30 insertions(+), 17 deletions(-) create mode 100644 kotlin/compiler/native.bzl 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/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/src/main/kotlin/BUILD.release.bazel b/src/main/kotlin/BUILD.release.bazel index 2211fe94b..493844783 100644 --- a/src/main/kotlin/BUILD.release.bazel +++ b/src/main/kotlin/BUILD.release.bazel @@ -46,6 +46,7 @@ java_binary( "//kotlin/compiler:symbol-processing-api", "//kotlin/compiler:symbol-processing-cmdline", "//src/main/kotlin/io/bazel/kotlin/compiler", + "//kotlin/compiler:kotlin-native", "@com_github_jetbrains_kotlin//:home", "@kotlin_build_tools_impl//jar", "@kotlinx_serialization_core_jvm//jar", @@ -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/cmd/BUILD.bazel b/src/main/kotlin/io/bazel/kotlin/builder/cmd/BUILD.bazel index 469587972..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,13 +19,13 @@ 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", "//src/main/kotlin:jdeps-gen", "//src/main/kotlin:skip-code-gen", "//src/main/kotlin/io/bazel/kotlin/compiler:compiler.jar", - "//src/main/starlark/core/compile/cli:kotlin-native", "@com_github_jetbrains_kotlin//:home", "@kotlin_build_tools_impl//jar", "@kotlinx_serialization_core_jvm//jar", @@ -45,7 +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 //src/main/starlark/core/compile/cli:kotlin-native)", + "-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/starlark/core/compile/cli/native.bzl b/src/main/starlark/core/compile/cli/native.bzl index dea7083b2..32f24e8ad 100644 --- a/src/main/starlark/core/compile/cli/native.bzl +++ b/src/main/starlark/core/compile/cli/native.bzl @@ -37,20 +37,6 @@ kotlin_native_cli_toolchain = rule( ) def define_native_cli_toolchains(): - # Ideally this would not be needed and be available from the toolchain - # but the builder uses java_binary and jvm_flags are propagated 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__"], - ) for exec_platform, targets in KOTLIN_NATIVE_TARGETS.items(): exec_compatible_with = targets.exec_compatible_with diff --git a/src/test/kotlin/io/bazel/kotlin/builder/KotlinAbstractTestBuilder.java b/src/test/kotlin/io/bazel/kotlin/builder/KotlinAbstractTestBuilder.java index 567606819..b4278df49 100644 --- a/src/test/kotlin/io/bazel/kotlin/builder/KotlinAbstractTestBuilder.java +++ b/src/test/kotlin/io/bazel/kotlin/builder/KotlinAbstractTestBuilder.java @@ -235,7 +235,7 @@ static KotlinToolchain toolchainForTest() { return KotlinToolchain.createToolchain( javaHome, new File(Deps.Dep.fromLabel("//kotlin/compiler:kotlin-compiler").singleCompileJar()), - new File(Deps.Dep.fromLabel("//src/main/starlark/core/compile/cli:kotlin-native").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()), From 490623922d5f33d53f13712a55e389dbae73bd03 Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Sun, 10 Aug 2025 15:14:05 -0400 Subject: [PATCH 35/40] buildifier and fix one reference --- src/main/kotlin/BUILD.release.bazel | 2 +- src/test/kotlin/io/bazel/kotlin/defs.bzl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/BUILD.release.bazel b/src/main/kotlin/BUILD.release.bazel index 493844783..50680c987 100644 --- a/src/main/kotlin/BUILD.release.bazel +++ b/src/main/kotlin/BUILD.release.bazel @@ -42,11 +42,11 @@ 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", "//src/main/kotlin/io/bazel/kotlin/compiler", - "//kotlin/compiler:kotlin-native", "@com_github_jetbrains_kotlin//:home", "@kotlin_build_tools_impl//jar", "@kotlinx_serialization_core_jvm//jar", diff --git a/src/test/kotlin/io/bazel/kotlin/defs.bzl b/src/test/kotlin/io/bazel/kotlin/defs.bzl index 1600fd624..4252c8e99 100644 --- a/src/test/kotlin/io/bazel/kotlin/defs.bzl +++ b/src/test/kotlin/io/bazel/kotlin/defs.bzl @@ -39,7 +39,7 @@ def kt_rules_test(name, **kwargs): "//kotlin/compiler:annotations", "//kotlin/compiler:jvm-abi-gen", "//kotlin/compiler:kotlin-compiler", - "//src/main/starlark/core/compile/cli:kotlin-native", + "//kotlin/compiler:kotlin-native", "//kotlin/compiler:kotlin-stdlib", "//kotlin/compiler:kotlin-stdlib-jdk7", "//kotlin/compiler:kotlin-stdlib-jdk8", From 89c25cd31450046fe666516ab0dcad675d0b8bf7 Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Sun, 10 Aug 2025 16:15:46 -0400 Subject: [PATCH 36/40] Fix some integration tests --- MODULE.release.bazel | 10 ++++++++++ kotlin/internal/BUILD | 2 ++ kotlin/internal/BUILD.release.bazel | 1 + kotlin/internal/native/BUILD.bazel | 21 +++++++++++++++++++++ kotlin/internal/native/BUILD.release.bazel | 15 +++++++++++++++ kotlin/internal/toolchains.bzl | 6 +++++- 6 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 kotlin/internal/native/BUILD.release.bazel 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/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/native/BUILD.bazel b/kotlin/internal/native/BUILD.bazel index 2c8067ce6..43844114c 100644 --- a/kotlin/internal/native/BUILD.bazel +++ b/kotlin/internal/native/BUILD.bazel @@ -1,3 +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..adbe66a03 --- /dev/null +++ b/kotlin/internal/native/BUILD.release.bazel @@ -0,0 +1,15 @@ +load(":toolchains.bzl", "kt_configure_native_toolchains") +load("@bazel_skylib//:bzl_library.bzl", "bzl_library") + +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", + ], +) \ No newline at end of file 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"], From 911f49d555cc8241a49ba4b7e6fe7c716aa698a8 Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Sun, 10 Aug 2025 16:15:59 -0400 Subject: [PATCH 37/40] Update docs --- docs/kotlin.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/kotlin.md b/docs/kotlin.md index b0f9dd387..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. From c23bc5ffb71594e632332d63c38a34470fc7f651 Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Sun, 10 Aug 2025 16:17:27 -0400 Subject: [PATCH 38/40] lint --- kotlin/internal/native/BUILD.release.bazel | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kotlin/internal/native/BUILD.release.bazel b/kotlin/internal/native/BUILD.release.bazel index adbe66a03..3178ca320 100644 --- a/kotlin/internal/native/BUILD.release.bazel +++ b/kotlin/internal/native/BUILD.release.bazel @@ -1,5 +1,5 @@ -load(":toolchains.bzl", "kt_configure_native_toolchains") load("@bazel_skylib//:bzl_library.bzl", "bzl_library") +load(":toolchains.bzl", "kt_configure_native_toolchains") kt_configure_native_toolchains() @@ -12,4 +12,4 @@ bzl_library( "//src/main/starlark/core/repositories/kotlin", "@bazel_skylib//rules/directory", ], -) \ No newline at end of file +) From 1cac1b1f982c5bd41bed7e592b685aafb2574eb2 Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Sun, 10 Aug 2025 17:57:19 -0400 Subject: [PATCH 39/40] Add tests for transitive outputs --- kotlin/internal/native/library.bzl | 7 ++++--- src/test/starlark/internal/native/kt_library_tests.bzl | 9 ++++++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/kotlin/internal/native/library.bzl b/kotlin/internal/native/library.bzl index abbfc56d9..856ebb157 100644 --- a/kotlin/internal/native/library.bzl +++ b/kotlin/internal/native/library.bzl @@ -17,7 +17,8 @@ def _kt_library_impl(ctx): deps_klibs = [] transitive_klibs = [] - runfiles = ctx.runfiles(files = ctx.files.data) + 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) @@ -57,10 +58,10 @@ def _kt_library_impl(ctx): ) return [ - DefaultInfo(files = depset(outputs), runfiles = runfiles), + DefaultInfo(files = depset(outputs, transitive = transitive_klibs + deps_klibs), runfiles = runfiles), _KtKlibInfo( klibs = depset(outputs), - transitive_klibs = depset(transitive = transitive_klibs), + transitive_klibs = depset(transitive = transitive_klibs + deps_klibs), ), ] diff --git a/src/test/starlark/internal/native/kt_library_tests.bzl b/src/test/starlark/internal/native/kt_library_tests.bzl index c53bc93a8..7d9a2f75b 100644 --- a/src/test/starlark/internal/native/kt_library_tests.bzl +++ b/src/test/starlark/internal/native/kt_library_tests.bzl @@ -1,5 +1,7 @@ load("@rules_testing//lib:analysis_test.bzl", "analysis_test") load("@rules_testing//lib:test_suite.bzl", "test_suite") +load("@rules_testing//lib:truth.bzl", "subjects") +load("@rules_testing//tests:test_util.bzl", "test_util") load("//kotlin/internal:defs.bzl", "KtKlibInfo") load("//kotlin/internal/native:library.bzl", "kt_library") @@ -17,6 +19,8 @@ def _test_kt_library_basic_impl(env, 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"]) @@ -35,6 +39,9 @@ def _test_kt_library_deps_impl(env, target): # 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"]) @@ -82,7 +89,7 @@ def kt_library_test_suite(name): tests = [ # assert compilation of single target with no deps works _test_kt_library_basic, - # Assert compilation with deps works + # Assert compilation with deps works and transitive outputs are propagated _test_kt_library_deps, # Assert runfiles are available _test_kt_library_runfiles, From f244d54113ab2f84844117159ac18ec2af2995f1 Mon Sep 17 00:00:00 2001 From: Sridhar Mocherla Date: Sun, 10 Aug 2025 17:59:13 -0400 Subject: [PATCH 40/40] Remove unused loads --- src/test/starlark/internal/native/kt_library_tests.bzl | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/starlark/internal/native/kt_library_tests.bzl b/src/test/starlark/internal/native/kt_library_tests.bzl index 7d9a2f75b..5a80ae9de 100644 --- a/src/test/starlark/internal/native/kt_library_tests.bzl +++ b/src/test/starlark/internal/native/kt_library_tests.bzl @@ -1,7 +1,5 @@ load("@rules_testing//lib:analysis_test.bzl", "analysis_test") load("@rules_testing//lib:test_suite.bzl", "test_suite") -load("@rules_testing//lib:truth.bzl", "subjects") -load("@rules_testing//tests:test_util.bzl", "test_util") load("//kotlin/internal:defs.bzl", "KtKlibInfo") load("//kotlin/internal/native:library.bzl", "kt_library")