Skip to content

Commit

Permalink
feat(native_image): add static_zlib
Browse files Browse the repository at this point in the history
When provided, the static zlib library will be used when Graal
statically links in zlib.

Signed-off-by: Sam Gammon <sam@elide.ventures>
  • Loading branch information
fmeum authored and sgammon committed Sep 1, 2023
1 parent 426cea5 commit 31e31e0
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 4 deletions.
3 changes: 2 additions & 1 deletion docs/api/defs.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Target rule definitions, intended for use by rule users.
<pre>
native_image(<a href="#native_image-name">name</a>, <a href="#native_image-deps">deps</a>, <a href="#native_image-main_class">main_class</a>, <a href="#native_image-include_resources">include_resources</a>, <a href="#native_image-reflection_configuration">reflection_configuration</a>, <a href="#native_image-jni_configuration">jni_configuration</a>,
<a href="#native_image-initialize_at_build_time">initialize_at_build_time</a>, <a href="#native_image-initialize_at_run_time">initialize_at_run_time</a>, <a href="#native_image-native_features">native_features</a>, <a href="#native_image-data">data</a>, <a href="#native_image-extra_args">extra_args</a>,
<a href="#native_image-check_toolchains">check_toolchains</a>, <a href="#native_image-c_compiler_option">c_compiler_option</a>, <a href="#native_image-executable_name">executable_name</a>, <a href="#native_image-native_image_tool">native_image_tool</a>,
<a href="#native_image-check_toolchains">check_toolchains</a>, <a href="#native_image-static_zlib">static_zlib</a>, <a href="#native_image-c_compiler_option">c_compiler_option</a>, <a href="#native_image-executable_name">executable_name</a>, <a href="#native_image-native_image_tool">native_image_tool</a>,
<a href="#native_image-native_image_settings">native_image_settings</a>, <a href="#native_image-kwargs">kwargs</a>)
</pre>

Expand All @@ -32,6 +32,7 @@ Generates and compiles a GraalVM native image from a Java library target.
| <a id="native_image-data"></a>data | Data files to make available during the compilation. No default; optional. | `[]` |
| <a id="native_image-extra_args"></a>extra_args | Extra `native-image` args to pass. Last wins. No default; optional. | `[]` |
| <a id="native_image-check_toolchains"></a>check_toolchains | Whether to perform toolchain checks in `native-image`; defaults to `True` on Windows, `False` otherwise. | `select({"@bazel_tools//src/conditions:windows": True, "//conditions:default": False})` |
| <a id="native_image-static_zlib"></a>static_zlib | A cc_library or cc_import target that provides zlib as a static library. On Linux, this is used when Graal statically links zlib into the binary, e.g. with `-H:+StaticExecutableWithDynamicLibC`. | `False` |
| <a id="native_image-c_compiler_option"></a>c_compiler_option | Extra C compiler options to pass through `native-image`. No default; optional. | `[]` |
| <a id="native_image-executable_name"></a>executable_name | Set the name of the output binary; defaults to `%target%-bin`, or `%target%-bin.exe` on Windows. The special string `%target%`, if present, is replaced with `name`. | `select({"@bazel_tools//src/conditions:windows": "%target%-bin.exe", "//conditions:default": "%target%-bin"})` |
| <a id="native_image-native_image_tool"></a>native_image_tool | Specific `native-image` executable target to use. | `None` |
Expand Down
8 changes: 6 additions & 2 deletions docs/api/legacy.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ Rules for building native binaries using the GraalVM `native-image` tool on Baze
<pre>
graal_binary(<a href="#graal_binary-name">name</a>, <a href="#graal_binary-deps">deps</a>, <a href="#graal_binary-main_class">main_class</a>, <a href="#graal_binary-include_resources">include_resources</a>, <a href="#graal_binary-reflection_configuration">reflection_configuration</a>, <a href="#graal_binary-jni_configuration">jni_configuration</a>,
<a href="#graal_binary-initialize_at_build_time">initialize_at_build_time</a>, <a href="#graal_binary-initialize_at_run_time">initialize_at_run_time</a>, <a href="#graal_binary-native_features">native_features</a>, <a href="#graal_binary-data">data</a>, <a href="#graal_binary-extra_args">extra_args</a>,
<a href="#graal_binary-check_toolchains">check_toolchains</a>, <a href="#graal_binary-c_compiler_option">c_compiler_option</a>, <a href="#graal_binary-executable_name">executable_name</a>, <a href="#graal_binary-native_image_tool">native_image_tool</a>, <a href="#graal_binary-kwargs">kwargs</a>)
<a href="#graal_binary-check_toolchains">check_toolchains</a>, <a href="#graal_binary-c_compiler_option">c_compiler_option</a>, <a href="#graal_binary-static_zlib">static_zlib</a>, <a href="#graal_binary-executable_name">executable_name</a>, <a href="#graal_binary-native_image_tool">native_image_tool</a>,
<a href="#graal_binary-kwargs">kwargs</a>)
</pre>

