Skip to content

Commit

Permalink
Support swift_{binary,test} generating a .dSYM bundle as an outpu…
Browse files Browse the repository at this point in the history
…t when `--apple_generate_dsym` is set

PiperOrigin-RevId: 478074024
(cherry picked from commit 98de95c)
Signed-off-by: Brentley Jones <github@brentleyjones.com>
  • Loading branch information
allevato authored and brentleyjones committed Oct 2, 2024
1 parent c0644db commit 9e529a9
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 9 deletions.
10 changes: 6 additions & 4 deletions doc/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,11 @@ Propagates Swift-specific information about a `proto_library`.

<pre>
SwiftToolchainInfo(<a href="#SwiftToolchainInfo-action_configs">action_configs</a>, <a href="#SwiftToolchainInfo-cc_toolchain_info">cc_toolchain_info</a>, <a href="#SwiftToolchainInfo-clang_implicit_deps_providers">clang_implicit_deps_providers</a>,
<a href="#SwiftToolchainInfo-const_protocols_to_gather">const_protocols_to_gather</a>, <a href="#SwiftToolchainInfo-developer_dirs">developer_dirs</a>, <a href="#SwiftToolchainInfo-entry_point_linkopts_provider">entry_point_linkopts_provider</a>,
<a href="#SwiftToolchainInfo-feature_allowlists">feature_allowlists</a>, <a href="#SwiftToolchainInfo-generated_header_module_implicit_deps_providers">generated_header_module_implicit_deps_providers</a>,
<a href="#SwiftToolchainInfo-implicit_deps_providers">implicit_deps_providers</a>, <a href="#SwiftToolchainInfo-package_configurations">package_configurations</a>, <a href="#SwiftToolchainInfo-requested_features">requested_features</a>, <a href="#SwiftToolchainInfo-root_dir">root_dir</a>,
<a href="#SwiftToolchainInfo-swift_worker">swift_worker</a>, <a href="#SwiftToolchainInfo-test_configuration">test_configuration</a>, <a href="#SwiftToolchainInfo-tool_configs">tool_configs</a>, <a href="#SwiftToolchainInfo-unsupported_features">unsupported_features</a>)
<a href="#SwiftToolchainInfo-const_protocols_to_gather">const_protocols_to_gather</a>, <a href="#SwiftToolchainInfo-debug_outputs_provider">debug_outputs_provider</a>, <a href="#SwiftToolchainInfo-developer_dirs">developer_dirs</a>,
<a href="#SwiftToolchainInfo-entry_point_linkopts_provider">entry_point_linkopts_provider</a>, <a href="#SwiftToolchainInfo-feature_allowlists">feature_allowlists</a>,
<a href="#SwiftToolchainInfo-generated_header_module_implicit_deps_providers">generated_header_module_implicit_deps_providers</a>, <a href="#SwiftToolchainInfo-implicit_deps_providers">implicit_deps_providers</a>,
<a href="#SwiftToolchainInfo-package_configurations">package_configurations</a>, <a href="#SwiftToolchainInfo-requested_features">requested_features</a>, <a href="#SwiftToolchainInfo-root_dir">root_dir</a>, <a href="#SwiftToolchainInfo-swift_worker">swift_worker</a>,
<a href="#SwiftToolchainInfo-test_configuration">test_configuration</a>, <a href="#SwiftToolchainInfo-tool_configs">tool_configs</a>, <a href="#SwiftToolchainInfo-unsupported_features">unsupported_features</a>)
</pre>

