diff options
Diffstat (limited to 'kotlin/common.bzl')
-rw-r--r-- | kotlin/common.bzl | 571 |
1 files changed, 272 insertions, 299 deletions
diff --git a/kotlin/common.bzl b/kotlin/common.bzl index 3789b0c..76bb57b 100644 --- a/kotlin/common.bzl +++ b/kotlin/common.bzl @@ -14,42 +14,22 @@ """Common Kotlin definitions.""" +# go/keep-sorted start +load("//kotlin/jvm/internal_do_not_use/util:file_factory.bzl", "FileFactory") +load("//kotlin/jvm/internal_do_not_use/util:run_deploy_jar.bzl", "kt_run_deploy_jar") +load("//kotlin/jvm/internal_do_not_use/util:srcjars.bzl", "kt_srcjars") +load("//toolchains/kotlin_jvm:androidlint_toolchains.bzl", "androidlint_toolchains") +load("//:visibility.bzl", "RULES_DEFS_THAT_COMPILE_KOTLIN") load("@bazel_skylib//lib:sets.bzl", "sets") +load("//bazel:stubs.bzl", "lint_actions") load("//bazel:stubs.bzl", "BASE_JVMOPTS") load("//bazel:stubs.bzl", "DEFAULT_BUILTIN_PROCESSORS") -load(":file_factory.bzl", "FileFactory") +# go/keep-sorted end # TODO: Remove the _ALLOWED_*_RULES lists to determine which rules # are accepted dependencies to Kotlin rules as the approach does not scale # because it will require a cl + release for every new rule. -_ALLOWED_ANDROID_RULES = [ - "aar_import", - "android_library", - "kt_android_library_helper", -] - -_ALLOWED_JVM_RULES = [ - "_java_grpc_library", - "_java_lite_grpc_library", - "af_internal_guice_module", # b/142743220 - "af_internal_jbcsrc_library", # added with b/143872075 - "af_internal_soyinfo_generator", # b/143872075 - "java_import", - "java_library", - "java_lite_proto_library", - "java_mutable_proto_library", - "java_proto_library", - "java_wrap_cc", # b/152799927 - "jvm_import", - "_kmp_library", - "kt_grpc_library_helper", - "kt_jvm_library_helper", - "kt_jvm_import", - "kt_proto_library_helper", - "_j2kt_jvm_library_rule", # b/233055549 -] - _EXT = struct( KT = ".kt", JAVA = ".java", @@ -78,6 +58,9 @@ _RULE_FAMILY = struct( def _is_dir(file, basename): return file.is_directory and file.basename == basename +def _is_file(file, extension): + return (not file.is_directory) and file.path.endswith(extension) + def _is_kt_src(src): """Decides if `src` Kotlin code. @@ -86,7 +69,7 @@ def _is_kt_src(src): - a tree-artifact expected to contain only Kotlin source files """ - return src.path.endswith(_EXT.KT) or _is_dir(src, "kotlin") + return _is_file(src, _EXT.KT) or _is_dir(src, "kotlin") # Compute module name based on target (b/139403883), similar to Swift def _derive_module_name(ctx): @@ -142,11 +125,11 @@ def _kapt( # Create a srcjar for the .java stubs generated by kapt, # mostly to filter out non-.java stub outputs, e.g. .kapt_metadata. - stub_srcjars.append(_create_jar( + stub_srcjars.append(kt_srcjars.zip( ctx, toolchain, file_factory.declare_file("stubs-srcjar.jar"), - kt_inputs = [stubs_dir], + srcs = [stubs_dir], ignore_not_allowed_files = True, )) @@ -319,7 +302,7 @@ def _run_turbine( java_runtime = toolchain.turbine_java_runtime if not java_runtime: java_runtime = toolchain.java_runtime - _actions_run_deploy_jar( + kt_run_deploy_jar( ctx = ctx, java_runtime = java_runtime, deploy_jar = toolchain.turbine, @@ -331,53 +314,24 @@ def _run_turbine( progress_message = progress_message, ) -def _derive_gen_class_jar( - ctx, - toolchain, - manifest_proto, - javac_jar, - java_srcs = []): - """Returns the annotation processor-generated classes contained in given Jar.""" - if not manifest_proto: - return None - if not javac_jar: - fail("There must be a javac Jar if there was annotation processing") - if not java_srcs: - # If there weren't any hand-written .java srcs, just use Javac's output - return javac_jar - - # Run GenClass tool to derive gen_class_jar by filtering hand-written sources. - # cf. Bazel's JavaCompilationHelper#createGenJarAction - result = FileFactory(ctx, javac_jar).declare_file("-gen.jar") - - genclass_args = ctx.actions.args() - genclass_args.add("--manifest_proto", manifest_proto) - genclass_args.add("--class_jar", javac_jar) - genclass_args.add("--output_jar", result) - - _actions_run_deploy_jar( - ctx = ctx, - java_runtime = toolchain.java_runtime, - deploy_jar = toolchain.genclass, - inputs = [manifest_proto, javac_jar], - outputs = [result], - args = [genclass_args], - mnemonic = "KtGenClassJar", - progress_message = "Deriving %{output}", - ) - - return result - def _kt_plugins_map( + android_lint_singlejar_plugins = depset(), + android_lint_libjar_plugin_infos = [], java_plugin_infos = [], kt_compiler_plugin_infos = []): """A struct containing all the plugin types understood by rules_kotlin. Args: - java_plugin_infos: (list[JavaPluginInfo]) - kt_compiler_plugin_infos: (list[KtCompilerPluginInfo]) + android_lint_singlejar_plugins: (depset[File]) Android Lint checkers. + Each JAR is self-contained and should be loaded in an isolated classloader. + android_lint_libjar_plugin_infos: (list[JavaInfo]) Android Lint checkers. + All infos share transitive dependencies and should be loaded in a combined classloader. + java_plugin_infos: (list[JavaPluginInfo]) + kt_compiler_plugin_infos: (list[KtCompilerPluginInfo]) """ return struct( + android_lint_singlejar_plugins = android_lint_singlejar_plugins, + android_lint_libjar_plugin_infos = android_lint_libjar_plugin_infos, java_plugin_infos = java_plugin_infos, kt_compiler_plugin_infos = kt_compiler_plugin_infos, ) @@ -387,7 +341,6 @@ def _run_kotlinc( file_factory, kt_srcs = [], common_srcs = [], - coverage_srcs = [], java_srcs_and_dirs = [], kotlincopts = [], compile_jdeps = depset(), @@ -397,7 +350,9 @@ def _run_kotlinc( plugins = _kt_plugins_map(), friend_jars = depset(), enforce_strict_deps = False, - enforce_complete_jdeps = False): + enforce_complete_jdeps = False, + mnemonic = None, + message_prefix = ""): direct_inputs = [] transitive_inputs = [] outputs = [] @@ -435,7 +390,7 @@ def _run_kotlinc( output = file_factory.declare_file(".jar") kotlinc_args.add("-d", output) - outputs.append(output) + outputs.insert(0, output) # The param file name is derived from the 0th output kotlinc_args.add_all(kt_srcs) direct_inputs.extend(kt_srcs) kotlinc_args.add_all(common_srcs) @@ -459,36 +414,126 @@ def _run_kotlinc( arguments = [kotlinc_args], inputs = depset(direct = direct_inputs, transitive = transitive_inputs), outputs = outputs, - mnemonic = "Kt2JavaCompile", - progress_message = "Compiling Kotlin For Java Runtime: %s" % _get_original_kt_target_label(ctx), + mnemonic = mnemonic, + progress_message = message_prefix + str(_get_original_kt_target_label(ctx)), execution_requirements = { "worker-key-mnemonic": "Kt2JavaCompile", }, ) - srcjar = _create_jar( + return struct( + output_jar = output, + compile_jar = kt_ijar, + ) + +def _kt_compile( + ctx, + file_factory, + kt_srcs = [], + common_srcs = [], + coverage_srcs = [], + java_srcs_and_dirs = [], + kt_hdrs = None, + common_hdrs = None, + kotlincopts = [], + compile_jdeps = depset(), + toolchain = None, + classpath = [], + directdep_jars = depset(), + plugins = _kt_plugins_map(), + friend_jars = depset(), + enforce_strict_deps = False, + enforce_complete_jdeps = False): + # TODO: don't run jvm-abi-gen plugin here if we have headers + kotlinc_full_result = _run_kotlinc( + ctx, + kt_srcs = kt_srcs, + common_srcs = common_srcs, + java_srcs_and_dirs = java_srcs_and_dirs, + file_factory = file_factory, + kotlincopts = kotlincopts, + compile_jdeps = compile_jdeps, + toolchain = toolchain, + classpath = classpath, + directdep_jars = directdep_jars, + plugins = plugins, + friend_jars = friend_jars, + enforce_strict_deps = enforce_strict_deps, + enforce_complete_jdeps = enforce_complete_jdeps, + mnemonic = "Kt2JavaCompile", + message_prefix = "Compiling for Java runtime: ", + ) + + srcjar = kt_srcjars.zip( ctx, toolchain, file_factory.declare_file("-kt-src.jar"), - kt_inputs = kt_srcs, - common_inputs = common_srcs, + srcs = kt_srcs, + common_srcs = common_srcs, ) + output_jar = kotlinc_full_result.output_jar if ctx.coverage_instrumented(): - output = _offline_instrument_jar( + output_jar = _offline_instrument_jar( ctx, toolchain, - output, + output_jar, kt_srcs + common_srcs + coverage_srcs, ) + # Use un-instrumented Jar at compile-time to avoid double-instrumenting inline functions + # (see b/110763361 for the comparable Gradle issue) + compile_jar = kotlinc_full_result.compile_jar + if toolchain.header_gen_tool: + kotlinc_header_result = _run_kotlinc( + ctx, + kt_srcs = kt_hdrs, + common_srcs = common_hdrs, + java_srcs_and_dirs = java_srcs_and_dirs, + file_factory = file_factory.derive("-abi"), + kotlincopts = kotlincopts, + compile_jdeps = compile_jdeps, + toolchain = toolchain, + classpath = classpath, + directdep_jars = directdep_jars, + plugins = plugins, + friend_jars = friend_jars, + enforce_strict_deps = enforce_strict_deps, + enforce_complete_jdeps = enforce_complete_jdeps, + mnemonic = "Kt2JavaHeaderCompile", + message_prefix = "Computing Kotlin ABI interface Jar: ", + ) + compile_jar = kotlinc_header_result.compile_jar + result = dict( - output_jar = output, - compile_jar = kt_ijar, + output_jar = output_jar, + compile_jar = compile_jar, source_jar = srcjar, ) return struct(java_info = JavaInfo(**result), **result) +def _derive_headers( + ctx, + toolchain, + file_factory, + srcs): + if not srcs or not toolchain.header_gen_tool: + return srcs + + output_dir = file_factory.declare_directory("-headers") + args = ctx.actions.args() + args.add(output_dir.path, format = "-output_dir=%s") + args.add_joined(srcs, format_joined = "-sources=%s", join_with = ",") + ctx.actions.run( + executable = toolchain.header_gen_tool, + arguments = [args], + inputs = srcs, + outputs = [output_dir], + mnemonic = "KtDeriveHeaders", + progress_message = "Deriving %s: %s" % (output_dir.basename, _get_original_kt_target_label(ctx)), + ) + return [output_dir] + def _get_original_kt_target_label(ctx): label = ctx.label if label.name.find("_DO_NOT_DEPEND") > 0: @@ -534,7 +579,7 @@ def _run_import_deps_checker( ) def _offline_instrument_jar(ctx, toolchain, jar, srcs = []): - if not jar.basename.endswith(".jar"): + if not _is_file(jar, _EXT.JAR): fail("Expect JAR input but got %s" % jar) file_factory = FileFactory(ctx, jar) @@ -613,174 +658,6 @@ def _merge_jdeps(ctx, kt_jvm_toolchain, jdeps_files, file_factory): return merged_jdeps_file -def _expand_zip(ctx, toolchain, dir, input): - args = ctx.actions.args() - args.add("unzip", input) - args.add(dir.path) - - _actions_run_deploy_jar( - ctx = ctx, - java_runtime = toolchain.java_runtime, - deploy_jar = toolchain.source_jar_zipper, - inputs = [input], - outputs = [dir], - args = [args], - mnemonic = "SrcJarUnzip", - ) - - return dir - -def _create_jar(ctx, toolchain, out_jar, kt_inputs = [], common_inputs = [], ignore_not_allowed_files = False): - args = ctx.actions.args() - args.add("zip") - args.add(out_jar) - args.add_joined("--kotlin_srcs", kt_inputs, join_with = ",") - args.add_joined("--common_srcs", common_inputs, join_with = ",") - if ignore_not_allowed_files: - args.add("-i") - - _actions_run_deploy_jar( - ctx = ctx, - java_runtime = toolchain.java_runtime, - deploy_jar = toolchain.source_jar_zipper, - inputs = kt_inputs + common_inputs, - outputs = [out_jar], - args = [args], - mnemonic = "KtJar", - progress_message = "Create Jar (kotlin/common.bzl): %{output}", - ) - - return out_jar - -def _create_jar_from_tree_artifacts(ctx, toolchain, output_jar, input_dirs): - """Packs a sequence of tree artifacts into a single jar. - - Given the following file directory structure, - /usr/home/a/x/1.txt - /usr/home/b/y/1.txt - with an input_dirs as [ - "/usr/home/a", - "/usr/home/b", - ], - The tool produces a jar with in-archive structure of, - x/1.txt - y/1.txt - - The function fails on the duplicate jar entry case. e.g. if we pass an - input_dirs as [ - "/usr/home/a/x", - "/usr/home/b/y", - ], - then the blaze action would fail with an error message. - "java.lang.IllegalStateException: 1.txt has the same path as 1.txt! - If it is intended behavior rename one or both of them." - - Args: - ctx: The build rule context. - toolchain: Toolchain containing the jar tool. - output_jar: The jar to be produced by this action. - input_dirs: A sequence of tree artifacts to be zipped. - - Returns: - The generated output jar, i.e. output_jar - """ - - args = ctx.actions.args() - args.add("zip_resources") - args.add(output_jar) - args.add_joined( - "--input_dirs", - input_dirs, - join_with = ",", - omit_if_empty = False, - expand_directories = False, - ) - - _actions_run_deploy_jar( - ctx = ctx, - java_runtime = toolchain.java_runtime, - deploy_jar = toolchain.source_jar_zipper, - inputs = input_dirs, - outputs = [output_jar], - args = [args], - mnemonic = "KtJarActionFromTreeArtifacts", - progress_message = "Create Jar %{output}", - ) - - return output_jar - -def _DirSrcjarSyncer(ctx, kt_toolchain, file_factory): - _dirs = [] - _srcjars = [] - - def add_dirs(dirs): - if not dirs: - return - - _dirs.extend(dirs) - _srcjars.append( - _create_jar_from_tree_artifacts( - ctx, - kt_toolchain, - file_factory.declare_file("%s.srcjar" % len(_srcjars)), - dirs, - ), - ) - - def add_srcjars(srcjars): - if not srcjars: - return - - for srcjar in srcjars: - _dirs.append( - _expand_zip( - ctx, - kt_toolchain, - file_factory.declare_directory("%s.expand" % len(_dirs)), - srcjar, - ), - ) - _srcjars.extend(srcjars) - - return struct( - add_dirs = add_dirs, - add_srcjars = add_srcjars, - dirs = _dirs, - srcjars = _srcjars, - ) - -def _actions_run_deploy_jar( - ctx, - java_runtime, - deploy_jar, - inputs, - args = [], - deploy_jsa = None, - **kwargs): - java_args = ctx.actions.args() - java_inputs = [] - if deploy_jsa: - java_args.add("-Xshare:auto") - java_args.add(deploy_jsa, format = "-XX:SharedArchiveFile=%s") - java_args.add("-XX:-VerifySharedSpaces") - java_args.add("-XX:-ValidateSharedClassPaths") - java_inputs.append(deploy_jsa) - java_args.add("-jar", deploy_jar) - java_inputs.append(deploy_jar) - - java_depset = depset(direct = java_inputs, transitive = [java_runtime[DefaultInfo].files]) - if type(inputs) == "depset": - all_inputs = depset(transitive = [java_depset, inputs]) - else: - all_inputs = depset(direct = inputs, transitive = [java_depset]) - - ctx.actions.run( - executable = str(java_runtime[java_common.JavaRuntimeInfo].java_executable_exec_path), - inputs = all_inputs, - arguments = BASE_JVMOPTS + [java_args] + args, - **kwargs - ) - def _check_srcs_package(target_package, srcs, attr_name): """Makes sure the given srcs live in the given package.""" @@ -790,6 +667,27 @@ def _check_srcs_package(target_package, srcs, attr_name): fail(("Please do not depend on %s directly in %s. Either move it to this package or " + "depend on an appropriate rule in its package.") % (src.owner, attr_name)) +def _split_srcs_by_language(srcs, common_srcs, java_syncer): + srcs_set = sets.make(srcs) + common_srcs_set = sets.make(common_srcs) + + overlapping_srcs_set = sets.intersection(srcs_set, common_srcs_set) + if sets.length(overlapping_srcs_set) != 0: + fail("Overlap between srcs and common_srcs: %s" % sets.to_list(overlapping_srcs_set)) + + # Split sources, as java requires a separate compile step. + kt_srcs = [s for s in srcs if _is_kt_src(s)] + java_srcs = [s for s in srcs if _is_file(s, _EXT.JAVA)] + java_syncer.add_dirs([s for s in srcs if _is_dir(s, "java")]) + java_syncer.add_srcjars([s for s in srcs if _is_file(s, _EXT.SRCJAR)]) + + expected_srcs_set = sets.make(kt_srcs + java_srcs + java_syncer.dirs + java_syncer.srcjars) + unexpected_srcs_set = sets.difference(srcs_set, expected_srcs_set) + if sets.length(unexpected_srcs_set) != 0: + fail("Unexpected srcs: %s" % sets.to_list(unexpected_srcs_set)) + + return (kt_srcs, java_srcs) + # TODO: Streamline API to generate less actions. def _kt_jvm_library( ctx, @@ -804,15 +702,11 @@ def _kt_jvm_library( output = None, output_srcjar = None, # Will derive default filename if not set. deps = [], - codegen_output_java_infos = [], # JavaInfo sequence from kt_codegen_plugin. exports = [], # passthrough for JavaInfo constructor runtime_deps = [], # passthrough for JavaInfo constructor native_libraries = [], # passthrough of CcInfo for JavaInfo constructor plugins = _kt_plugins_map(), - pre_processed_java_plugin_processors = sets.make([]), exported_plugins = [], - android_lint_plugins = [], - android_lint_rules_jars = depset(), # Depset with standalone Android Lint rules Jars javacopts = [], kotlincopts = [], compile_jdeps = depset(), @@ -832,26 +726,25 @@ def _kt_jvm_library( fail("Missing or invalid kt_toolchain") file_factory = FileFactory(ctx, output) - deps = list(deps) # Defensive copy + static_deps = list(deps) # Defensive copy - # Split sources, as java requires a separate compile step. - kt_srcs = [s for s in srcs if _is_kt_src(s)] - java_srcs = [s for s in srcs if s.path.endswith(_EXT.JAVA)] - java_syncer = _DirSrcjarSyncer(ctx, kt_toolchain, file_factory) - java_syncer.add_dirs([s for s in srcs if _is_dir(s, "java")]) - java_syncer.add_srcjars([s for s in srcs if s.path.endswith(_EXT.SRCJAR)]) + kt_codegen_processing_env = dict( + pre_processed_processors = depset(), + codegen_output_java_infos = [], + ) + + pre_processed_processors = kt_codegen_processing_env["pre_processed_processors"] + generative_deps = kt_codegen_processing_env["codegen_output_java_infos"] - expected_srcs = sets.make(kt_srcs + java_srcs + java_syncer.dirs + java_syncer.srcjars) - unexpected_srcs = sets.difference(sets.make(srcs), expected_srcs) - if sets.length(unexpected_srcs) != 0: - fail("Unexpected srcs: %s" % sets.to_list(unexpected_srcs)) + java_syncer = kt_srcjars.DirSrcjarSyncer(ctx, kt_toolchain, file_factory) + kt_srcs, java_srcs = _split_srcs_by_language(srcs, common_srcs, java_syncer) # TODO: Remove this special case if kt_srcs and ("flogger" in [p.plugin_id for p in plugins.kt_compiler_plugin_infos]): - deps.append(kt_toolchain.flogger_runtime) + static_deps.append(kt_toolchain.flogger_runtime) - if srcs or common_srcs or rule_family != _RULE_FAMILY.ANDROID_LIBRARY: - deps.extend(kt_toolchain.kotlin_libs) + if kt_srcs or common_srcs or rule_family != _RULE_FAMILY.ANDROID_LIBRARY: + static_deps.extend(kt_toolchain.kotlin_libs) # Skip srcs package check for android_library targets with no kotlin sources: b/239725424 if rule_family != _RULE_FAMILY.ANDROID_LIBRARY or kt_srcs: @@ -859,17 +752,19 @@ def _kt_jvm_library( _check_srcs_package(ctx.label.package, common_srcs, "common_srcs") _check_srcs_package(ctx.label.package, coverage_srcs, "coverage_srcs") - full_classpath = _create_classpath(java_toolchain, deps + codegen_output_java_infos) + # Includes generative deps from codegen. + extended_deps = static_deps + generative_deps + full_classpath = _create_classpath(java_toolchain, extended_deps) # Collect all plugin data, including processors to run and all plugin classpaths, # whether they have processors or not (b/120995492). # This may include go/errorprone plugin classpaths that kapt will ignore. - java_plugin_datas = [info.plugins for info in plugins.java_plugin_infos] + [dep.plugins for dep in deps] + java_plugin_datas = [info.plugins for info in plugins.java_plugin_infos] + [dep.plugins for dep in static_deps] plugin_processors = [ cls for p in java_plugin_datas for cls in p.processor_classes.to_list() - if not sets.contains(pre_processed_java_plugin_processors, cls) + if cls not in pre_processed_processors.to_list() ] plugin_classpaths = depset(transitive = [p.processor_jars for p in java_plugin_datas]) @@ -877,6 +772,20 @@ def _kt_jvm_library( out_srcjars = [] out_compilejars = [] + kt_hdrs = _derive_headers( + ctx, + toolchain = kt_toolchain, + file_factory = file_factory.derive("-kt"), + # TODO: prohibit overlap of srcs and common_srcs + srcs = kt_srcs, + ) + common_hdrs = _derive_headers( + ctx, + toolchain = kt_toolchain, + file_factory = file_factory.derive("-common"), + srcs = common_srcs, + ) + # Kotlin compilation requires two passes when annotation processing is # required. The initial pass processes the annotations and generates # additional sources and the following pass compiles the Kotlin code. @@ -887,8 +796,8 @@ def _kt_jvm_library( kapt_outputs = _kapt( ctx, file_factory = file_factory, - kt_srcs = kt_srcs, - common_srcs = common_srcs, + kt_srcs = kt_hdrs, + common_srcs = common_hdrs, java_srcs = java_srcs, plugin_processors = plugin_processors, plugin_classpaths = plugin_classpaths, @@ -908,12 +817,14 @@ def _kt_jvm_library( kotlinc_result = None if kt_srcs or common_srcs: - kotlinc_result = _run_kotlinc( + kotlinc_result = _kt_compile( ctx, kt_srcs = kt_srcs, common_srcs = common_srcs, coverage_srcs = coverage_srcs, java_srcs_and_dirs = java_srcs + java_syncer.dirs, + kt_hdrs = kt_hdrs, + common_hdrs = common_hdrs, file_factory = file_factory.derive("-kt"), kotlincopts = kotlincopts, compile_jdeps = compile_jdeps, @@ -924,9 +835,6 @@ def _kt_jvm_library( enforce_strict_deps = enforce_strict_deps, enforce_complete_jdeps = enforce_complete_jdeps, ) - - # Use un-instrumented Jar at compile-time to avoid double-instrumenting inline functions - # (see b/110763361 for the comparable Gradle issue) out_compilejars.append(kotlinc_result.compile_jar) out_srcjars.append(kotlinc_result.source_jar) out_jars.append(kotlinc_result.output_jar) @@ -937,7 +845,7 @@ def _kt_jvm_library( ) if classpath_resources_dirs: out_jars.append( - _create_jar_from_tree_artifacts( + kt_srcjars.zip_resources( ctx, kt_toolchain, file_factory.declare_file("-dir-res.jar"), @@ -947,11 +855,10 @@ def _kt_jvm_library( javac_java_info = None java_native_headers_jar = None - java_gensrcjar = None - java_genjar = None is_android_library_without_kt_srcs = rule_family == _RULE_FAMILY.ANDROID_LIBRARY and not kt_srcs + if java_srcs or java_syncer.srcjars or classpath_resources: - javac_deps = deps + codegen_output_java_infos # Defensive copy + javac_deps = extended_deps # Defensive copy if kapt_outputs.java_info: javac_deps.append(kapt_outputs.java_info) if kotlinc_result: @@ -963,6 +870,12 @@ def _kt_jvm_library( javac_deps.append(kt_toolchain.coverage_runtime) javac_out = output if is_android_library_without_kt_srcs else file_factory.declare_file("-java.jar") + + annotation_plugins = list(plugins.java_plugin_infos) + + # Enable annotation processing for java-only sources to enable data binding + enable_annotation_processing = not kt_srcs + javac_java_info = java_common.compile( ctx, source_files = java_srcs, @@ -978,17 +891,16 @@ def _kt_jvm_library( # all sources of default flags (for Ellipsis builds, see b/125452475). # TODO: remove default_javac_flags here once java_common.compile is fixed. javac_opts = ctx.fragments.java.default_javac_flags + javacopts, - plugins = plugins.java_plugin_infos, + plugins = annotation_plugins, strict_deps = "DEFAULT", java_toolchain = java_toolchain, neverlink = neverlink, - # Enable annotation processing for java-only sources to enable data binding - enable_annotation_processing = not kt_srcs, + enable_annotation_processing = enable_annotation_processing, annotation_processor_additional_outputs = annotation_processor_additional_outputs, annotation_processor_additional_inputs = annotation_processor_additional_inputs, ) - # Directly return the JavaInfo from java.compile() for java-only andorid_library targets + # Directly return the JavaInfo from java.compile() for java-only android_library targets # to avoid creating a new JavaInfo. See b/239847857 for additional context. if is_android_library_without_kt_srcs: return struct( @@ -1001,14 +913,25 @@ def _kt_jvm_library( out_compilejars.extend(javac_java_info.compile_jars.to_list()) # unpack singleton depset java_native_headers_jar = javac_java_info.outputs.native_headers - if kt_srcs: - java_gensrcjar = kapt_outputs.srcjar - java_genjar = _derive_gen_class_jar(ctx, kt_toolchain, kapt_outputs.manifest, javac_out, java_srcs) - else: - java_gensrcjar = javac_java_info.annotation_processing.source_jar - java_genjar = javac_java_info.annotation_processing.class_jar - if java_gensrcjar: - java_syncer.add_srcjars([java_gensrcjar]) + java_gensrcjar = None + java_genjar = None + if pre_processed_processors: + java_gen_srcjars = kt_codegen_processing_env["java_gen_srcjar"] + kt_gen_srcjars = kt_codegen_processing_env["kt_gen_srcjar"] + java_gensrcjar = file_factory.declare_file("-java_info_generated_source_jar.srcjar") + _singlejar( + ctx, + inputs = java_gen_srcjars + kt_gen_srcjars, + output = java_gensrcjar, + singlejar = java_toolchain.single_jar, + mnemonic = "JavaInfoGeneratedSourceJar", + ) + + elif javac_java_info: + java_gensrcjar = javac_java_info.annotation_processing.source_jar + java_genjar = javac_java_info.annotation_processing.class_jar + if java_gensrcjar: + java_syncer.add_srcjars([java_gensrcjar]) jdeps_output = None compile_jdeps_output = None @@ -1017,6 +940,54 @@ def _kt_jvm_library( # TODO: Move severity overrides to config file when possible again blocking_action_outs = [] + # TODO: Remove the is_android_library_without_kt_srcs condition once KtAndroidLint + # uses the same lint checks with AndroidLint + + if not is_android_library_without_kt_srcs: + lint_flags = [ + "--java-language-level", # b/159950410 + kt_toolchain.java_language_version, + "--kotlin-language-level", + kt_toolchain.kotlin_language_version, + "--nowarn", # Check for "errors", which includes custom checks that report errors. + "--XallowBaselineSuppress", # allow baseline exemptions of otherwise unsuppressable errors + "--exitcode", # fail on error + "--fullpath", # reduce file path clutter in reported issues + "--text", + "stdout", # also log to stdout + ] + if disable_lint_checks and disable_lint_checks != [""]: + lint_flags.append("--disable") + lint_flags.append(",".join(disable_lint_checks)) + + android_lint_out = lint_actions.run_lint_on_library( + ctx, + runner = kt_toolchain.android_lint_runner, + output = file_factory.declare_file("_android_lint_output.xml"), + srcs = kt_srcs + java_srcs + common_srcs, + source_jars = java_syncer.srcjars, + classpath = full_classpath, + manifest = manifest, + merged_manifest = merged_manifest, + resource_files = resource_files, + baseline_file = androidlint_toolchains.get_baseline(ctx), + config = kt_toolchain.android_lint_config, + android_lint_plugins_depset = depset( + order = "preorder", + transitive = [plugin_classpaths] + [ + dep.transitive_runtime_jars + for dep in plugins.android_lint_libjar_plugin_infos + ], + ), + android_lint_rules = plugins.android_lint_singlejar_plugins, + lint_flags = lint_flags, + extra_input_depsets = [p.processor_data for p in java_plugin_datas] + [depset([java_genjar] if java_genjar else [])], + testonly = testonly, + android_java8_libs = kt_toolchain.android_java8_apis_desugared, + mnemonic = "KtAndroidLint", # so LSA extractor can distinguish Kotlin (b/189442586) + ) + blocking_action_outs.append(android_lint_out) + if output_srcjar == None: output_srcjar = file_factory.declare_file("-src.jar") compile_jar = file_factory.declare_file("-compile.jar") @@ -1045,7 +1016,7 @@ def _kt_jvm_library( output_jar = output, compile_jar = compile_jar, source_jar = output_srcjar, - deps = deps, + deps = static_deps, exports = exports, exported_plugins = exported_plugins, runtime_deps = runtime_deps, @@ -1079,6 +1050,10 @@ def _kt_jvm_import( if not jars: fail("Must import at least one JAR") + _check_srcs_package(ctx.label.package, jars, "jars") + if srcjar: + _check_srcs_package(ctx.label.package, [srcjar], "srcjar") + file_factory = FileFactory(ctx, jars[0]) deps = java_common.merge(deps + kt_toolchain.kotlin_libs) @@ -1186,8 +1161,6 @@ def _partition(sequence, filter): return pos, neg common = struct( - ALLOWED_ANDROID_RULES = _ALLOWED_ANDROID_RULES, - ALLOWED_JVM_RULES = _ALLOWED_JVM_RULES, JAR_FILE_TYPE = _JAR_FILE_TYPE, JVM_FLAGS = BASE_JVMOPTS, KT_FILE_TYPES = _KT_FILE_TYPES, @@ -1196,7 +1169,7 @@ common = struct( SRCJAR_FILE_TYPES = _SRCJAR_FILE_TYPES, collect_proguard_specs = _collect_proguard_specs, collect_providers = _collect_providers, - create_jar_from_tree_artifacts = _create_jar_from_tree_artifacts, + create_jar_from_tree_artifacts = kt_srcjars.zip_resources, common_kapt_and_kotlinc_args = _common_kapt_and_kotlinc_args, is_kt_src = _is_kt_src, kt_jvm_import = _kt_jvm_import, |