Skip to content

Commit

Permalink
Remove deploy jar Java runtime dependency for non-executable targets
Browse files Browse the repository at this point in the history
This allows deploy jars for `java_binary` targets with
`create_executable = False` to compile for target platforms for which no
standalone Java runtime is available (e.g. Android).

Along the way, this removes a redundant check: `runtime.hermetic_files`
is never `None`.
  • Loading branch information
fmeum committed Aug 2, 2023
1 parent 404eb64 commit 93f5856
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def _stamping_enabled(ctx, stamp):
def _get_build_info(ctx, stamp):
return get_build_info(ctx, _stamping_enabled(ctx, stamp))

def _bazel_deploy_jars_impl(ctx):
def _bazel_deploy_jars_impl(ctx, *, create_executable):
info = ctx.attr.binary[InternalDeployJarInfo]

runfiles_manifest = ctx.attr.binary.files_to_run.runfiles_manifest
Expand All @@ -55,8 +55,17 @@ def _bazel_deploy_jars_impl(ctx):
build_info_files,
str(ctx.attr.binary.label),
manifest_lines = info.manifest_lines,
create_executable = create_executable,
)

return []

deploy_jars = make_deploy_jars_rule(implementation = _bazel_deploy_jars_impl)
executable_deploy_jars = make_deploy_jars_rule(
implementation = lambda ctx: _bazel_deploy_jars_impl(ctx, create_executable = True),
create_executable = True,
)

nonexecutable_deploy_jars = make_deploy_jars_rule(
implementation = lambda ctx: _bazel_deploy_jars_impl(ctx, create_executable = False),
create_executable = False,
)
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ load(":bazel/java/bazel_java_binary.bzl", _java_test = "java_test", java_bin_exe
load(":bazel/java/bazel_java_binary_nolauncher.bzl", java_bin_exec_no_launcher_flag = "java_binary", java_test_no_launcher = "java_test")
load(":bazel/java/bazel_java_binary_custom_launcher.bzl", java_bin_exec_custom_launcher = "java_binary", java_test_custom_launcher = "java_test")
load(":bazel/java/bazel_java_binary_nonexec.bzl", java_bin_nonexec = "java_binary")
load(":bazel/java/bazel_java_binary_deploy_jar.bzl", "deploy_jars")
load(":bazel/java/bazel_java_binary_deploy_jar.bzl", "executable_deploy_jars", "nonexecutable_deploy_jars")
load(":common/java/java_binary_wrapper.bzl", "register_java_binary_rules")

def java_binary(**kwargs):
Expand All @@ -31,7 +31,8 @@ def java_binary(**kwargs):
java_bin_nonexec,
java_bin_exec_no_launcher_flag,
java_bin_exec_custom_launcher,
rule_deploy_jars = deploy_jars,
rule_executable_deploy_jars = executable_deploy_jars,
rule_nonexecutable_deploy_jars = nonexecutable_deploy_jars,
**kwargs
)

