|
1 | 1 | '''Defines the `graalvm_native_image` rule. |
2 | 2 | ''' |
3 | 3 |
|
| 4 | +load("//java:providers/JavaDependencyInfo.bzl", "JavaDependencyInfo") |
| 5 | +load("//java:common/extract/toolchain_info.bzl", "extract_graalvm_native_image_toolchain_info") |
| 6 | + |
| 7 | +def _build_script_name(ctx): |
| 8 | + return ctx.attr.name + ".build_native_image.sh" |
| 9 | + |
| 10 | +# TODO(dwtj): Consider revising control flow so that this is called just once, |
| 11 | +# not twice. |
| 12 | +def _make_class_path_depset(ctx): |
| 13 | + depsets = [] |
| 14 | + for dep in ctx.attr.deps: |
| 15 | + dep_info = dep[JavaDependencyInfo] |
| 16 | + depsets.append(dep_info.compile_time_class_path_jars) |
| 17 | + return depset([], transitive = depsets) |
| 18 | + |
| 19 | +def _make_class_path_string(ctx): |
| 20 | + toolchain_info = extract_graalvm_native_image_toolchain_info(ctx) |
| 21 | + jar_depset = _make_class_path_depset(ctx) |
| 22 | + jar_list = [jar.path for jar in jar_depset.to_list()] |
| 23 | + return toolchain_info.class_path_separator.join(jar_list) |
| 24 | + |
| 25 | +def _make_native_image_build_script(ctx): |
| 26 | + toolchain_info = extract_graalvm_native_image_toolchain_info(ctx) |
| 27 | + build_script = ctx.actions.declare_file(_build_script_name(ctx)) |
| 28 | + ctx.actions.expand_template( |
| 29 | + template = toolchain_info.graalvm_native_image_script_template, |
| 30 | + output = build_script, |
| 31 | + substitutions = { |
| 32 | + "{NATIVE_IMAGE_EXEC}": toolchain_info.native_image_exec.path, |
| 33 | + "{CLASS_PATH}": _make_class_path_string(ctx), |
| 34 | + "{MAIN_CLASS}": ctx.attr.main_class, |
| 35 | + "{OUTPUT_IMAGE}": ctx.outputs.output_image.path, |
| 36 | + }, |
| 37 | + is_executable = True, |
| 38 | + ) |
| 39 | + return build_script |
| 40 | + |
| 41 | +def _build_native_image(ctx): |
| 42 | + toolchain_info = extract_graalvm_native_image_toolchain_info(ctx) |
| 43 | + build_script = _make_native_image_build_script(ctx) |
| 44 | + ctx.actions.run( |
| 45 | + outputs = [ctx.outputs.output_image], |
| 46 | + inputs = _make_class_path_depset(ctx), |
| 47 | + executable = build_script, |
| 48 | + tools = [toolchain_info.native_image_exec], |
| 49 | + mnemonic = "GraalVmNativeImage", |
| 50 | + progress_message = "Building native image for `{}`".format(ctx.label), |
| 51 | + # NOTE(dwtj): Currently, we `use_default_shell_env` so that the |
| 52 | + # `native-image` executable can find the system C compiler and |
| 53 | + # libraries. |
| 54 | + # TODO(dwtj): Set this to `False` to make builds more hermetic. How can |
| 55 | + # we help `native-image` find the C compiler and libraries. |
| 56 | + use_default_shell_env = True, |
| 57 | + ) |
| 58 | + |
4 | 59 | def _graalvm_native_image_impl(ctx): |
5 | | - # TODO(dwtj): Everything! |
6 | | - print("Hello, from `_graalvm_native_image_impl().") |
7 | | - pass |
| 60 | + _build_native_image(ctx) |
| 61 | + return [ |
| 62 | + DefaultInfo( |
| 63 | + files = depset([ctx.outputs.output_image]), |
| 64 | + ) |
| 65 | + ] |
8 | 66 |
|
9 | 67 | graalvm_native_image = rule( |
10 | 68 | implementation = _graalvm_native_image_impl, |
11 | 69 | attrs = { |
12 | | - # TODO(dwtj): Everything! |
| 70 | + "main_class": attr.string( |
| 71 | + mandatory = True, |
| 72 | + ), |
| 73 | + "deps": attr.label_list( |
| 74 | + allow_empty = False, |
| 75 | + providers = [JavaDependencyInfo], |
| 76 | + mandatory = True, |
| 77 | + ), |
| 78 | + "output_image": attr.output( |
| 79 | + # TODO(dwtj): Make this optional. |
| 80 | + mandatory = True, |
| 81 | + ), |
13 | 82 | }, |
14 | 83 | toolchains = [ |
15 | 84 | "@dwtj_rules_java//java/toolchains/graalvm_native_image_toolchain:toolchain_type", |
|
0 commit comments