Alias for the renamed `native_image` rule. Identical.
Expand All @@ -32,6 +33,7 @@ Alias for the renamed `native_image` rule. Identical.
| <a id="graal_binary-extra_args"></a>extra_args | Extra `native-image` args to pass. Last wins. No default; optional. | `[]` |
| <a id="graal_binary-check_toolchains"></a>check_toolchains | Whether to perform toolchain checks in `native-image`; defaults to `True` on Windows, `False` otherwise. | `select({"@bazel_tools//src/conditions:windows": True, "//conditions:default": False})` |
| <a id="graal_binary-c_compiler_option"></a>c_compiler_option | Extra C compiler options to pass through `native-image`. No default; optional. | `[]` |
| <a id="graal_binary-static_zlib"></a>static_zlib | A cc_library or cc_import target that provides zlib as a static library. On Linux, this is used when Graal statically links zlib into the binary, e.g. with `-H:+StaticExecutableWithDynamicLibC`. | `False` |
| <a id="graal_binary-executable_name"></a>executable_name | Set the name of the output binary; defaults to `%target%-bin`, or `%target%-bin.exe` on Windows. The special string `%target%`, if present, is replaced with `name`. | `select({"@bazel_tools//src/conditions:windows": "%target%-bin.exe", "//conditions:default": "%target%-bin"})` |
| <a id="graal_binary-native_image_tool"></a>native_image_tool | Specific `native-image` executable target to use. | `Label("@graalvm//:native-image")` |
| <a id="graal_binary-kwargs"></a>kwargs | Extra keyword arguments are passed to the underlying `native_image` rule. | none |
Expand All @@ -44,7 +46,8 @@ Alias for the renamed `native_image` rule. Identical.
<pre>
native_image(<a href="#native_image-name">name</a>, <a href="#native_image-deps">deps</a>, <a href="#native_image-main_class">main_class</a>, <a href="#native_image-include_resources">include_resources</a>, <a href="#native_image-reflection_configuration">reflection_configuration</a>, <a href="#native_image-jni_configuration">jni_configuration</a>,
<a href="#native_image-initialize_at_build_time">initialize_at_build_time</a>, <a href="#native_image-initialize_at_run_time">initialize_at_run_time</a>, <a href="#native_image-native_features">native_features</a>, <a href="#native_image-data">data</a>, <a href="#native_image-extra_args">extra_args</a>,
<a href="#native_image-check_toolchains">check_toolchains</a>, <a href="#native_image-c_compiler_option">c_compiler_option</a>, <a href="#native_image-executable_name">executable_name</a>, <a href="#native_image-native_image_tool">native_image_tool</a>, <a href="#native_image-kwargs">kwargs</a>)
<a href="#native_image-check_toolchains">check_toolchains</a>, <a href="#native_image-c_compiler_option">c_compiler_option</a>, <a href="#native_image-static_zlib">static_zlib</a>, <a href="#native_image-executable_name">executable_name</a>, <a href="#native_image-native_image_tool">native_image_tool</a>,
<a href="#native_image-kwargs">kwargs</a>)
</pre>

