Skip to content
This repository was archived by the owner on Jan 25, 2024. It is now read-only.

Commit 96f0a67

Browse files
allevatoswiple-rules-gardener
authored andcommitted
Propagate Swift-specific linker flags as an implicit dependency of the toolchain.
Apple binaries/bundles will automatically get these linker flags if they have any Swift target in their dependencies; this eliminates the need to pass them separately at the top level. PiperOrigin-RevId: 378024438
1 parent bf5fccc commit 96f0a67

File tree

5 files changed

+70
-70
lines changed

5 files changed

+70
-70
lines changed

swift/internal/providers.bzl

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -165,19 +165,6 @@ linking target (but not to precompiled explicit C/Objective-C modules):
165165
166166
For ease of use, this field is never `None`; it will always be a valid `struct`
167167
containing the fields described above, even if those lists are empty.
168-
""",
169-
"linker_opts_producer": """\
170-
Skylib `partial`. A partial function that returns the flags that should be
171-
passed to Clang to link a binary or test target with the Swift runtime
172-
libraries.
173-
174-
The partial should be called with two arguments:
175-
176-
* `is_static`: A `Boolean` value indicating whether to link against the static
177-
or dynamic runtime libraries.
178-
179-
* `is_test`: A `Boolean` value indicating whether the target being linked is a
180-
test target.
181168
""",
182169
"object_format": """\
183170
`String`. The object file format of the platform that the toolchain is

swift/internal/swift_binary_test.bzl

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
"""Implementation of the `swift_binary` and `swift_test` rules."""
1616

1717
load("@bazel_skylib//lib:dicts.bzl", "dicts")
18-
load("@bazel_skylib//lib:partial.bzl", "partial")
1918
load(":compiling.bzl", "output_groups_from_compilation_outputs")
2019
load(":derived_files.bzl", "derived_files")
2120
load(":feature_names.bzl", "SWIFT_FEATURE_BUNDLED_XCTESTS")
@@ -208,16 +207,6 @@ def _swift_linking_rule_impl(
208207
compilation_outputs = compilation_outputs,
209208
)
210209

211-
# Retrieve any additional linker flags required by the Swift toolchain.
212-
# TODO(b/70228246): Also support mostly-static and fully-dynamic modes,
213-
# here and for the C++ toolchain args below.
214-
toolchain_linker_flags = partial.call(
215-
swift_toolchain.linker_opts_producer,
216-
is_static = True,
217-
is_test = is_test,
218-
)
219-
user_link_flags.extend(toolchain_linker_flags)
220-
221210
# Collect linking contexts from any of the toolchain's implicit
222211
# dependencies.
223212
for cc_info in swift_toolchain.implicit_deps_providers.cc_infos:

swift/internal/swift_toolchain.bzl

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ toolchain, see `swift.bzl`.
2020
"""
2121

2222
load("@bazel_skylib//lib:dicts.bzl", "dicts")
23-
load("@bazel_skylib//lib:partial.bzl", "partial")
2423
load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
2524
load(":actions.bzl", "swift_action_names")
2625
load(":attrs.bzl", "swift_toolchain_driver_attrs")
@@ -107,37 +106,33 @@ def _all_action_configs(additional_swiftc_copts):
107106
autolink_extract_action_configs()
108107
)
109108

110-
def _default_linker_opts(
109+
def _swift_linkopts_cc_info(
111110
cc_toolchain,
112111
cpu,
113112
os,
114-
toolchain_root,
115-
is_static,
116-
is_test):
117-
"""Returns options that should be passed by default to `clang` when linking.
113+
toolchain_label,
114+
toolchain_root):
115+
"""Returns a `CcInfo` containing flags that should be passed to the linker.
118116
119-
This function is wrapped in a `partial` that will be propagated as part of
120-
the toolchain provider. The first three arguments are pre-bound; the
121-
`is_static` and `is_test` arguments are expected to be passed by the caller.
117+
The provider returned by this function will be used as an implicit
118+
dependency of the toolchain to ensure that any binary containing Swift code
119+
will link to the standard libraries correctly.
122120
123121
Args:
124122
cc_toolchain: The cpp toolchain from which the `ld` executable is
125123
determined.
126124
cpu: The CPU architecture, which is used as part of the library path.
127125
os: The operating system name, which is used as part of the library
128126
path.
127+
toolchain_label: The label of the Swift toolchain that will act as the
128+
owner of the linker input propagating the flags.
129129
toolchain_root: The toolchain's root directory.
130-
is_static: `True` to link against the static version of the Swift
131-
runtime, or `False` to link against dynamic/shared libraries.
132-
is_test: `True` if the target being linked is a test target.
133130
134131
Returns:
135-
The command line options to pass to `clang` to link against the desired
136-
variant of the Swift runtime libraries.
132+
A `CcInfo` provider that will provide linker flags to binaries that
133+
depend on Swift targets.
137134
"""
138135