Propagates information about a Swift toolchain to compilation and linking rules
Expand All @@ -102,6 +103,7 @@ that use the toolchain.
| <a id="SwiftToolchainInfo-cc_toolchain_info"></a>cc_toolchain_info | The `cc_common.CcToolchainInfo` provider from the Bazel C++ toolchain that this Swift toolchain depends on. |
| <a id="SwiftToolchainInfo-clang_implicit_deps_providers"></a>clang_implicit_deps_providers | A `struct` with the following fields, which represent providers from targets that should be added as implicit dependencies of any precompiled explicit C/Objective-C modules:<br><br>* `cc_infos`: A list of `CcInfo` providers from targets specified as the toolchain's implicit dependencies. * `objc_infos`: A list of `apple_common.Objc` providers from targets specified as the toolchain's implicit dependencies. * `swift_infos`: A list of `SwiftInfo` providers from targets specified as the toolchain's implicit dependencies.<br><br>For ease of use, this field is never `None`; it will always be a valid `struct` containing the fields described above, even if those lists are empty. |
| <a id="SwiftToolchainInfo-const_protocols_to_gather"></a>const_protocols_to_gather | `File`. A JSON file specifying a list of protocols for extraction of conformances' const values. |
| <a id="SwiftToolchainInfo-debug_outputs_provider"></a>debug_outputs_provider | An optional function that provides toolchain-specific logic around the handling of additional debug outputs for `swift_binary` and `swift_test` targets. If specified, this function must take the following keyword arguments: * `ctx`: The rule context of the calling binary or test rule. It must return a `struct` with the following fields: * `additional_outputs`: Additional outputs expected from the linking action. * `variables_extension`: A dictionary of additional crosstool variables to pass to the linking action. |
| <a id="SwiftToolchainInfo-developer_dirs"></a>developer_dirs | A list of `structs` containing the following fields:* `developer_path_label`: A `string` representing the type of developer path. * `path`: A `string` representing the path to the developer framework. |
| <a id="SwiftToolchainInfo-entry_point_linkopts_provider"></a>entry_point_linkopts_provider | A function that returns flags that should be passed to the linker to control the name of the entry point of a linked binary for rules that customize their entry point. This function must take the following keyword arguments: * `entry_point_name`: The name of the entry point function, as was passed to the Swift compiler using the `-entry-point-function-name` flag. It must return a `struct` with the following fields: * `linkopts`: A list of strings that will be passed as additional linker flags when linking a binary with a custom entry point. |
| <a id="SwiftToolchainInfo-feature_allowlists"></a>feature_allowlists | A list of `SwiftFeatureAllowlistInfo` providers that allow or prohibit packages from requesting or disabling features. |
Expand Down
17 changes: 13 additions & 4 deletions swift/internal/linking.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -568,19 +568,22 @@ def new_objc_provider(
return apple_common.new_objc_provider(**kwargs)

def register_link_binary_action(
*,
actions,
additional_inputs,
additional_linking_contexts,
additional_inputs = [],
additional_linking_contexts = [],
additional_outputs = [],
compilation_outputs,
deps,
feature_configuration,
name,
module_contexts,
module_contexts = [],
output_type,
owner,
stamp,
swift_toolchain,
user_link_flags):
user_link_flags = [],
variables_extension = {}):
"""Registers an action that invokes the linker to produce a binary.
Args:
Expand All @@ -590,6 +593,8 @@ 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.
additional_outputs: Additional files that are outputs of the linking
action but which are not among the return value of `cc_common.link`.
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
Expand All @@ -611,6 +616,8 @@ def register_link_binary_action(
user_link_flags: Additional flags passed to the linker. Any
`$(location ...)` placeholders are assumed to have already been
expanded.
variables_extension: A dictionary containing additional crosstool
variables that should be set for the linking action.
Returns:
A `CcLinkingOutputs` object that contains the `executable` or
Expand Down Expand Up @@ -749,6 +756,7 @@ def register_link_binary_action(
return cc_common.link(
actions = actions,
additional_inputs = additional_inputs,
additional_outputs = additional_outputs,
cc_toolchain = swift_toolchain.cc_toolchain_info,
compilation_outputs = compilation_outputs,
feature_configuration = get_cc_feature_configuration(
Expand All @@ -760,4 +768,5 @@ def register_link_binary_action(
link_deps_statically = True,
output_type = output_type,
stamp = stamp,
variables_extension = variables_extension,
)
10 changes: 10 additions & 0 deletions swift/providers.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,16 @@ containing the fields described above, even if those lists are empty.
"const_protocols_to_gather": """\
`File`. A JSON file specifying a list of protocols for extraction of
conformances' const values.
""",
"debug_outputs_provider": """\
An optional function that provides toolchain-specific logic around the handling
of additional debug outputs for `swift_binary` and `swift_test` targets.
If specified, this function must take the following keyword arguments:
* `ctx`: The rule context of the calling binary or test rule.
It must return a `struct` with the following fields:
* `additional_outputs`: Additional outputs expected from the linking action.
* `variables_extension`: A dictionary of additional crosstool variables to
pass to the linking action.
""",
"developer_dirs": """
A list of `structs` containing the following fields:\
Expand Down
16 changes: 16 additions & 0 deletions swift/swift_binary.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,17 @@ def _swift_binary_impl(ctx):

additional_linking_contexts.append(malloc_linking_context(ctx))

# Apply the optional debugging outputs extension if the toolchain defines
# one.
debug_outputs_provider = swift_toolchain.debug_outputs_provider
if debug_outputs_provider:
debug_extension = debug_outputs_provider(ctx = ctx)
additional_debug_outputs = debug_extension.additional_outputs
variables_extension = debug_extension.variables_extension
else:
additional_debug_outputs = []
variables_extension = {}

