Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support swift_{binary,test} generating a .dSYM bundle as an output when --apple_generate_dsym is set #1327

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
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