From b47eea7e0867a8862d73633bddbca20bcfd59cdf Mon Sep 17 00:00:00 2001 From: snorlax Date: Sun, 21 Jan 2024 00:27:54 +0800 Subject: [PATCH] ksp: support ksp options --- docs/kotlin.md | 3 ++- kotlin/internal/defs.bzl | 1 + kotlin/internal/jvm/compile.bzl | 11 +++++++++++ kotlin/internal/jvm/impl.bzl | 7 ++++++- kotlin/internal/jvm/jvm.bzl | 6 ++++++ kotlin/internal/jvm/plugins.bzl | 8 ++++++++ .../io/bazel/kotlin/builder/tasks/KotlinBuilder.kt | 4 ++++ .../bazel/kotlin/builder/tasks/jvm/CompilationTask.kt | 7 +++++++ src/main/protobuf/kotlin_model.proto | 2 ++ 9 files changed, 47 insertions(+), 2 deletions(-) diff --git a/docs/kotlin.md b/docs/kotlin.md index aaa1b9ba7..7c623d5c9 100755 --- a/docs/kotlin.md +++ b/docs/kotlin.md @@ -445,7 +445,7 @@ kt_kotlinc_options(name, name, deps, processor_class) +kt_ksp_plugin(name, deps, options, processor_class) Define a KSP plugin for the Kotlin compiler to run. The plugin can then be referenced in the `plugins` attribute @@ -478,6 +478,7 @@ kt_ksp_plugin(name, name | A unique name for this target. | Name | required | | |deps | The list of libraries to be added to the compiler's plugin classpath | List of labels | optional | [] | +|options | Dictionary of options to be passed to the ksp plugin. | Dictionary: String -> String | optional | {} | |processor_class | The fully qualified class name that the Java compiler uses as an entry point to the annotation processor. | String | required | | diff --git a/kotlin/internal/defs.bzl b/kotlin/internal/defs.bzl index 498ce0645..06df4cb0e 100644 --- a/kotlin/internal/defs.bzl +++ b/kotlin/internal/defs.bzl @@ -63,5 +63,6 @@ KtCompilerPluginInfo = provider( KspPluginInfo = provider( fields = { "plugins": "List of JavaPLuginInfo providers for the plugins to run with KSP", + "options": "List of plugin options, represented as string with key=value field, to be passed to the ksp compiler", }, ) diff --git a/kotlin/internal/jvm/compile.bzl b/kotlin/internal/jvm/compile.bzl index 5b1df20fb..e0432557b 100644 --- a/kotlin/internal/jvm/compile.bzl +++ b/kotlin/internal/jvm/compile.bzl @@ -317,6 +317,7 @@ def _run_kapt_builder_actions( compile_deps = compile_deps, deps_artifacts = deps_artifacts, annotation_processors = annotation_processors, + ksp_options = [], transitive_runtime_jars = transitive_runtime_jars, plugins = plugins, outputs = { @@ -343,6 +344,7 @@ def _run_ksp_builder_actions( compile_deps, deps_artifacts, annotation_processors, + options, transitive_runtime_jars, plugins): """Runs KSP using the KotlinBuilder tool @@ -362,6 +364,7 @@ def _run_ksp_builder_actions( compile_deps = compile_deps, deps_artifacts = deps_artifacts, annotation_processors = annotation_processors, + ksp_options = options, transitive_runtime_jars = transitive_runtime_jars, plugins = plugins, outputs = { @@ -383,6 +386,7 @@ def _run_kt_builder_action( compile_deps, deps_artifacts, annotation_processors, + ksp_options, transitive_runtime_jars, plugins, outputs, @@ -408,6 +412,7 @@ def _run_kt_builder_action( args.add_all("--deps_artifacts", deps_artifacts, omit_if_empty = True) args.add_all("--kotlin_friend_paths", associates.jars, map_each = _associate_utils.flatten_jars) args.add("--instrument_coverage", ctx.coverage_instrumented()) + args.add_all("--ksp_options", ksp_options, omit_if_empty = True) # Collect and prepare plugin descriptor for the worker. args.add_all( @@ -535,6 +540,8 @@ def kt_jvm_produce_jar_actions(ctx, rule_kind): ) annotation_processors = _plugin_mappers.targets_to_annotation_processors(ctx.attr.plugins + ctx.attr.deps) ksp_annotation_processors = _plugin_mappers.targets_to_ksp_annotation_processors(ctx.attr.plugins + ctx.attr.deps) + ksp_options = _plugin_mappers.targets_to_ksp_options(ctx.attr.plugins + ctx.attr.deps).to_list() + transitive_runtime_jars = _plugin_mappers.targets_to_transitive_runtime_jars(ctx.attr.plugins + ctx.attr.deps) plugins = ctx.attr.plugins + _exported_plugins(deps = ctx.attr.deps) deps_artifacts = _deps_artifacts(toolchains, ctx.attr.deps + associates.targets) @@ -558,6 +565,7 @@ def kt_jvm_produce_jar_actions(ctx, rule_kind): deps_artifacts = deps_artifacts, annotation_processors = annotation_processors, ksp_annotation_processors = ksp_annotation_processors, + ksp_options = ksp_options, transitive_runtime_jars = transitive_runtime_jars, plugins = plugins, compile_jar = compile_jar, @@ -650,6 +658,7 @@ def _run_kt_java_builder_actions( deps_artifacts, annotation_processors, ksp_annotation_processors, + ksp_options, transitive_runtime_jars, plugins, compile_jar, @@ -699,6 +708,7 @@ def _run_kt_java_builder_actions( compile_deps = compile_deps, deps_artifacts = deps_artifacts, annotation_processors = ksp_annotation_processors, + options = ksp_options, transitive_runtime_jars = transitive_runtime_jars, plugins = plugins, ) @@ -736,6 +746,7 @@ def _run_kt_java_builder_actions( compile_deps = compile_deps, deps_artifacts = deps_artifacts, annotation_processors = [], + ksp_options = [], transitive_runtime_jars = transitive_runtime_jars, plugins = plugins, outputs = outputs, diff --git a/kotlin/internal/jvm/impl.bzl b/kotlin/internal/jvm/impl.bzl index 4c6569829..21e06cf40 100644 --- a/kotlin/internal/jvm/impl.bzl +++ b/kotlin/internal/jvm/impl.bzl @@ -424,6 +424,11 @@ def kt_compiler_plugin_impl(ctx): def kt_ksp_plugin_impl(ctx): info = java_common.merge([dep[JavaInfo] for dep in ctx.attr.deps]) classpath = depset(info.runtime_output_jars, transitive = [info.transitive_runtime_jars]) + options = [] + for (k, v) in ctx.attr.options.items(): + if "=" in k: + fail("kt_compiler_plugin options keys cannot contain the = symbol") + options.append("%s=%s" % (k, v)) return [ DefaultInfo(files = classpath), @@ -437,5 +442,5 @@ def kt_ksp_plugin_impl(ctx): # processors out of the public ABI. generates_api = True, ), - ]), + ], options = options), ] diff --git a/kotlin/internal/jvm/jvm.bzl b/kotlin/internal/jvm/jvm.bzl index bef495e43..ef7e6fe2c 100644 --- a/kotlin/internal/jvm/jvm.bzl +++ b/kotlin/internal/jvm/jvm.bzl @@ -597,6 +597,12 @@ kt_jvm_library( doc = " The fully qualified class name that the Java compiler uses as an entry point to the annotation processor.", mandatory = True, ), + "options": attr.string_dict( + doc = """\ +Dictionary of options to be passed to the ksp plugin. +""", + default = {}, + ), }, implementation = _kt_ksp_plugin_impl, provides = [_KspPluginInfo], diff --git a/kotlin/internal/jvm/plugins.bzl b/kotlin/internal/jvm/plugins.bzl index 71c44026e..4c39c0a05 100644 --- a/kotlin/internal/jvm/plugins.bzl +++ b/kotlin/internal/jvm/plugins.bzl @@ -49,6 +49,13 @@ def _targets_to_ksp_annotation_processors(targets): plugins.append(plugin.plugins) return depset(plugins) +def _targets_to_ksp_options(targets): + options = [] + for t in targets: + if _KspPluginInfo in t: + options.extend(t[_KspPluginInfo].options) + return depset(options) + def _targets_to_annotation_processors_java_plugin_info(targets): return [t[JavaPluginInfo] for t in targets if JavaPluginInfo in t] @@ -66,6 +73,7 @@ def _targets_to_transitive_runtime_jars(targets): mappers = struct( targets_to_annotation_processors = _targets_to_annotation_processors, targets_to_ksp_annotation_processors = _targets_to_ksp_annotation_processors, + targets_to_ksp_options = _targets_to_ksp_options, targets_to_annotation_processors_java_plugin_info = _targets_to_annotation_processors_java_plugin_info, targets_to_transitive_runtime_jars = _targets_to_transitive_runtime_jars, kt_plugin_to_processor = _kt_plugin_to_processor, 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 d2dd9d483..bedd7ea06 100644 --- a/src/main/kotlin/io/bazel/kotlin/builder/tasks/KotlinBuilder.kt +++ b/src/main/kotlin/io/bazel/kotlin/builder/tasks/KotlinBuilder.kt @@ -87,6 +87,7 @@ class KotlinBuilder @Inject internal constructor( REDUCED_CLASSPATH_MODE("--reduced_classpath_mode"), INSTRUMENT_COVERAGE("--instrument_coverage"), KSP_GENERATED_JAVA_SRCJAR("--ksp_generated_java_srcjar"), + KSP_OPTIONS("--ksp_options"), } } @@ -295,6 +296,9 @@ class KotlinBuilder @Inject internal constructor( addAllCompilerPluginClasspath( argMap.optional(KotlinBuilderFlags.COMPILER_PLUGIN_CLASS_PATH) ?: emptyList(), ) + addAllKspOptions( + argMap.optional(KotlinBuilderFlags.KSP_OPTIONS) ?: emptyList(), + ) argMap.optional(KotlinBuilderFlags.SOURCES) ?.iterator() diff --git a/src/main/kotlin/io/bazel/kotlin/builder/tasks/jvm/CompilationTask.kt b/src/main/kotlin/io/bazel/kotlin/builder/tasks/jvm/CompilationTask.kt index 3aec8cb03..349427670 100644 --- a/src/main/kotlin/io/bazel/kotlin/builder/tasks/jvm/CompilationTask.kt +++ b/src/main/kotlin/io/bazel/kotlin/builder/tasks/jvm/CompilationTask.kt @@ -208,6 +208,10 @@ internal fun JvmCompilationTask.kspArgs( flag(pair.first, value) } } + + inputs.kspOptionsList.forEach { option -> + flag("apoption", option) + } } } } @@ -281,6 +285,9 @@ private fun JvmCompilationTask.runKspPlugin( .flag("-d", directories.generatedClasses) .values(inputs.kotlinSourcesList) .values(inputs.javaSourcesList).list().let { args -> + context.whenTracing { + printLines("Ksp args:", args) + } context.executeCompilerTask( args, compiler::compile, diff --git a/src/main/protobuf/kotlin_model.proto b/src/main/protobuf/kotlin_model.proto index 2a3b5146b..696c22890 100644 --- a/src/main/protobuf/kotlin_model.proto +++ b/src/main/protobuf/kotlin_model.proto @@ -158,6 +158,8 @@ message JvmCompilationTask { repeated string javac_flags = 15; // JDeps dependency artifacts repeated string deps_artifacts = 16; + // Kotlin symbol processor options + repeated string ksp_options = 17; } CompilationTaskInfo info = 1;