if swift_common.is_enabled(
feature_configuration = feature_configuration,
feature_name = SWIFT_FEATURE_ADD_TARGET_NAME_TO_OUTPUT,
Expand All @@ -128,6 +139,7 @@ def _swift_binary_impl(ctx):
actions = ctx.actions,
additional_inputs = ctx.files.swiftc_inputs,
additional_linking_contexts = additional_linking_contexts,
additional_outputs = additional_debug_outputs,
feature_configuration = feature_configuration,
compilation_outputs = compilation_outputs,
deps = ctx.attr.deps,
Expand All @@ -142,11 +154,15 @@ def _swift_binary_impl(ctx):
ctx.attr.linkopts,
ctx.attr.swiftc_inputs,
) + ctx.fragments.cpp.linkopts,
variables_extension = variables_extension,
)

return [
DefaultInfo(
executable = linking_outputs.executable,
files = depset(
[linking_outputs.executable] + additional_debug_outputs,
),
runfiles = ctx.runfiles(
collect_data = True,
collect_default = True,
Expand Down
18 changes: 17 additions & 1 deletion swift/swift_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,17 @@ def _swift_test_impl(ctx):
# Mach-O type `MH_BUNDLE` instead of `MH_EXECUTE`.
extra_linkopts = ["-Wl,-bundle"] if is_bundled else []

# Apply the optional debugging outputs extension if the toolchain defines
# one.
debug_outputs_provider = swift_toolchain.debug_outputs_provider
if debug_outputs_provider:
debug_extension = debug_outputs_provider(ctx = ctx)
additional_debug_outputs = debug_extension.additional_outputs
variables_extension = debug_extension.variables_extension
else:
additional_debug_outputs = []
variables_extension = {}

if swift_common.is_enabled(
feature_configuration = feature_configuration,
feature_name = SWIFT_FEATURE_ADD_TARGET_NAME_TO_OUTPUT,
Expand All @@ -506,6 +517,7 @@ def _swift_test_impl(ctx):
actions = ctx.actions,
additional_inputs = ctx.files.swiftc_inputs,
additional_linking_contexts = additional_linking_contexts,
additional_outputs = additional_debug_outputs,
compilation_outputs = compilation_outputs,
deps = all_deps,
feature_configuration = feature_configuration,
Expand All @@ -520,6 +532,7 @@ def _swift_test_impl(ctx):
ctx.attr.linkopts,
ctx.attr.swiftc_inputs,
) + extra_linkopts + ctx.fragments.cpp.linkopts,
variables_extension = variables_extension,
)

# If the tests are to be bundled, create the bundle and the test runner
Expand Down Expand Up @@ -552,7 +565,10 @@ def _swift_test_impl(ctx):
return [
DefaultInfo(
executable = executable,
files = depset(direct = [executable] + additional_test_outputs),
files = depset(
[executable] + additional_test_outputs +
additional_debug_outputs,
),
runfiles = ctx.runfiles(
collect_data = True,
collect_default = True,
Expand Down
1 change: 1 addition & 0 deletions swift/toolchains/swift_toolchain.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,7 @@ def _swift_toolchain_impl(ctx):
clang_implicit_deps_providers = (
collect_implicit_deps_providers([])
),
debug_outputs_provider = None,
developer_dirs = [],
entry_point_linkopts_provider = _entry_point_linkopts_provider,
feature_allowlists = [
Expand Down
24 changes: 24 additions & 0 deletions swift/toolchains/xcode_swift_toolchain.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,25 @@ def _entry_point_linkopts_provider(*, entry_point_name):
linkopts = ["-Wl,-alias,_{},_main".format(entry_point_name)],
)

def _dsym_provider(*, ctx):
"""Apple-specific linking extension to generate .dSYM binaries.
This extension generates a minimal dSYM bundle that LLDB can find next to
the built binary.
"""
dsym_file = ctx.actions.declare_file(
"{name}.dSYM/Contents/Resources/DWARF/{name}".format(
name = ctx.label.name,
),
)
variables_extension = {
"dsym_path": dsym_file.path,
}
return struct(
additional_outputs = [dsym_file],
variables_extension = variables_extension,
)

def _xcode_swift_toolchain_impl(ctx):
cpp_fragment = ctx.fragments.cpp
apple_toolchain = apple_common.apple_toolchain()
Expand Down Expand Up @@ -778,6 +797,11 @@ def _xcode_swift_toolchain_impl(ctx):
target[SwiftFeatureAllowlistInfo]
for target in ctx.attr.feature_allowlists
],
debug_outputs_provider = (
# This function unconditionally declares the output file, so we
# should only use it if a .dSYM is being requested during the build.
_dsym_provider if cpp_fragment.apple_generate_dsym else None
),
generated_header_module_implicit_deps_providers = (
collect_implicit_deps_providers(
ctx.attr.generated_header_module_implicit_deps,
Expand Down

0 comments on commit 9e529a9

Please sign in to comment.