139-
_ignore = is_test
140-
141136
# TODO(#8): Support statically linking the Swift runtime.
142137
platform_lib_dir = "{toolchain_root}/lib/swift/{os}".format(
143138
os = os,
@@ -158,22 +153,29 @@ def _default_linker_opts(
158153
"-lrt",
159154
"-ldl",
160155
runtime_object_path,
156+
"-static-libgcc",
161157
]
162158

163-
if is_static:
164-
linkopts.append("-static-libgcc")
165-
166-
return linkopts
159+
return CcInfo(
160+
linking_context = cc_common.create_linking_context(
161+
linker_inputs = depset([
162+
cc_common.create_linker_input(
163+
owner = toolchain_label,
164+
user_link_flags = depset(linkopts),
165+
),
166+
]),
167+
),
168+
)
167169

168170
def _swift_toolchain_impl(ctx):
169171
toolchain_root = ctx.attr.root
170172
cc_toolchain = find_cpp_toolchain(ctx)
171173

172-
linker_opts_producer = partial.make(
173-
_default_linker_opts,
174+
swift_linkopts_cc_info = _swift_linkopts_cc_info(
174175
cc_toolchain,
175176
ctx.attr.arch,
176177
ctx.attr.os,
178+
ctx.label,
177179
toolchain_root,
178180
)
179181

@@ -223,10 +225,10 @@ def _swift_toolchain_impl(ctx):
223225
generated_header_module_implicit_deps_providers = (
224226
collect_implicit_deps_providers([])
225227
),
226-
implicit_deps_providers = (
227-
collect_implicit_deps_providers([])
228+
implicit_deps_providers = collect_implicit_deps_providers(
229+
[],
230+
additional_cc_infos = [swift_linkopts_cc_info],
228231
),
229-
linker_opts_producer = linker_opts_producer,
230232
object_format = "elf",
231233
requested_features = requested_features,
232234
root_dir = toolchain_root,

swift/internal/utils.bzl

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,21 @@ def collect_cc_libraries(
5959

6060
return libraries
6161

62-
def collect_implicit_deps_providers(targets):
62+
def collect_implicit_deps_providers(
63+
targets,
64+
additional_cc_infos = [],
65+
additional_objc_infos = []):
6366
"""Returns a struct with important providers from a list of implicit deps.
6467
6568
Note that the relationship between each provider in the list and the target
6669
it originated from is no longer retained.
6770
6871
Args:
6972
targets: A list (possibly empty) of `Target`s.
73+
additional_cc_infos: A `list` of additional `CcInfo` providers that
74+
should be included in the returned value.
75+
additional_objc_infos: A `list` of additional `apple_common.Objc`
76+
providers that should be included in the returned value.
7077
7178
Returns:
7279
A `struct` containing three fields:
@@ -90,8 +97,8 @@ def collect_implicit_deps_providers(targets):
9097
swift_infos.append(target[SwiftInfo])
9198

9299
return struct(
93-
cc_infos = cc_infos,
94-
objc_infos = objc_infos,
100+
cc_infos = cc_infos + additional_cc_infos,
101+
objc_infos = objc_infos + additional_objc_infos,
95102
swift_infos = swift_infos,
96103
)
97104

swift/internal/xcode_swift_toolchain.bzl

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -172,33 +172,35 @@ def _sdk_developer_framework_dir(apple_toolchain, apple_fragment, xcode_config):
172172

173173
return paths.join(apple_toolchain.sdk_dir(), "Developer/Library/Frameworks")
174174

175-
def _default_linker_opts(
175+
def _swift_linkopts_providers(
176176
apple_fragment,
177177
apple_toolchain,
178178
platform,
179179
target,
180-
xcode_config,
181-
is_static,
182-
is_test):
183-
"""Returns options that should be passed by default to `clang` when linking.
180+
toolchain_label,
181+
xcode_config):
182+
"""Returns providers containing flags that should be passed to the linker.
184183
185-
This function is wrapped in a `partial` that will be propagated as part of
186-
the toolchain provider. The first five arguments are pre-bound; the
187-
`is_static` and `is_test` arguments are expected to be passed by the caller.
184+
The providers returned by this function will be used as implicit
185+
dependencies of the toolchain to ensure that any binary containing Swift code
186+
will link to the standard libraries correctly.
188187
189188
Args:
190189
apple_fragment: The `apple` configuration fragment.
191190
apple_toolchain: The `apple_common.apple_toolchain()` object.
192191
platform: The `apple_platform` value describing the target platform.
193192
target: The target triple.
193+
toolchain_label: The label of the Swift toolchain that will act as the
194+
owner of the linker input propagating the flags.
194195
xcode_config: The Xcode configuration.
195-
is_static: `True` to link against the static version of the Swift
196-
runtime, or `False` to link against dynamic/shared libraries.
197-
is_test: `True` if the target being linked is a test target.
198196
199197
Returns:
200-
The command line options to pass to `clang` to link against the desired
201-
variant of the Swift runtime libraries.
198+
A `struct` containing the following fields:
199+
200+
* `cc_info`: A `CcInfo` provider that will provide linker flags to
201+
binaries that depend on Swift targets.
202+
* `objc_info`: An `apple_common.Objc` provider that will provide
203+
linker flags to binaries that depend on Swift targets.
202204
"""
203205
platform_developer_framework_dir = _platform_developer_framework_dir(
204206
apple_toolchain,
@@ -241,15 +243,27 @@ def _default_linker_opts(
241243
# So, we need to explicitly add that to test binaries' rpaths. We also need
242244
# to add the linker path to the directory containing the dylib with Swift
243245
# extensions for the XCTest module.
244-
if is_test and platform_developer_framework_dir:
246+
if platform_developer_framework_dir:
245247
linkopts.extend([
246248
"-Wl,-rpath,{}".format(platform_developer_framework_dir),
247249
"-L{}".format(
248250
_swift_developer_lib_dir(platform_developer_framework_dir),
249251
),
250252
])
251253

252-
return linkopts
254+
return struct(
255+
cc_info = CcInfo(
256+
linking_context = cc_common.create_linking_context(
257+
linker_inputs = depset([
258+
cc_common.create_linker_input(
259+
owner = toolchain_label,
260+
user_link_flags = depset(linkopts),
261+
),
262+
]),
263+
),
264+
),
265+
objc_info = apple_common.new_objc_provider(linkopt = depset(linkopts)),
266+
)
253267

254268
def _features_for_bitcode_mode(bitcode_mode):
255269
"""Gets the list of features to enable for the selected Bitcode mode.
@@ -590,12 +604,12 @@ def _xcode_swift_toolchain_impl(ctx):
590604
)
591605
target = _swift_apple_target_triple(cpu, platform, target_os_version)
592606

593-
linker_opts_producer = partial.make(
594-
_default_linker_opts,
607+
swift_linkopts_providers = _swift_linkopts_providers(
595608
apple_fragment,
596609
apple_toolchain,
597610
platform,
598611
target,
612+
ctx.label,
599613
xcode_config,
600614
)
601615

@@ -698,8 +712,9 @@ def _xcode_swift_toolchain_impl(ctx):
698712
),
699713
implicit_deps_providers = collect_implicit_deps_providers(
700714
ctx.attr.implicit_deps,
715+
additional_cc_infos = [swift_linkopts_providers.cc_info],
716+
additional_objc_infos = [swift_linkopts_providers.objc_info],
701717
),
702-
linker_opts_producer = linker_opts_producer,
703718
object_format = "macho",
704719
requested_features = requested_features,
705720
supports_objc_interop = True,

0 commit comments

Comments
 (0)