Expand All @@ -41,7 +42,8 @@ def java_test(**kwargs):
java_test_no_launcher,
java_test_no_launcher,
java_test_custom_launcher,
rule_deploy_jars = deploy_jars,
rule_executable_deploy_jars = executable_deploy_jars,
rule_nonexecutable_deploy_jars = nonexecutable_deploy_jars,
is_test_rule_class = True,
**kwargs
)
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def create_deploy_archives(
strip_as_default,
build_info_files,
build_target,
create_executable,
hermetic = False,
add_exports = depset(),
add_opens = depset(),
Expand All @@ -53,9 +54,10 @@ def create_deploy_archives(
runfiles: (Depset) the runfiles for the deploy jar
main_class: (String) FQN of the entry point for execution
coverage_main_class: (String) FQN of the entry point for coverage collection
build_target: (String) Name of the build target for stamping
strip_as_default: (bool) Whether to create unstripped deploy jar
build_info_files: ([File]) the artifacts containing workspace status for the current build
build_target: (String) Name of the build target for stamping
create_executable: (bool) The value of the java_binary create_executable attribute
hermetic: (bool)
add_exports: (depset)
add_opens: (depset)
Expand Down Expand Up @@ -89,6 +91,7 @@ def create_deploy_archives(
manifest_lines,
build_info_files,
build_target,
create_executable = create_executable,
output = ctx.outputs.deployjar,
shared_archive = shared_archive,
one_version_level = one_version_level,
Expand All @@ -113,6 +116,7 @@ def create_deploy_archives(
manifest_lines,
build_info_files,
build_target,
create_executable = create_executable,
output = ctx.outputs.unstrippeddeployjar,
multi_release = multi_release,
hermetic = hermetic,
Expand All @@ -133,6 +137,7 @@ def create_deploy_archive(
manifest_lines,
build_info_files,
build_target,
create_executable,
output,
shared_archive = None,
one_version_level = "OFF",
Expand All @@ -157,6 +162,7 @@ def create_deploy_archive(
manifest_lines: (list[String]) Optional lines added to the jar manifest
build_info_files: (list[File]) build info files for stamping
build_target: (String) the owner build target label name string
create_executable: (bool) The value of the java_binary create_executable attribute
output: (File) the output jar artifact
shared_archive: (File) Optional .jsa artifact
one_version_level: (String) Optional one version check level, default OFF
Expand All @@ -167,8 +173,6 @@ def create_deploy_archive(
add_opens: (depset)
extra_args: (list[Args]) Optional arguments for the deploy jar action
"""
runtime = semantics.find_java_runtime_toolchain(ctx)

input_files = []
input_files.extend(build_info_files)

Expand All @@ -178,6 +182,13 @@ def create_deploy_archive(
if ctx.configuration.coverage_enabled:
manifest_lines.append("Coverage-Main-Class: %s" % coverage_main_class)

transitive_inputs = [
resources,
classpath_resources,
runtime_classpath,
runfiles,
]

args = ctx.actions.args()
args.set_param_file_format("shell").use_param_file("@%s", use_always = True)

Expand Down Expand Up @@ -209,17 +220,20 @@ def create_deploy_archive(
if multi_release:
args.add("--multi_release")

hermetic_files = runtime.hermetic_files
if hermetic and runtime.lib_modules != None and hermetic_files != None:
java_home = runtime.java_home
lib_modules = runtime.lib_modules
args.add("--hermetic_java_home", java_home)
args.add("--jdk_lib_modules", lib_modules)
args.add_all("--resources", hermetic_files)
input_files.append(lib_modules)
if create_executable:
runtime = semantics.find_java_runtime_toolchain(ctx)
if hermetic and runtime.lib_modules != None:
java_home = runtime.java_home
lib_modules = runtime.lib_modules
hermetic_files = runtime.hermetic_files
args.add("--hermetic_java_home", java_home)
args.add("--jdk_lib_modules", lib_modules)
args.add_all("--resources", hermetic_files)
input_files.append(lib_modules)
transitive_inputs.append(hermetic_files)

if shared_archive == None:
shared_archive = runtime.default_cds
if shared_archive == None:
shared_archive = runtime.default_cds

if shared_archive:
input_files.append(shared_archive)
Expand All @@ -228,13 +242,7 @@ def create_deploy_archive(
args.add_all("--add_exports", add_exports)
args.add_all("--add_opens", add_opens)

inputs = depset(input_files, transitive = [
resources,
classpath_resources,
runtime_classpath,
runfiles,
hermetic_files,
])
inputs = depset(input_files, transitive = transitive_inputs)

ctx.actions.run(
mnemonic = "JavaDeployJar",
Expand All @@ -254,11 +262,12 @@ def _implicit_outputs(binary):
"unstrippeddeployjar": "%s_deploy.jar.unstripped" % binary_name,
}

def make_deploy_jars_rule(implementation):
def make_deploy_jars_rule(implementation, *, create_executable):
"""Creates the deploy jar auxiliary rule for java_binary
Args:
implementation: (Function) The rule implementation function
create_executable: (bool) The value of the create_executable attribute of java_binary
Returns:
The deploy jar rule class
Expand All @@ -274,12 +283,19 @@ def make_deploy_jars_rule(implementation):
),
"_cc_toolchain": attr.label(default = "@" + cc_semantics.get_repo() + "//tools/cpp:current_cc_toolchain"),
"_java_toolchain_type": attr.label(default = semantics.JAVA_TOOLCHAIN_TYPE),
"_java_runtime_toolchain_type": attr.label(default = semantics.JAVA_RUNTIME_TOOLCHAIN_TYPE),
"_build_info_translator": attr.label(
default = semantics.BUILD_INFO_TRANSLATOR_LABEL,
),
},
} | (
{
"_java_runtime_toolchain_type": attr.label(
default = semantics.JAVA_RUNTIME_TOOLCHAIN_TYPE,
),
} if create_executable else {}
),
outputs = _implicit_outputs,
fragments = ["java"],
toolchains = [semantics.JAVA_TOOLCHAIN, semantics.JAVA_RUNTIME_TOOLCHAIN] + cc_helper.use_cpp_toolchain(),
toolchains = [semantics.JAVA_TOOLCHAIN] + cc_helper.use_cpp_toolchain() + (
[semantics.JAVA_RUNTIME_TOOLCHAIN] if create_executable else []
),
)
18 changes: 15 additions & 3 deletions src/main/starlark/builtins_bzl/common/java/java_binary_wrapper.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,34 @@ the supplied value of the `create_executable` attribute.

_DEPLOY_JAR_RULE_NAME_SUFFIX = "_deployjars_internal_rule"

def register_java_binary_rules(rule_exec, rule_nonexec, rule_nolauncher, rule_customlauncher, rule_deploy_jars = None, is_test_rule_class = False, **kwargs):
def register_java_binary_rules(
rule_exec,
rule_nonexec,
rule_nolauncher,
rule_customlauncher,
rule_executable_deploy_jars = None,
rule_nonexecutable_deploy_jars = None,
is_test_rule_class = False,
**kwargs):
"""Registers the correct java_binary rule and deploy jar rule
Args:
rule_exec: (Rule) The executable java_binary rule
rule_nonexec: (Rule) The non-executable java_binary rule
rule_nolauncher: (Rule) The executable java_binary rule without launcher flag resolution
rule_customlauncher: (Rule) The executable java_binary rule with a custom launcher attr set
rule_deploy_jars: (Rule) The auxiliary deploy jars rule
rule_executable_deploy_jars: (Rule) The auxiliary deploy jars rule for create_executable = True
rule_nonexecutable_deploy_jars: (Rule) The auxiliary deploy jars rule for create_executable = False
is_test_rule_class: (bool) If this is a test rule
**kwargs: Actual args to instantiate the rule
"""

create_executable = "create_executable" not in kwargs or kwargs["create_executable"]

# TODO(hvd): migrate depot to integers / maybe use decompose_select_list()
if "stamp" in kwargs and type(kwargs["stamp"]) == type(True):
kwargs["stamp"] = 1 if kwargs["stamp"] else 0
if "create_executable" in kwargs and not kwargs["create_executable"]:
if not create_executable:
rule_nonexec(**kwargs)
elif "use_launcher" in kwargs and not kwargs["use_launcher"]:
rule_nolauncher(**kwargs)
Expand All @@ -45,6 +56,7 @@ def register_java_binary_rules(rule_exec, rule_nonexec, rule_nolauncher, rule_cu
else:
rule_exec(**kwargs)

rule_deploy_jars = rule_executable_deploy_jars if create_executable else rule_nonexecutable_deploy_jars
if rule_deploy_jars and (
not kwargs.get("tags", []) or "nodeployjar" not in kwargs.get("tags", [])
):
Expand Down

0 comments on commit 93f5856

Please sign in to comment.