Skip to content

Commit

Permalink
feat(native_image): honor C toolchain compiler and linker flags
Browse files Browse the repository at this point in the history
Signed-off-by: Fabian Meumertzheim <fabian@meumertzhe.im>
  • Loading branch information
fmeum committed Sep 4, 2023
1 parent d08e249 commit 5d6fdc0
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 16 deletions.
40 changes: 33 additions & 7 deletions internal/native_image/builder.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def _configure_reflection(ctx, args, direct_inputs):
direct_inputs.append(ctx.file.jni_configuration)
args.add("-H:+JNI")

def _configure_native_compiler(ctx, args, c_compiler_path, gvm_toolchain):
def _configure_native_compiler(ctx, args, native_toolchain, gvm_toolchain):
"""Configure native compiler and linker flags for a Native Image build.
Args:
Expand All @@ -113,14 +113,41 @@ def _configure_native_compiler(ctx, args, c_compiler_path, gvm_toolchain):
_configure_optimization_mode(ctx, args)

if gvm_toolchain != None:
args.add(c_compiler_path, format = "--native-compiler-path=%s")
args.add(native_toolchain.c_compiler_path, format = "--native-compiler-path=%s")

# add custom compiler options
args.add_all(
_filter_linker_options(native_toolchain.linker_options),
format_each = "-H:NativeLinkerOption=%s",
)

args.add_all(
native_toolchain.compiler_options,
format_each = "-H:CCompilerOption=%s",
)

# add custom compiler options last
args.add_all(
ctx.attr.c_compiler_option,
format_each = "-H:CCompilerOption=%s",
)

def _filter_linker_options(options):
"""Filter out linker options that aren't desirable for native image builds.
Args:
options: List of linker options.
Returns:
List of linker options with undesirable options removed.
"""

# -Wl,-no-as-needed forcibly links against libstdc++ or libc++ with Bazel's auto-configured
# Unix toolchain, which is not desirable for native image builds.
# Return the list unchanged if possible as a memory optimization.
if "-Wl,-no-as-needed" not in options:
return options
return [option for option in options if option != "-Wl,-no-as-needed"]

def _configure_native_test_flags(ctx, args):
"""Configure native testing flags; only applies if we are building a test-only target.
Expand All @@ -138,7 +165,7 @@ def assemble_native_build_options(
binary,
classpath_depset,
direct_inputs,
c_compiler_path,
native_toolchain,
path_list_separator,
gvm_toolchain = None):
"""Assemble the effective arguments to `native-image`.
Expand All @@ -152,7 +179,7 @@ def assemble_native_build_options(
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.
native_toolchain: Struct with information about the C toolchain.
path_list_separator: Platform-specific path separator.
gvm_toolchain: Resolved GraalVM toolchain, or `None` if a tool target is in use via legacy rules.
"""
Expand All @@ -169,7 +196,6 @@ def assemble_native_build_options(
if not ctx.attr.allow_fallback:
args.add("--no-fallback")


args.add(ctx.attr.main_class, format = "-H:Class=%s")
args.add(binary.basename.replace(".exe", ""), format = "-H:Name=%s")
args.add(binary.dirname, format = "-H:Path=%s")
Expand All @@ -192,7 +218,7 @@ def assemble_native_build_options(
)

# configure the build optimization mode
_configure_native_compiler(ctx, args, c_compiler_path, gvm_toolchain)
_configure_native_compiler(ctx, args, native_toolchain, gvm_toolchain)

# configure reflection
_configure_reflection(ctx, args, direct_inputs)
Expand Down
6 changes: 3 additions & 3 deletions internal/native_image/classic.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ load(
"//internal/native_image:common.bzl",
_BAZEL_CPP_TOOLCHAIN_TYPE = "BAZEL_CPP_TOOLCHAIN_TYPE",
_BAZEL_CURRENT_CPP_TOOLCHAIN = "BAZEL_CURRENT_CPP_TOOLCHAIN",
_DEFAULT_GVM_REPO = "DEFAULT_GVM_REPO",
_DEBUG_CONDITION = "DEBUG_CONDITION",
_OPTIMIZATION_MODE_CONDITION = "OPTIMIZATION_MODE_CONDITION",
_DEFAULT_GVM_REPO = "DEFAULT_GVM_REPO",
_GVM_TOOLCHAIN_TYPE = "GVM_TOOLCHAIN_TYPE",
_NATIVE_IMAGE_ATTRS = "NATIVE_IMAGE_ATTRS",
_OPTIMIZATION_MODE_CONDITION = "OPTIMIZATION_MODE_CONDITION",
_RULES_REPO = "RULES_REPO",
_prepare_native_image_rule_context = "prepare_native_image_rule_context",
)
Expand Down Expand Up @@ -55,7 +55,7 @@ def _graal_binary_classic_implementation(ctx):
args,
classpath_depset,
direct_inputs,
native_toolchain.c_compiler_path,
native_toolchain,
)

