Skip to content

Commit

Permalink
Fix LLDB expr evaluation for swift_{binary,test} targets only conta…
Browse files Browse the repository at this point in the history
…ining Swift in their `srcs`.

The `.swiftmodule` resulting from compilation of the target's sources was being ignored (since it cannot be a dependency of anything else), but it needs to be embedded as with any other `.swiftmodule` in order for LLDB to find it and initialize the AST context properly.

PiperOrigin-RevId: 477544434
  • Loading branch information
allevato authored and swiple-rules-gardener committed Sep 28, 2022
1 parent bead123 commit c0cdb8b
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 45 deletions.
1 change: 1 addition & 0 deletions swift/internal/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ bzl_library(
":actions",
":feature_names",
":features",
"@bazel_skylib//lib:paths",
],
)

Expand Down
3 changes: 2 additions & 1 deletion swift/internal/debugging.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ load(
"SWIFT_FEATURE_NO_EMBED_DEBUG_MODULE",
)
load(":features.bzl", "is_feature_enabled")
load("@bazel_skylib//lib:paths.bzl", "paths")

def ensure_swiftmodule_is_embedded(
actions,
Expand Down Expand Up @@ -60,7 +61,7 @@ def ensure_swiftmodule_is_embedded(
# to wrap the .swiftmodule file in a .o file that gets propagated to the
# linker.
modulewrap_obj = actions.declare_file(
"{}.modulewrap.o".format(label.name),
paths.replace_extension(swiftmodule.basename, ".modulewrap.o"),
)
prerequisites = struct(
object_file = modulewrap_obj,
Expand Down
115 changes: 83 additions & 32 deletions swift/internal/linking.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,55 @@ def configure_features_for_binary(
unsupported_features = unsupported_features,
)

def _create_embedded_debugging_linking_context(
*,
actions,
feature_configuration,
label,
module_context,
swift_toolchain):
"""Creates a linking context that embeds a .swiftmodule for debugging.
Args:
actions: The context's `actions` object.
feature_configuration: A feature configuration obtained from
`swift_common.configure_features`.
label: The `Label` of the target being built. This is used as the owner
of the linker inputs created for post-compile actions (if any), and
the label's name component also determines the name of the artifact
unless it is overridden by the `name` argument.
module_context: The module context returned by `swift_common.compile`
containing information about the Swift module that was compiled.
Typically, this is the first tuple element in the value returned by
`swift_common.compile`.
swift_toolchain: The `SwiftToolchainInfo` provider of the toolchain.
Returns:
A valid `CcLinkingContext`, or `None` if no linking context was created.
"""
if (
module_context and
module_context.swift and
should_embed_swiftmodule_for_debugging(
feature_configuration = feature_configuration,
module_context = module_context,
)
):
post_compile_linker_inputs = [
ensure_swiftmodule_is_embedded(
actions = actions,
feature_configuration = feature_configuration,
label = label,
swiftmodule = module_context.swift.swiftmodule,
swift_toolchain = swift_toolchain,
),
]
return cc_common.create_linking_context(
linker_inputs = depset(post_compile_linker_inputs),
)

return None

def create_linking_context_from_compilation_outputs(
*,
actions,
Expand Down Expand Up @@ -213,30 +262,15 @@ def create_linking_context_from_compilation_outputs(
for cc_info in swift_toolchain.implicit_deps_providers.cc_infos
]

if module_context and module_context.swift:
post_compile_linker_inputs = []

# Ensure that the .swiftmodule file is embedded in the final library or
# binary for debugging purposes.
if should_embed_swiftmodule_for_debugging(
feature_configuration = feature_configuration,
module_context = module_context,
):
post_compile_linker_inputs.append(
ensure_swiftmodule_is_embedded(
actions = actions,
feature_configuration = feature_configuration,
label = label,
swiftmodule = module_context.swift.swiftmodule,
swift_toolchain = swift_toolchain,
),
)

extra_linking_contexts.append(
cc_common.create_linking_context(
linker_inputs = depset(post_compile_linker_inputs),
),
)
debugging_linking_context = _create_embedded_debugging_linking_context(
actions = actions,
feature_configuration = feature_configuration,
label = label,
module_context = module_context,
swift_toolchain = swift_toolchain,
)
if debugging_linking_context:
extra_linking_contexts.append(debugging_linking_context)

if not name:
name = label.name
Expand Down Expand Up @@ -368,11 +402,12 @@ def register_link_binary_action(
actions,
additional_inputs,
additional_linking_contexts,
cc_feature_configuration,
compilation_outputs,
deps,
feature_configuration,
grep_includes,
name,
label,
module_contexts,
output_type,
owner,
stamp,
Expand All @@ -387,15 +422,18 @@ def register_link_binary_action(
scripts, and so forth.
additional_linking_contexts: Additional linking contexts that provide
libraries or flags that should be linked into the executable.
cc_feature_configuration: The C++ feature configuration to use when
constructing the action.
compilation_outputs: A `CcCompilationOutputs` object containing object
files that will be passed to the linker.
deps: A list of targets representing additional libraries that will be
passed to the linker.
feature_configuration: The Swift feature configuration.
grep_includes: Used internally only.
name: The name of the target being linked, which is used to derive the
output artifact.
label: The label of the target being linked, whose name is used to
derive the output artifact.
module_contexts: A list of module contexts resulting from the
compilation of the sources in the binary target, which are embedded
in the binary for debugging if this is a debug build. This list may
be empty if the target had no sources of its own.
output_type: A string indicating the output type; "executable" or
"dynamic_library".
owner: The `Label` of the target that owns this linker input.
Expand Down Expand Up @@ -455,6 +493,17 @@ def register_link_binary_action(

linking_contexts.extend(additional_linking_contexts)

for module_context in module_contexts:
debugging_linking_context = _create_embedded_debugging_linking_context(
actions = actions,
feature_configuration = feature_configuration,
label = label,
module_context = module_context,
swift_toolchain = swift_toolchain,
)
if debugging_linking_context:
linking_contexts.append(debugging_linking_context)

# Collect linking contexts from any of the toolchain's implicit
# dependencies.
linking_contexts.extend([
Expand All @@ -467,9 +516,11 @@ def register_link_binary_action(
additional_inputs = additional_inputs,
cc_toolchain = swift_toolchain.cc_toolchain_info,
compilation_outputs = compilation_outputs,
feature_configuration = cc_feature_configuration,
feature_configuration = get_cc_feature_configuration(
feature_configuration,
),
grep_includes = grep_includes,
name = name,
name = label.name,
user_link_flags = user_link_flags,
linking_contexts = linking_contexts,
link_deps_statically = True,
Expand Down
11 changes: 5 additions & 6 deletions swift/swift_binary.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ def _swift_binary_impl(ctx):

srcs = ctx.files.srcs
output_groups = {}
module_contexts = []

# If the binary has sources, compile those first and collect the outputs to
# be passed to the linker.
Expand All @@ -71,6 +72,7 @@ def _swift_binary_impl(ctx):
swift_toolchain = swift_toolchain,
target_name = ctx.label.name,
)
module_contexts.append(compile_result.module_context)
compilation_outputs = compile_result.compilation_outputs
supplemental_outputs = compile_result.supplemental_outputs

Expand All @@ -81,19 +83,16 @@ def _swift_binary_impl(ctx):
else:
compilation_outputs = cc_common.create_compilation_outputs()

cc_feature_configuration = swift_common.cc_feature_configuration(
feature_configuration = feature_configuration,
)

linking_outputs = register_link_binary_action(
actions = ctx.actions,
additional_inputs = ctx.files.swiftc_inputs,
additional_linking_contexts = [malloc_linking_context(ctx)],
cc_feature_configuration = cc_feature_configuration,
feature_configuration = feature_configuration,
compilation_outputs = compilation_outputs,
deps = ctx.attr.deps,
grep_includes = ctx.file._grep_includes,
name = ctx.label.name,
label = ctx.label,
module_contexts = module_contexts,
output_type = "executable",
owner = ctx.label,
stamp = ctx.attr.stamp,
Expand Down
13 changes: 7 additions & 6 deletions swift/swift_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,8 @@ def _swift_test_impl(ctx):
if not module_name:
module_name = swift_common.derive_module_name(ctx.label)

module_contexts = []

if srcs:
# If the `swift_test` target had sources, compile those first and then
# extract a symbol graph from it.
Expand All @@ -322,6 +324,7 @@ def _swift_test_impl(ctx):
swift_toolchain = swift_toolchain,
)

module_contexts.append(compile_result.module_context)
compilation_outputs = compile_result.compilation_outputs
supplemental_outputs = compile_result.supplemental_outputs

Expand Down Expand Up @@ -379,6 +382,7 @@ def _swift_test_impl(ctx):
swift_infos = swift_infos_including_owner,
swift_toolchain = swift_toolchain,
)
module_contexts.append(discovery_compile_result.module_context)
compilation_outputs = cc_common.merge_compilation_outputs(
compilation_outputs = [
compilation_outputs,
Expand All @@ -393,10 +397,6 @@ def _swift_test_impl(ctx):
discovery_supplemental_outputs.indexstore_directory,
])

cc_feature_configuration = swift_common.cc_feature_configuration(
feature_configuration = feature_configuration,
)

# If we need to run the test in an .xctest bundle, the binary must have
# Mach-O type `MH_BUNDLE` instead of `MH_EXECUTE`.
extra_linkopts = ["-Wl,-bundle"] if is_bundled else []
Expand All @@ -405,11 +405,12 @@ def _swift_test_impl(ctx):
actions = ctx.actions,
additional_inputs = ctx.files.swiftc_inputs,
additional_linking_contexts = [malloc_linking_context(ctx)],
cc_feature_configuration = cc_feature_configuration,
compilation_outputs = compilation_outputs,
deps = all_deps,
feature_configuration = feature_configuration,
grep_includes = ctx.file._grep_includes,
name = ctx.label.name,
label = ctx.label,
module_contexts = module_contexts,
output_type = "executable",
owner = ctx.label,
stamp = ctx.attr.stamp,
Expand Down

1 comment on commit c0cdb8b

@brentleyjones
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.