diff options
Diffstat (limited to 'kotlin/jvm/internal_do_not_use/util')
-rw-r--r-- | kotlin/jvm/internal_do_not_use/util/BUILD | 28 | ||||
-rw-r--r-- | kotlin/jvm/internal_do_not_use/util/class_file_selectors.bzl | 57 | ||||
-rw-r--r-- | kotlin/jvm/internal_do_not_use/util/file_factory.bzl | 59 | ||||
-rw-r--r-- | kotlin/jvm/internal_do_not_use/util/run_deploy_jar.bzl | 54 | ||||
-rw-r--r-- | kotlin/jvm/internal_do_not_use/util/srcjars.bzl | 183 |
5 files changed, 381 insertions, 0 deletions
diff --git a/kotlin/jvm/internal_do_not_use/util/BUILD b/kotlin/jvm/internal_do_not_use/util/BUILD new file mode 100644 index 0000000..bcfec8d --- /dev/null +++ b/kotlin/jvm/internal_do_not_use/util/BUILD @@ -0,0 +1,28 @@ +# Copyright 2022 Google LLC. 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 = ["//:internal"]) + +licenses(["notice"]) + +bzl_library( + name = "util_bzl", + srcs = glob(["*.bzl"]), + deps = [ + "//:visibility_bzl", + "@bazel_tools//tools/jdk:jvmopts", + ], +) diff --git a/kotlin/jvm/internal_do_not_use/util/class_file_selectors.bzl b/kotlin/jvm/internal_do_not_use/util/class_file_selectors.bzl new file mode 100644 index 0000000..d5341c8 --- /dev/null +++ b/kotlin/jvm/internal_do_not_use/util/class_file_selectors.bzl @@ -0,0 +1,57 @@ +# Copyright 2022 Google LLC. 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. + +"""Selects bytecode class files with a matched source file in srcjars.""" + +load("//:visibility.bzl", "RULES_KOTLIN") + +def gen_java_info_generated_class_jar(ctx, file_factory, kt_toolchain, input_jars, srcjars): + """Generates a class jar with class file jar entries matching files in the give srcjars. + + Args: + ctx: A rule context. + file_factory: A file factory in responsible for file creation under the current context. + kt_toolchain: The toolchain for kotlin builds. + input_jars: A sequence of jar files from which class files are selected. + srcjars: A sequence of source jar files that the selection references to. + Returns: + The output jar file, i.e. output_jar. + """ + output_jar = file_factory.declare_file("-java_info_generated_class_jar.jar") + input_jars = depset(input_jars) + transformer_env_files = depset(srcjars) + + transformer_entry_point = "com.google.devtools.jar.transformation.ClassFileSelectorBySourceFile" + transformer_jars = kt_toolchain.class_file_selector_by_source_file[JavaInfo].transitive_runtime_jars + jar_transformer = kt_toolchain.jar_transformer[DefaultInfo].files_to_run + + args = ctx.actions.args() + args.add_joined("--input_jars", input_jars, join_with = ",") + args.add_joined("--transformer_jars", transformer_jars, join_with = ",") + args.add("--transformer_entry_point", transformer_entry_point) + args.add_joined("--transformer_env_files", transformer_env_files, join_with = ",") + args.add("--result", output_jar) + ctx.actions.run( + inputs = depset(transitive = [ + input_jars, + transformer_jars, + transformer_env_files, + ]), + outputs = [output_jar], + arguments = [args], + progress_message = "Generating JavaInfo.generated_class_jar into %{output}", + mnemonic = "ClassFileSelectorBySourceFile", + executable = jar_transformer, + ) + return output_jar diff --git a/kotlin/jvm/internal_do_not_use/util/file_factory.bzl b/kotlin/jvm/internal_do_not_use/util/file_factory.bzl new file mode 100644 index 0000000..2e076c3 --- /dev/null +++ b/kotlin/jvm/internal_do_not_use/util/file_factory.bzl @@ -0,0 +1,59 @@ +# Copyright 2022 Google LLC. 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. + +"""FileFactory""" + +load("//:visibility.bzl", "RULES_KOTLIN") + +def FileFactory(ctx, base): + """Creates files with names derived from some base file or prefix + + Including the name of a rule is not always enough to guarantee unique filenames. For example, + helper functions that declare their own output files may be called multiple times in the same + rule impl. + + Args: + ctx: ctx + base: [File|string] The file to derive other filenames from, or an exact base prefix + + Returns: + FileFactory + """ + + if type(base) == "File": + base = _scrub_base_file(ctx, base) + + def declare_directory(suffix): + return ctx.actions.declare_directory(base + suffix) + + def declare_file(suffix): + return ctx.actions.declare_file(base + suffix) + + def derive(suffix): + return FileFactory(ctx, base + suffix) + + return struct( + base_as_path = ctx.bin_dir.path + "/" + ctx.label.package + "/" + base, + declare_directory = declare_directory, + declare_file = declare_file, + derive = derive, + ) + +def _scrub_base_file(ctx, file): + if not file.extension: + fail("Base file must have an extension: was %s" % (file.path)) + if file.owner.package != ctx.label.package: + fail("Base file must be from ctx package: was %s expected %s" % (file.owner.package, ctx.label.package)) + + return file.short_path.removeprefix(ctx.label.package + "/").rsplit(".", 1)[0] diff --git a/kotlin/jvm/internal_do_not_use/util/run_deploy_jar.bzl b/kotlin/jvm/internal_do_not_use/util/run_deploy_jar.bzl new file mode 100644 index 0000000..14c784b --- /dev/null +++ b/kotlin/jvm/internal_do_not_use/util/run_deploy_jar.bzl @@ -0,0 +1,54 @@ +# Copyright 2022 Google LLC. 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. + +"""kt_run_deploy_jar""" + +# go/keep-sorted start +load("//:visibility.bzl", "RULES_KOTLIN") +load("//bazel:stubs.bzl", "BASE_JVMOPTS") +# go/keep-sorted end + +def kt_run_deploy_jar( + ctx, + java_runtime, + deploy_jar, + inputs, + args = [], + deploy_jsa = None, + **kwargs): + """An analogue to ctx.actions.run for _deploy.jar executables.""" + + 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 + ) diff --git a/kotlin/jvm/internal_do_not_use/util/srcjars.bzl b/kotlin/jvm/internal_do_not_use/util/srcjars.bzl new file mode 100644 index 0000000..becf573 --- /dev/null +++ b/kotlin/jvm/internal_do_not_use/util/srcjars.bzl @@ -0,0 +1,183 @@ +# Copyright 2022 Google LLC. 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. + +"""kt_srcjars""" + +# go/keep-sorted start +load("//:visibility.bzl", "RULES_KOTLIN") +load(":run_deploy_jar.bzl", "kt_run_deploy_jar") +# go/keep-sorted end + +def _zip( + ctx, + kt_jvm_toolchain, + out_jar, + srcs = [], + common_srcs = [], + ignore_not_allowed_files = False): + """Creates a srcjar from a set of Kotlin and Java srcs + + Paths inside the srcjar are derived from the package name in the source file. + """ + + args = ctx.actions.args() + args.add("zip") + args.add(out_jar) + args.add_joined("--kotlin_srcs", srcs, join_with = ",") + args.add_joined("--common_srcs", common_srcs, join_with = ",") + if ignore_not_allowed_files: + args.add("-i") + + kt_run_deploy_jar( + ctx = ctx, + java_runtime = kt_jvm_toolchain.java_runtime, + deploy_jar = kt_jvm_toolchain.source_jar_zipper, + inputs = srcs + common_srcs, + outputs = [out_jar], + args = [args], + mnemonic = "KtJar", + progress_message = "Create Jar (kotlin/common.bzl): %{output}", + ) + + return out_jar + +def _unzip( + ctx, + kt_jvm_toolchain, + dir, + input): + args = ctx.actions.args() + args.add("unzip", input) + args.add(dir.path) + + kt_run_deploy_jar( + ctx = ctx, + java_runtime = kt_jvm_toolchain.java_runtime, + deploy_jar = kt_jvm_toolchain.source_jar_zipper, + inputs = [input], + outputs = [dir], + args = [args], + mnemonic = "SrcJarUnzip", + ) + + return dir + +def _zip_resources(ctx, kt_jvm_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. + kt_jvm_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, + ) + + kt_run_deploy_jar( + ctx = ctx, + java_runtime = kt_jvm_toolchain.java_runtime, + deploy_jar = kt_jvm_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_jvm_toolchain, + file_factory): + """Synchronizes the contents of a set of srcjar files and tree-artifacts""" + + _dirs = [] + _srcjars = [] + + def add_dirs(dirs): + if not dirs: + return + + _dirs.extend(dirs) + _srcjars.append( + _zip_resources( + ctx, + kt_jvm_toolchain, + file_factory.declare_file("%s-codegen.srcjar" % len(_srcjars)), + dirs, + ), + ) + + def add_srcjars(srcjars): + if not srcjars: + return + + for srcjar in srcjars: + _dirs.append( + _unzip( + ctx, + kt_jvm_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, + ) + +kt_srcjars = struct( + zip = _zip, + unzip = _unzip, + zip_resources = _zip_resources, + DirSrcjarSyncer = _DirSrcjarSyncer, +) |