Generates and compiles a GraalVM native image from a Java library target.
Expand All @@ -67,6 +70,7 @@ Generates and compiles a GraalVM native image from a Java library target.
| <a id="native_image-extra_args"></a>extra_args | Extra `native-image` args to pass. Last wins. No default; optional. | `[]` |
| <a id="native_image-check_toolchains"></a>check_toolchains | Whether to perform toolchain checks in `native-image`; defaults to `True` on Windows, `False` otherwise. | `select({"@bazel_tools//src/conditions:windows": True, "//conditions:default": False})` |
| <a id="native_image-c_compiler_option"></a>c_compiler_option | Extra C compiler options to pass through `native-image`. No default; optional. | `[]` |
| <a id="native_image-static_zlib"></a>static_zlib | A cc_library or cc_import target that provides zlib as a static library. On Linux, this is used when Graal statically links zlib into the binary, e.g. with `-H:+StaticExecutableWithDynamicLibC`. | `False` |
| <a id="native_image-executable_name"></a>executable_name | Set the name of the output binary; defaults to `%target%-bin`, or `%target%-bin.exe` on Windows. The special string `%target%`, if present, is replaced with `name`. | `select({"@bazel_tools//src/conditions:windows": "%target%-bin.exe", "//conditions:default": "%target%-bin"})` |
| <a id="native_image-native_image_tool"></a>native_image_tool | Specific `native-image` executable target to use. | `Label("@graalvm//:native-image")` |
| <a id="native_image-kwargs"></a>kwargs | Extra keyword arguments are passed to the underlying `native_image` rule. | none |
Expand Down
10 changes: 10 additions & 0 deletions graal/graal.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ def native_image(
"//conditions:default": False,
}),
c_compiler_option = [],
static_zlib = None,
executable_name = select({
"@bazel_tools//src/conditions:windows": "%target%-bin.exe",
"//conditions:default": "%target%-bin",
Expand All @@ -78,6 +79,9 @@ def native_image(
extra_args: Extra `native-image` args to pass. Last wins. No default; optional.
check_toolchains: Whether to perform toolchain checks in `native-image`; defaults to `True` on Windows, `False` otherwise.
c_compiler_option: Extra C compiler options to pass through `native-image`. No default; optional.
static_zlib: A cc_library or cc_import target that provides zlib as a static library.
On Linux, this is used when Graal statically links zlib into the binary, e.g. with
`-H:+StaticExecutableWithDynamicLibC`.
executable_name: Set the name of the output binary; defaults to `%target%-bin`, or `%target%-bin.exe` on Windows.
The special string `%target%`, if present, is replaced with `name`.
native_image_tool: Specific `native-image` executable target to use.
Expand All @@ -97,6 +101,7 @@ def native_image(
data = data,
extra_args = extra_args,
check_toolchains = check_toolchains,
static_zlib = static_zlib,
c_compiler_option = c_compiler_option,
executable_name = executable_name,
native_image_tool = native_image_tool,
Expand All @@ -120,6 +125,7 @@ def graal_binary(
"//conditions:default": False,
}),
c_compiler_option = [],
static_zlib = None,
executable_name = select({
"@bazel_tools//src/conditions:windows": "%target%-bin.exe",
"//conditions:default": "%target%-bin",
Expand All @@ -141,6 +147,9 @@ def graal_binary(
data: Data files to make available during the compilation. No default; optional.
extra_args: Extra `native-image` args to pass. Last wins. No default; optional.
check_toolchains: Whether to perform toolchain checks in `native-image`; defaults to `True` on Windows, `False` otherwise.
static_zlib: A cc_library or cc_import target that provides zlib as a static library.
On Linux, this is used when Graal statically links zlib into the binary, e.g. with
`-H:+StaticExecutableWithDynamicLibC`.
c_compiler_option: Extra C compiler options to pass through `native-image`. No default; optional.
executable_name: Set the name of the output binary; defaults to `%target%-bin`, or `%target%-bin.exe` on Windows.
The special string `%target%`, if present, is replaced with `name`.
Expand All @@ -160,6 +169,7 @@ def graal_binary(
native_features = native_features,
data = data,
extra_args = extra_args,
static_zlib = static_zlib,
check_toolchains = check_toolchains,
c_compiler_option = c_compiler_option,
executable_name = executable_name,
Expand Down
5 changes: 5 additions & 0 deletions graalvm/nativeimage/rules.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ def native_image(
data = [],
extra_args = [],
check_toolchains = _DEFAULT_CHECK_TOOLCHAINS_CONDITION,
static_zlib = None,
c_compiler_option = [],
executable_name = _EXEUCTABLE_NAME_CONDITION,
native_image_tool = None, # uses toolchains by default
Expand All @@ -92,6 +93,9 @@ def native_image(
data: Data files to make available during the compilation. No default; optional.
extra_args: Extra `native-image` args to pass. Last wins. No default; optional.
check_toolchains: Whether to perform toolchain checks in `native-image`; defaults to `True` on Windows, `False` otherwise.
static_zlib: A cc_library or cc_import target that provides zlib as a static library.
On Linux, this is used when Graal statically links zlib into the binary, e.g. with
`-H:+StaticExecutableWithDynamicLibC`.
c_compiler_option: Extra C compiler options to pass through `native-image`. No default; optional.
executable_name: Set the name of the output binary; defaults to `%target%-bin`, or `%target%-bin.exe` on Windows.
The special string `%target%`, if present, is replaced with `name`.
Expand All @@ -113,6 +117,7 @@ def native_image(
data = data,
extra_args = extra_args,
check_toolchains = check_toolchains,
static_zlib = static_zlib,
c_compiler_option = c_compiler_option,
executable_name = executable_name,
native_image_tool = native_image_tool,
Expand Down
66 changes: 65 additions & 1 deletion internal/native_image/builder.bzl
Original file line number Diff line number Diff line change
@@ -1,5 +1,48 @@
"Logic to assemble `native-image` options."

def _configure_static_zlib_compile(ctx, args, direct_inputs):
"""Configure a static image compile against hermetic/static zlib.
Args:
ctx: Context of the Native Image rule implementation.
args: Args builder for the Native Image build.
direct_inputs: Inputs into the image build (mutable). """

if CcInfo in ctx.attr.static_zlib and ctx.target_platform_has_constraint(ctx.attr._linux_constraint[platform_common.ConstraintValueInfo]):
linking_context = ctx.attr.static_zlib[CcInfo].linking_context
linker_inputs = linking_context.linker_inputs.to_list()
if len(linker_inputs) != 1:
fail("Expected exactly one LinkerInput for static_zlib, got %s" % repr(linker_inputs))
libraries = linker_inputs[0].libraries

# In some versions of Bazel, libraries is a depset, in others it's a list.
if type(libraries) == type(depset([])):
libraries = libraries.to_list()
if len(libraries) != 1:
fail("Expected exactly one library for static_zlib, got %s" % repr(libraries))
library = libraries[0]

# Prefer PIC over non-PIC.
static_library = library.pic_static_library
if not static_library:
static_library = library.static_library
if not static_library:
fail("Expected a static library for static_zlib, got %s" % library)

zlib_static = ctx.actions.declare_file(
ctx.attr.name + "_hermetic_libs/libz.a"
)
ctx.actions.symlink(
output = zlib_static,
target_file = static_library,
)
args.add(
zlib_static.dirname,
format = "-H:CLibraryPath=%s",
)
direct_inputs.append(zlib_static)


def assemble_native_build_options(
ctx,
args,
Expand All @@ -9,7 +52,20 @@ def assemble_native_build_options(
c_compiler_path,
path_list_separator,
gvm_toolchain = None):
"""Assemble the effective arguments to `native-image`."""
"""Assemble the effective arguments to `native-image`.
This function is responsible for converting the current rule invocation context into a set of arguments
which can be passed to the `native-image` builder.
Args:
ctx: Context of the Native Image rule implementation.
args: Args builder for the Native Image build.
binary: Target output binary which will be built with Native Image.
classpath_depset: Classpath dependency set.
direct_inputs: Direct inputs into the native image build (mutable).
c_compiler_path: Path to the C compiler; resolved via toolchains.
path_list_separator: Platform-specific path separator.
gvm_toolchain: Resolved GraalVM toolchain, or `None` if a tool target is in use via legacy rules. """

args.add("--no-fallback")

Expand Down Expand Up @@ -63,3 +119,11 @@ def assemble_native_build_options(
args.add(ctx.file.jni_configuration, format = "-H:JNIConfigurationFiles=%s")
direct_inputs.append(ctx.file.jni_configuration)
args.add("-H:+JNI")

# if a static build is being performed against hermetic zlib, configure it
if ctx.attr.static_zlib != None:
_configure_static_zlib_compile(
ctx,
args,
direct_inputs,
)
3 changes: 3 additions & 0 deletions internal/native_image/common.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ _NATIVE_IMAGE_ATTRS = {
"native_features": attr.string_list(
mandatory = False,
),
"static_zlib": attr.label(
providers = [[CcInfo]],
),
"data": attr.label_list(
allow_files = True,
),
Expand Down
3 changes: 3 additions & 0 deletions internal/native_image/rules.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,13 @@ def _graal_binary_implementation(ctx):
native_toolchain.c_compiler_path,
gvm_toolchain,
)

# assemble final inputs
inputs = depset(
direct_inputs,
transitive = transitive_inputs,
)

run_params = {
"outputs": [binary],
"executable": graal,
Expand Down

0 comments on commit 31e31e0

Please sign in to comment.