| # 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. | |
| load("//kotlin/rules:defs.bzl", "KotlinInfo") | |
| # DEPSET UTILS ######################################################################################################### | |
| def _select_compile_jars(dep): | |
| """selects the correct compile time jar from a java provider""" | |
| if not JavaInfo in dep: | |
| return [] | |
| is_kotlin_provider = KotlinInfo in dep | |
| java_provider = dep[JavaInfo] | |
| if is_kotlin_provider: | |
| return java_provider.full_compile_jars | |
| elif dep.label.workspace_root == "external/com_github_jetbrains_kotlin": | |
| return java_provider.full_compile_jars | |
| else: | |
| return java_provider.compile_jars | |
| def collect_jars_for_compile(deps): | |
| """creates the compile jar depset, this should be strict including only the output jars of the listed dependencies. | |
| """ | |
| compile_jars = depset() | |
| for d in deps: | |
| compile_jars += _select_compile_jars(d) | |
| return compile_jars | |
| def collect_all_jars(deps): | |
| """ | |
| Merges a list of java providers into a struct of depsets. | |
| """ | |
| compile_jars = depset() | |
| runtime_jars = depset() | |
| transitive_runtime_jars = depset() | |
| transitive_compile_time_jars = depset() | |
| for dep_target in deps: | |
| if JavaInfo in dep_target: | |
| java_provider = dep_target[JavaInfo] | |
| compile_jars += java_provider.compile_jars | |
| # the runtime_jar compile_jar seperation is here to support the exports concept. | |
| runtime_jars += java_provider.full_compile_jars | |
| transitive_compile_time_jars += java_provider.transitive_compile_time_jars | |
| transitive_runtime_jars += java_provider.transitive_runtime_jars | |
| return struct ( | |
| compile_jars = compile_jars, | |
| runtime_jars = runtime_jars, | |
| transitive_runtime_jars = transitive_runtime_jars, | |
| transitive_compile_time_jars = transitive_compile_time_jars | |
| ) | |
| # RESOURCE JARS ######################################################################################################## | |
| _CONVENTIONAL_RESOURCE_PATHS = [ | |
| "src/main/resources", | |
| "src/test/resources", | |
| ] | |
| def _adjust_resources_path_by_strip_prefix(path, resource_strip_prefix): | |
| if not path.startswith(resource_strip_prefix): | |
| fail("Resource file %s is not under the specified prefix to strip" % path) | |
| clean_path = path[len(resource_strip_prefix):] | |
| return resource_strip_prefix, clean_path | |
| def _adjust_resources_path_by_default_prefixes(path): | |
| for cp in _CONVENTIONAL_RESOURCE_PATHS: | |
| dir_1, dir_2, rel_path = path.partition(cp) | |
| if rel_path: | |
| return dir_1 + dir_2, rel_path | |
| return "", path | |
| def _adjust_resources_path(path, resource_strip_prefix): | |
| if resource_strip_prefix: | |
| return _adjust_resources_path_by_strip_prefix(path,resource_strip_prefix) | |
| else: | |
| return _adjust_resources_path_by_default_prefixes(path) | |
| def _add_resources_cmd(ctx): | |
| res_cmd = [] | |
| for f in ctx.files.resources: | |
| c_dir, res_path = _adjust_resources_path(f.short_path, ctx.attr.resource_strip_prefix) | |
| target_path = res_path | |
| if target_path[0] == "/": | |
| target_path = target_path[1:] | |
| line = "{target_path}={c_dir}{res_path}\n".format( | |
| res_path=res_path, | |
| target_path=target_path, | |
| c_dir=c_dir) | |
| res_cmd.extend([line]) | |
| return "".join(res_cmd) | |
| def kotlin_build_resourcejar_action(ctx): | |
| resources = _add_resources_cmd(ctx) | |
| resources_jar_output = ctx.actions.declare_file(ctx.label.name + "-resources.jar") | |
| zipper_arg_path = ctx.actions.declare_file("%s_resources_zipper_args" % ctx.label.name) | |
| ctx.file_action(zipper_arg_path, resources) | |
| cmd = """ | |
| rm -f {resources_jar_output} | |
| {zipper} c {resources_jar_output} @{path} | |
| """.format( | |
| path=zipper_arg_path.path, | |
| resources_jar_output=resources_jar_output.path, | |
| zipper=ctx.executable._zipper.path, | |
| ) | |
| ctx.action( | |
| mnemonic="KotlinZipResourceJar", | |
| inputs=ctx.files.resources + [ctx.executable._zipper,zipper_arg_path], | |
| outputs=[resources_jar_output], | |
| command=cmd, | |
| progress_message="Creating intermediate resource jar %s" % ctx.label, | |
| arguments=[] | |
| ) | |
| return resources_jar_output | |
| # SRC JARS ############################################################################################################# | |
| def kotlin_maybe_make_srcs_action(ctx): | |
| if len(ctx.files.srcs) > 0: | |
| output_srcjar = ctx.actions.declare_file(ctx.label.name + "-sources.jar") | |
| args = ["--output", output_srcjar.path] | |
| for i in ctx.files.srcs: | |
| args += ["--resources", i.path] | |
| ctx.action( | |
| mnemonic = "KotlinPackageSources", | |
| inputs = ctx.files.srcs, | |
| outputs = [output_srcjar], | |
| executable = ctx.executable._singlejar, | |
| arguments = args, | |
| progress_message="Creating Kotlin srcjar from %d srcs" % len(ctx.files.srcs), | |
| ) | |
| return [output_srcjar] | |
| else: | |
| return [] | |
| # PACKAGE JARS ######################################################################################################### | |
| def kotlin_fold_jars_action(ctx, output_jar, input_jars): | |
| args=["--output", output_jar.path] | |
| for i in input_jars: | |
| args += ["--sources", i.path] | |
| ctx.action( | |
| mnemonic = "KotlinFoldOutput", | |
| inputs = input_jars, | |
| outputs = [output_jar], | |
| executable = ctx.executable._singlejar, | |
| arguments = args, | |
| progress_message="Merging Kotlin output jar " + output_jar.short_path | |
| ) | |
| # JVM LAUNCH SCRIPTS ################################################################################################### | |
| def kotlin_write_launcher_action(ctx, rjars, main_class, jvm_flags, args="", wrapper_preamble=""): | |
| """Macro that writes out a launcher script shell script. | |
| Args: | |
| rjars: All of the runtime jars required to launch this java target. | |
| main_class: the main class to launch. | |
| jvm_flags: The flags that should be passed to the jvm. | |
| args: Args that should be passed to the Binary. | |
| """ | |
| classpath = ":".join(["${RUNPATH}%s" % (j.short_path) for j in rjars.to_list()]) | |
| jvm_flags = " ".join([ctx.expand_location(f, ctx.attr.data) for f in jvm_flags]) | |
| template = ctx.attr._java_stub_template.files.to_list()[0] | |
| ctx.template_action( | |
| template = template, | |
| output = ctx.outputs.executable, | |
| substitutions = { | |
| "%classpath%": classpath, | |
| "%java_start_class%": main_class, | |
| "%javabin%": "JAVABIN=${RUNPATH}" + ctx.executable._java.short_path, | |
| "%jvm_flags%": jvm_flags, | |
| "%set_jacoco_metadata%": "", | |
| "%workspace_prefix%": ctx.workspace_name + "/", | |
| }, | |
| executable = True, | |
| ) |