inputs = depset(
Expand Down
4 changes: 2 additions & 2 deletions internal/native_image/common.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def _prepare_native_image_rule_context(
args,
classpath_depset,
direct_inputs,
c_compiler_path,
native_toolchain,
gvm_toolchain = None):
"""Prepare a `native-image` build context."""

Expand All @@ -155,7 +155,7 @@ def _prepare_native_image_rule_context(
binary,
classpath_depset,
direct_inputs,
c_compiler_path,
native_toolchain,
path_list_separator,
gvm_toolchain,
)
Expand Down
4 changes: 2 additions & 2 deletions internal/native_image/rules.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ load(
_BAZEL_CPP_TOOLCHAIN_TYPE = "BAZEL_CPP_TOOLCHAIN_TYPE",
_BAZEL_CURRENT_CPP_TOOLCHAIN = "BAZEL_CURRENT_CPP_TOOLCHAIN",
_DEBUG_CONDITION = "DEBUG_CONDITION",
_OPTIMIZATION_MODE_CONDITION = "OPTIMIZATION_MODE_CONDITION",
_DEFAULT_GVM_REPO = "DEFAULT_GVM_REPO",
_GVM_TOOLCHAIN_TYPE = "GVM_TOOLCHAIN_TYPE",
_NATIVE_IMAGE_ATTRS = "NATIVE_IMAGE_ATTRS",
_OPTIMIZATION_MODE_CONDITION = "OPTIMIZATION_MODE_CONDITION",
_RULES_REPO = "RULES_REPO",
_prepare_native_image_rule_context = "prepare_native_image_rule_context",
)
Expand Down Expand Up @@ -87,7 +87,7 @@ def _graal_binary_implementation(ctx):
args,
classpath_depset,
direct_inputs,
native_toolchain.c_compiler_path,
native_toolchain,
gvm_toolchain,
)

Expand Down
17 changes: 15 additions & 2 deletions internal/native_image/toolchain.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ def resolve_cc_toolchain(ctx, transitive_inputs, *, is_windows):
feature_configuration = feature_configuration,
action_name = C_COMPILE_ACTION_NAME,
)
compile_flags = cc_common.get_memory_inefficient_command_line(
feature_configuration = feature_configuration,
action_name = C_COMPILE_ACTION_NAME,
variables = compile_variables,
)

link_variables = cc_common.create_link_variables(
cc_toolchain = cc_toolchain,
feature_configuration = feature_configuration,
Expand All @@ -90,6 +96,11 @@ def resolve_cc_toolchain(ctx, transitive_inputs, *, is_windows):
feature_configuration = feature_configuration,
action_name = CPP_LINK_EXECUTABLE_ACTION_NAME,
)
link_flags = cc_common.get_memory_inefficient_command_line(
feature_configuration = feature_configuration,
action_name = CPP_LINK_EXECUTABLE_ACTION_NAME,
variables = link_variables,
)

# build final env and execution requirements
env = dicts.add(compile_env, link_env)
Expand All @@ -116,11 +127,13 @@ def resolve_cc_toolchain(ctx, transitive_inputs, *, is_windows):
if "/usr/bin" not in path_set:
paths.append("/usr/bin")

# seal paths with hack above
env["PATH"] = ctx.configuration.host_path_separator.join(paths)
path_separator = ";" if is_windows else ":"
env["PATH"] = path_separator.join(paths)

return struct(
c_compiler_path = c_compiler_path,
env = env,
execution_requirements = execution_requirements,
compiler_options = compile_flags,
linker_options = link_flags,
)

0 comments on commit 5d6fdc0

Please sign in to comment.