Skip to content

Commit ccddf99

Browse files
Allow to opt-out from library evolution (#2484)
As the title says. A followup on #2401 (closed as I reorganised my fork a bit).
1 parent 0309ba6 commit ccddf99

File tree

5 files changed

+81
-22
lines changed

5 files changed

+81
-22
lines changed

apple/internal/partials/swift_framework.bzl

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,25 @@ issue with a reproducible error case.
7070

7171
found_module_name = swift_module.name
7272

73-
bundle_interface = swift_info_support.declare_swiftinterface(
74-
actions = actions,
75-
arch = arch,
76-
label_name = label_name,
77-
output_discriminator = output_discriminator,
78-
swiftinterface = swift_module.swift.swiftinterface,
79-
)
80-
bundle_files.append((processor.location.bundle, modules_parent, depset([bundle_interface])))
73+
# A swiftinterface will not be present when library evolution is disabled, if so, fallback to swiftmodule.
74+
if swift_module.swift.swiftinterface:
75+
bundle_interface = swift_info_support.declare_swiftinterface(
76+
actions = actions,
77+
arch = arch,
78+
label_name = label_name,
79+
output_discriminator = output_discriminator,
80+
swiftinterface = swift_module.swift.swiftinterface,
81+
)
82+
bundle_files.append((processor.location.bundle, modules_parent, depset([bundle_interface])))
83+
else:
84+
bundle_swiftmodule = swift_info_support.declare_swiftmodule(
85+
actions = actions,
86+
arch = arch,
87+
label_name = label_name,
88+
output_discriminator = output_discriminator,
89+
swiftmodule = swift_module.swift.swiftmodule,
90+
)
91+
bundle_files.append((processor.location.bundle, modules_parent, depset([bundle_swiftmodule])))
8192

8293
bundle_doc = swift_info_support.declare_swiftdoc(
8394
actions = actions,

apple/internal/swift_info_support.bzl

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ swift_library dependencies.\
8181
""",
8282
)
8383

84-
if not all([module.name, module.swift.swiftdoc, module.swift.swiftinterface]):
84+
if not all([module.name, module.swift.swiftdoc]) or not (module.swift.swiftmodule or module.swift.swiftinterface):
8585
fail(
8686
"""\
8787
error: Could not find all required artifacts and information to build a Swift framework. \
@@ -246,6 +246,38 @@ def _declare_swiftinterface(
246246
)
247247
return bundle_interface
248248

249+
def _declare_swiftmodule(
250+
*,
251+
actions,
252+
arch,
253+
label_name,
254+
output_discriminator,
255+
swiftmodule):
256+
"""Declares the swiftmodule for this Swift framework.
257+
258+
Args:
259+
actions: The actions provider from `ctx.actions`.
260+
arch: The cpu architecture that the generated swiftdoc belongs to.
261+
label_name: Name of the target being built.
262+
output_discriminator: A string to differentiate between different target intermediate files
263+
or `None`.
264+
swiftmodule: A File referencing the swiftmodule file from a SwiftInfo provider.
265+
266+
Returns:
267+
A File referencing the intermediate swiftmodule.
268+
"""
269+
bundle_module = intermediates.file(
270+
actions = actions,
271+
target_name = label_name,
272+
output_discriminator = output_discriminator,
273+
file_name = "{}.swiftmodule".format(arch),
274+
)
275+
actions.symlink(
276+
target_file = swiftmodule,
277+
output = bundle_module,
278+
)
279+
return bundle_module
280+
249281
swift_info_support = struct(
250282
verify_found_module_name = _verify_found_module_name,
251283
modules_from_avoid_deps = _modules_from_avoid_deps,
@@ -254,4 +286,5 @@ swift_info_support = struct(
254286
declare_generated_header = _declare_generated_header,
255287
declare_swiftdoc = _declare_swiftdoc,
256288
declare_swiftinterface = _declare_swiftinterface,
289+
declare_swiftmodule = _declare_swiftmodule,
257290
)

apple/internal/transition_support.bzl

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ def _resolved_environment_arch_for_arch(*, arch, environment, platform_type):
320320

321321
def _command_line_options_for_xcframework_platform(
322322
*,
323+
attr,
323324
minimum_os_version,
324325
platform_attr,
325326
platform_type,
@@ -328,6 +329,7 @@ def _command_line_options_for_xcframework_platform(
328329
"""Generates a dictionary of command line options keyed by 1:2+ transition for this platform.
329330
330331
Args:
332+
attr: The attributes passed to the transition function.
331333
minimum_os_version: A string representing the minimum OS version specified for this
332334
platform, represented as a dotted version number (for example, `"9.0"`).
333335
platform_attr: The attribute for the apple platform specifying in dictionary form which
@@ -361,7 +363,10 @@ def _command_line_options_for_xcframework_platform(
361363
environment = target_environment,
362364
platform_type = platform_type,
363365
): _command_line_options(
364-
emit_swiftinterface = True,
366+
emit_swiftinterface = _should_emit_swiftinterface(
367+
attr,
368+
is_xcframework = True,
369+
),
365370
environment_arch = resolved_environment_arch,
366371
minimum_os_version = minimum_os_version,
367372
platform_type = platform_type,
@@ -372,11 +377,28 @@ def _command_line_options_for_xcframework_platform(
372377

373378
return output_dictionary
374379

380+
def _should_emit_swiftinterface(attr, is_xcframework = False):
381+
"""Determines if a .swiftinterface file should be generated for Swift dependencies.
382+
383+
Needed until users of the framework rules are allowed to enable
384+
library evolution on specific targets instead of having it automatically
385+
applied to the entire dependency subgraph.
386+
"""
387+
388+
features = getattr(attr, "features", [])
389+
if type(features) == "list" and "apple.no_legacy_swiftinterface" in features:
390+
return False
391+
392+
# iOS and tvOS static frameworks require underlying swift_library targets generate a Swift
393+
# interface file. These rules define a private attribute called `_emitswiftinterface` that
394+
# let's this transition flip rules_swift config down the build graph.
395+
return is_xcframework or hasattr(attr, "_emitswiftinterface")
396+
375397
def _apple_rule_base_transition_impl(settings, attr):
376398
"""Rule transition for Apple rules using Bazel CPUs and a valid Apple split transition."""
377399
platform_type = attr.platform_type
378400
return _command_line_options(
379-
emit_swiftinterface = hasattr(attr, "_emitswiftinterface"),
401+
emit_swiftinterface = _should_emit_swiftinterface(attr),
380402
environment_arch = _environment_archs(platform_type, settings)[0],
381403
minimum_os_version = attr.minimum_os_version,
382404
platform_type = platform_type,
@@ -447,7 +469,7 @@ def _apple_platforms_rule_base_transition_impl(settings, attr):
447469
environment_arch = _environment_archs(platform_type, settings)[0]
448470
return _command_line_options(
449471
apple_platforms = settings["//command_line_option:apple_platforms"],
450-
emit_swiftinterface = hasattr(attr, "_emitswiftinterface"),
472+
emit_swiftinterface = _should_emit_swiftinterface(attr),
451473
environment_arch = environment_arch,
452474
minimum_os_version = minimum_os_version,
453475
platform_type = platform_type,
@@ -470,7 +492,7 @@ def _apple_platforms_rule_bundle_output_base_transition_impl(settings, attr):
470492
environment_arch = _environment_archs(platform_type, settings)[0]
471493
return _command_line_options(
472494
apple_platforms = settings["//command_line_option:apple_platforms"],
473-
emit_swiftinterface = hasattr(attr, "_emitswiftinterface"),
495+
emit_swiftinterface = _should_emit_swiftinterface(attr),
474496
environment_arch = environment_arch,
475497
force_bundle_outputs = True,
476498
minimum_os_version = minimum_os_version,
@@ -550,7 +572,7 @@ def _apple_platform_split_transition_impl(settings, attr):
550572
# iOS and tvOS static frameworks require underlying swift_library targets generate a Swift
551573
# interface file. These rules define a private attribute called `_emitswiftinterface` that
552574
# let's this transition flip rules_swift config down the build graph.
553-
emit_swiftinterface = hasattr(attr, "_emitswiftinterface")
575+
emit_swiftinterface = _should_emit_swiftinterface(attr)
554576

555577
if settings["//command_line_option:incompatible_enable_apple_toolchain_resolution"]:
556578
platforms = (
@@ -665,6 +687,7 @@ def _xcframework_transition_impl(settings, attr):
665687
target_environments.append("simulator")
666688

667689
command_line_options = _command_line_options_for_xcframework_platform(
690+
attr = attr,
668691
minimum_os_version = attr.minimum_os_versions.get(platform_type),
669692
platform_attr = getattr(attr, platform_type),
670693
platform_type = platform_type,

test/starlark_tests/targets_under_test/apple/BUILD

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -863,9 +863,6 @@ apple_xcframework(
863863
name = "ios_swift_3p_xcframework_with_generated_header",
864864
bundle_id = "com.google.example",
865865
bundle_name = "Swift3PFmwkWithGenHeader",
866-
# TODO(b/239957001): Remove this when the rule no longer forces library
867-
# evolution.
868-
features = ["apple.no_legacy_swiftinterface"],
869866
infoplists = [
870867
"//test/starlark_tests/resources:Info.plist",
871868
],
@@ -1271,7 +1268,6 @@ swift_library(
12711268
swift_library(
12721269
name = "Swift3PFmwkWithGenHeader",
12731270
srcs = ["DummyFmwk.swift"],
1274-
features = ["swift.enable_library_evolution"],
12751271
generates_header = True,
12761272
module_name = "Swift3PFmwkWithGenHeader",
12771273
tags = common.fixture_tags,

test/starlark_tests/targets_under_test/ios/BUILD

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4071,9 +4071,6 @@ ios_static_framework(
40714071
ios_static_framework(
40724072
name = "static_framework_with_generated_header",
40734073
bundle_name = "SwiftStaticFmwkWithGenHeader",
4074-
# TODO(b/239957001): Remove this when the rule no longer forces library
4075-
# evolution.
4076-
features = ["apple.no_legacy_swiftinterface"],
40774074
minimum_os_version = common.min_os_ios.baseline,
40784075
tags = common.fixture_tags,
40794076
deps = [":SwiftStaticFmwkWithGenHeader"],
@@ -4171,7 +4168,6 @@ swift_library(
41714168
swift_library(
41724169
name = "SwiftStaticFmwkWithGenHeader",
41734170
srcs = [":dummy_swift"],
4174-
features = ["swift.enable_library_evolution"],
41754171
generates_header = True,
41764172
module_name = "SwiftStaticFmwkWithGenHeader",
41774173
tags = common.fixture_tags,

0 commit comments

Comments
 (0)