Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion d/private/rules/binary.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@ load("//d/private/rules:link.bzl", "link_action")
def _d_binary_impl(ctx):
"""Implementation of d_binary rule."""
d_info = compilation_action(ctx, target_type = TARGET_TYPE.BINARY)
output = link_action(ctx, d_info)
link_result = link_action(ctx, d_info)
output = link_result.executable
env_with_expansions = {
k: expand_variables(ctx, ctx.expand_location(v, ctx.files.data), [output], "env")
for k, v in ctx.attr.env.items()
}
return [
DefaultInfo(
executable = output,
files = depset([output] + link_result.additional_outputs),
runfiles = ctx.runfiles(files = ctx.files.data),
),
RunEnvironmentInfo(environment = env_with_expansions),
Expand Down
23 changes: 20 additions & 3 deletions d/private/rules/compile.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,15 @@ runnable_attrs = dicts.add(
"fat_lto": attr.string(default = "auto", values = ["auto", "on", "off"], doc = "Whether to use fat LTO."),
"linker_script": attr.label(allow_single_file = True, doc = "Linker script to be used for the binary."),
"link_with_d": attr.string(default = "auto", values = ["auto", "on", "off"], doc = "Whether to use the D compiler for linking."),
"additional_linker_inputs": attr.label_list(
allow_files = True,
default = [],
doc = "Additional inputs made visible to the link action (matches cc_library.additional_linker_inputs).",
),
"link_output_dirs": attr.string_list(
default = [],
doc = "Names of additional TreeArtifact directory outputs the link action will produce. The link action declares them, surfaces them via DefaultInfo.files, and (cc_common.link path only) passes them to cc_common.link's additional_outputs so the linker — or a wrapper invoked through it — can populate them.",
),
"_cc_toolchain": attr.label(
default = "@rules_cc//cc:current_cc_toolchain",
doc = "Default CC toolchain, used for linking. Remove after https://github.com/bazelbuild/bazel/issues/7260 is flipped (and support for old Bazel version is not needed)",
Expand Down Expand Up @@ -513,19 +522,27 @@ def compilation_action(ctx, target_type = TARGET_TYPE.LIBRARY, cycle_breaker = F
bc_output = compilation_result.bc_object
bc_library_to_link = compilation_result.bc_library_to_link

# Expand $(location ...) / $(execpath ...) / $(rootpath ...) against the
# rule's additional_linker_inputs (matching cc_library.linkopts semantics).
# Done here so the expanded form propagates through both linker_input.user_link_flags
# and DInfo.linker_flags, avoiding double-add in link.bzl.
expanded_linkopts = [
ctx.expand_location(opt, targets = getattr(ctx.attr, "additional_linker_inputs", []))
for opt in ctx.attr.linkopts
]
linker_input = None
if library_to_link:
linker_input = cc_common.create_linker_input(
owner = ctx.label,
libraries = depset(direct = [library_to_link] if library_to_link else None),
user_link_flags = ctx.attr.linkopts,
user_link_flags = expanded_linkopts,
)
bc_linker_input = linker_input
if bc_library_to_link:
bc_linker_input = cc_common.create_linker_input(
owner = ctx.label,
libraries = depset(direct = [bc_library_to_link] if bc_library_to_link else None),
user_link_flags = ctx.attr.linkopts,
user_link_flags = expanded_linkopts,
)
linking_context = cc_common.create_linking_context(
linker_inputs = depset(
Expand Down Expand Up @@ -558,7 +575,7 @@ def compilation_action(ctx, target_type = TARGET_TYPE.LIBRARY, cycle_breaker = F
),
linking_context = linking_context, # Already includes all deps internally
linker_flags = depset(
ctx.attr.linkopts,
expanded_linkopts,
transitive = [d.linker_flags for d in d_deps], # Only regular deps
),
source_map = export_source_map,
Expand Down
45 changes: 32 additions & 13 deletions d/private/rules/link.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,24 @@ def link_action(ctx, d_info):
ctx: The rule context.
d_info: The DInfo provider containing the linking context.
Returns:
A File for the linked binary.
A struct with:
executable: File for the linked binary.
additional_outputs: list of TreeArtifact File objects for the
directories declared via the `link_output_dirs` attribute
(empty if none requested).
"""
additional_outputs = [
ctx.actions.declare_directory(name)
for name in getattr(ctx.attr, "link_output_dirs", [])
]
toolchain = ctx.toolchains["//d:toolchain_type"].d_toolchain_info
link_with_d = resolve_tristate_flag(ctx.attr.link_with_d, toolchain.link_with_d)
fat_lto = resolve_tristate_flag(ctx.attr.fat_lto, toolchain.fat_lto)
if link_with_d:
return link_with_d_action(ctx, d_info, fat_lto)
return struct(
executable = link_with_d_action(ctx, d_info, fat_lto, additional_outputs),
additional_outputs = additional_outputs,
)
druntime = None
mode = ctx.var["COMPILATION_MODE"]
if fat_lto:
Expand Down Expand Up @@ -63,7 +74,8 @@ def link_action(ctx, d_info):
if toolchain.linker_flags_per_mode and compilation_mode in toolchain.linker_flags_per_mode:
user_link_flags.extend(toolchain.linker_flags_per_mode[compilation_mode])

user_link_flags.extend(ctx.attr.linkopts)
# ctx.attr.linkopts is propagated via d_info.linker_flags (with location
# expansion already applied in compile.bzl). Adding it here would double-add.
user_link_flags.extend(d_info.linker_flags.to_list())

additional_inputs = []
Expand All @@ -77,13 +89,20 @@ def link_action(ctx, d_info):
additional_inputs.append(dynamic_symbols)
user_link_flags.append("-Wl,--dynamic-list=%s" % dynamic_symbols.path)

return cc_common.link(
name = ctx.label.name,
actions = ctx.actions,
feature_configuration = cc_linker_info.feature_configuration,
cc_toolchain = cc_linker_info.cc_toolchain,
compilation_outputs = compilation_outputs,
linking_contexts = linking_contexts,
user_link_flags = user_link_flags,
additional_inputs = additional_inputs,
).executable
for t in getattr(ctx.attr, "additional_linker_inputs", []):
additional_inputs.extend(t.files.to_list())

return struct(
executable = cc_common.link(
name = ctx.label.name,
actions = ctx.actions,
feature_configuration = cc_linker_info.feature_configuration,
cc_toolchain = cc_linker_info.cc_toolchain,
compilation_outputs = compilation_outputs,
linking_contexts = linking_contexts,
user_link_flags = user_link_flags,
additional_inputs = additional_inputs,
additional_outputs = additional_outputs,
).executable,
additional_outputs = additional_outputs,
)
10 changes: 7 additions & 3 deletions d/private/rules/link_with_d.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@ Action supporting old style linking using the D compiler.
load("//d/private/rules:cc_toolchain.bzl", "find_cc_toolchain_for_linking")
load("//d/private/rules:utils.bzl", "binary_name", "get_os")

def link_with_d_action(ctx, d_info, fat_lto):
def link_with_d_action(ctx, d_info, fat_lto, additional_outputs = []):
"""Action supporting old style linking using the D compiler.

Args:
ctx: The rule context.
d_info: The DInfo provider containing the linking context.
fat_lto: Whether to use fat LTO.
additional_outputs: extra File outputs (typically TreeArtifacts) to
declare on the link action so a wrapper or post-link tooling can
populate them. They are added to the action's outputs as-is — LDC
does not see them.
Returns:
A File for the linked binary.
"""
Expand Down Expand Up @@ -87,10 +91,10 @@ def link_with_d_action(ctx, d_info, fat_lto):
if get_os(ctx) != "windows":
# DMD on Windows doesn't support -Xcc=
args.add_all(cc_linker_info.cc_linking_options, format_each = "-Xcc=%s")
inputs = depset(direct = [object] + libraries + unpacked_lib_dirs)
inputs = depset(direct = [object] + libraries + unpacked_lib_dirs + ctx.files.additional_linker_inputs)
ctx.actions.run(
inputs = inputs,
outputs = [output],
outputs = [output] + additional_outputs,
executable = toolchain.d_compiler[DefaultInfo].files_to_run,
tools = [cc_linker_info.cc_toolchain.all_files],
arguments = [args],
Expand Down
4 changes: 3 additions & 1 deletion d/private/rules/test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@ load("//d/private/rules:link.bzl", "link_action")
def _d_test_impl(ctx):
"""Implementation of d_test rule."""
d_info = compilation_action(ctx, target_type = TARGET_TYPE.TEST)
output = link_action(ctx, d_info)
link_result = link_action(ctx, d_info)
output = link_result.executable
env_with_expansions = {
k: expand_variables(ctx, ctx.expand_location(v, ctx.files.data), [output], "env")
for k, v in ctx.attr.env.items()
}
return [
DefaultInfo(
executable = output,
files = depset([output] + link_result.additional_outputs),
runfiles = ctx.runfiles(files = ctx.files.data),
),
RunEnvironmentInfo(environment = env_with_expansions),
Expand Down
Loading