Skip to content

Commit d952fdf

Browse files
nglevinluispadron
authored andcommitted
Build out providers to reference XCFramework outputs of interest for future avoid_frameworks functionality, and start propagating inputs through the XCFramework rules.
Cherry-pick: ebeb01e
1 parent 85e1e12 commit d952fdf

4 files changed

Lines changed: 137 additions & 5 deletions

File tree

apple/internal/BUILD

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,7 @@ bzl_library(
807807
":apple_toolchains",
808808
":cc_info_support",
809809
":experimental",
810+
":features_support",
810811
":intermediates",
811812
":linking_support",
812813
":outputs",
@@ -824,6 +825,8 @@ bzl_library(
824825
"//apple/internal/aspects:resource_aspect",
825826
"//apple/internal/aspects:resource_aspect_hint",
826827
"//apple/internal/aspects:swift_usage_aspect",
828+
"//apple/internal/providers:xcframework_deps_info",
829+
"//apple/internal/toolchains:apple_toolchains",
827830
"//apple/internal/utils:files",
828831
"@bazel_skylib//lib:partial",
829832
"@bazel_skylib//lib:paths",

apple/internal/providers/BUILD

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,14 @@ bzl_library(
4949
],
5050
)
5151

52+
bzl_library(
53+
name = "xcframework_deps_info",
54+
srcs = ["xcframework_deps_info.bzl"],
55+
visibility = [
56+
"//apple/internal:__subpackages__",
57+
],
58+
)
59+
5260
# Consumed by bazel tests.
5361
filegroup(
5462
name = "for_bazel_tests",
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Copyright 2025 The Bazel Authors. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""XCFrameworkDepsInfo provider implementation."""
16+
17+
visibility([
18+
"//apple/internal/...",
19+
])
20+
21+
XCFrameworkDepsInfo = provider(
22+
doc = "Contains information about the framework contents of a dynamic framework XCFramework.",
23+
fields = {
24+
"frameworks_by_platform_and_environment": """\
25+
A Dictionary of platform and environment keys simulating the key-bsaed interface of a split
26+
transition, referencing Lists of structs with these fields:
27+
28+
* `apple_dynamic_framework_info`: An AppleDynamicFrameworkInfo provider representing one
29+
framework's linking information.
30+
31+
* `apple_resource_info`: An optional AppleFrameworkInfo provider representing the resource
32+
contents of a given framework.
33+
34+
* `architectures`: A list of architectures that the framework supports for validation.
35+
""",
36+
},
37+
)

apple/internal/xcframework_rules.bzl

Lines changed: 89 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,10 @@ load(
4343
"is_experimental_tree_artifact_enabled",
4444
)
4545
load(
46-
"//apple/internal:intermediates.bzl",
47-
"intermediates",
46+
"//apple/internal:features_support.bzl",
47+
"features_support",
4848
)
49+
load("//apple/internal:intermediates.bzl", "intermediates")
4950
load(
5051
"//apple/internal:linking_support.bzl",
5152
"linking_support",
@@ -106,6 +107,10 @@ load(
106107
"//apple/internal/aspects:swift_usage_aspect.bzl",
107108
"swift_usage_aspect",
108109
)
110+
load(
111+
"//apple/internal/providers:xcframework_deps_info.bzl",
112+
"XCFrameworkDepsInfo",
113+
)
109114
load(
110115
"//apple/internal/utils:files.bzl",
111116
"files",
@@ -265,6 +270,18 @@ _PLATFORM_TYPE_TO_XCFRAMEWORK_PLATFORM_NAME = {
265270
"visionos": "xros",
266271
}
267272

273+
def _framework_key(*, platform_type, environment):
274+
"""Returns a dictionary key to retrieve linker outputs by platform_type/os and environment.
275+
276+
This is used in intermediate dictionaries used to represent the expected final contents of
277+
potentially lipoed/merged frameworks, such as frameworks_by_platform_and_environment in
278+
XCFrameworkDepsInfo.
279+
"""
280+
return "{platform_type}_{environment}".format(
281+
platform_type = platform_type,
282+
environment = environment,
283+
)
284+
268285
def _validate_resource_attrs(
269286
*,
270287
all_attrs,
@@ -399,7 +416,10 @@ def _group_link_outputs_by_library_identifier(
399416
# Iterate through the outputs of the registered linking action, match archs to platform and
400417
# environment combinations.
401418
for link_output in link_result.outputs:
402-
framework_key = link_output.platform + "_" + link_output.environment
419+
framework_key = _framework_key(
420+
platform_type = link_output.platform,
421+
environment = link_output.environment,
422+
)
403423
if link_outputs_by_framework.get(framework_key):
404424
link_outputs_by_framework[framework_key].append(link_output)
405425
else:
@@ -428,6 +448,7 @@ def _group_link_outputs_by_library_identifier(
428448
architectures = []
429449
dsym_outputs = {}
430450
linkmaps = {}
451+
linking_contexts = {}
431452
split_attr_keys = []
432453
framework_swift_generated_headers = {}
433454
framework_swift_infos = {}
@@ -459,6 +480,7 @@ def _group_link_outputs_by_library_identifier(
459480
if linking_type == "binary":
460481
dsym_outputs[link_output.architecture] = link_output.dsym_output
461482
linkmaps[link_output.architecture] = link_output.linkmap
483+
linking_contexts[link_output.architecture] = link_output.linking_context
462484

463485
# Keep the architectures sorted.
464486
sorted_architectures = sorted(architectures)
@@ -477,6 +499,7 @@ def _group_link_outputs_by_library_identifier(
477499
dsym_outputs = dsym_outputs,
478500
environment = environment,
479501
linkmaps = linkmaps,
502+
linking_contexts = linking_contexts,
480503
platform = platform,
481504
split_attr_keys = split_attr_keys,
482505
framework_swift_generated_headers = framework_swift_generated_headers,
@@ -585,9 +608,11 @@ def _create_framework_outputs(
585608
apple_mac_toolchain_info,
586609
apple_xplat_toolchain_info,
587610
bundle_name,
611+
cc_configured_features_init = None,
588612
cc_toolchain_forwarder,
589613
config_vars,
590614
cpp_fragment,
615+
disabled_features,
591616
environment_plist_files,
592617
executable_name,
593618
families_required,
@@ -614,10 +639,14 @@ def _create_framework_outputs(
614639
apple_mac_toolchain_info: A AppleMacToolsToolchainInfo provider.
615640
apple_xplat_toolchain_info: An AppleXPlatToolsToolchainInfo provider.
616641
bundle_name: The name of the XCFramework bundle.
642+
cc_configured_features_init: A lambda that is the same as cc_common.configure_features(...)
643+
without the need for a `ctx`.
617644
cc_toolchain_forwarder: The instance of cc_toolchain_forwarder to retrieve CcToolchainInfo
618645
providers from through the split_attrs interface.
619646
config_vars: A reference to configuration variables, typically from `ctx.var`.
620647
cpp_fragment: A cpp fragment (ctx.fragments.cpp), if it is present. Optional.
648+
disabled_features: A list of features disabled by the user. Typically from
649+
`ctx.disabled_features`.
621650
environment_plist_files: A list of Files referencing all supported platform-specific plists
622651
with predefined supporting variables.
623652
executable_name: The name of the executable for the nested framework.
@@ -693,6 +722,7 @@ bundle_id on the target.
693722
framework_archive_merge_zips = []
694723
framework_output_files = []
695724
framework_output_groups = []
725+
frameworks_by_platform_and_environment = {}
696726

697727
for library_identifier, link_output in link_outputs_by_library_identifier.items():
698728
binary_artifact = link_output.binary
@@ -840,7 +870,10 @@ bundle_id on the target.
840870
actions = actions,
841871
bundle_extension = nested_bundle_extension,
842872
bundle_name = bundle_name,
843-
debug_discriminator = link_output.platform + "_" + link_output.environment,
873+
debug_discriminator = _framework_key(
874+
platform_type = link_output.platform,
875+
environment = link_output.environment,
876+
),
844877
dsym_outputs = link_output.dsym_outputs,
845878
dsym_info_plist_template = apple_mac_toolchain_info.dsym_info_plist_template,
846879
label_name = rule_label.name,
@@ -851,6 +884,17 @@ bundle_id on the target.
851884
rule_label = rule_label,
852885
version = version,
853886
),
887+
partials.framework_provider_partial(
888+
actions = actions,
889+
binary_artifact = binary_artifact,
890+
bundle_only = False,
891+
cc_configured_features_init = cc_configured_features_init,
892+
cc_linking_contexts = link_output.linking_contexts.values(),
893+
cc_toolchain = cc_toolchain[cc_common.CcToolchainInfo],
894+
disabled_features = disabled_features,
895+
features = features,
896+
rule_label = rule_label,
897+
),
854898
partials.swift_dylibs_partial(
855899
actions = actions,
856900
apple_mac_toolchain_info = apple_mac_toolchain_info,
@@ -879,6 +923,12 @@ bundle_id on the target.
879923
rule_label = rule_label,
880924
)
881925

926+
# The inputs of XCFrameworkDepsInfo for dynamic XCFrameworks are both mandatory; each
927+
# dynamic framework must have a AppleDynamicFrameworkInfo provider, and an AppleResourceInfo
928+
# provider to cover the required Info.plist and optional extra bundle resources.
929+
direct_dynamic_framework_info = None
930+
direct_resource_info = None
931+
882932
for provider in processor_result.providers:
883933
# Save the framework archive.
884934
if getattr(provider, "archive", None):
@@ -911,16 +961,39 @@ bundle_id on the target.
911961
framework_output_files.append(depset(transitive = [provider.linkmaps]))
912962
framework_output_groups.append({"linkmaps": provider.linkmaps})
913963

964+
# Save the AppleDynamicFrameworkInfo, identified via the presence of the
965+
# "framework_linking_context" field.
966+
if getattr(provider, "framework_linking_context", None):
967+
direct_dynamic_framework_info = provider
968+
969+
# Save the AppleResourceInfo, identified via the presence of the "owners" field.
970+
if getattr(provider, "owners", None):
971+
direct_resource_info = provider
972+
914973
if library_type == _LIBRARY_TYPE.dynamic:
974+
# Save the dSYMs.
915975
dsyms = outputs.dsyms(
916976
platform_prerequisites = platform_prerequisites,
917977
processor_result = processor_result,
918978
)
919979
if dsyms:
920-
# Save the dSYMs.
921980
framework_output_files.append(depset(transitive = [dsyms]))
922981
framework_output_groups.append({"dsyms": dsyms})
923982

983+
# Save the XCFrameworkDepsInfo inputs for this particular framework.
984+
#
985+
# TODO(b/220185798): Append transitive providers from the partials as well as direct
986+
# providers from this particular framework, once we have targets to reference with
987+
# supported providers via an attribute such as `avoid_frameworks`.
988+
frameworks_by_platform_and_environment[_framework_key(
989+
platform_type = link_output.platform,
990+
environment = link_output.environment,
991+
)] = struct(
992+
apple_dynamic_framework_info = [direct_dynamic_framework_info],
993+
apple_resource_info = [direct_resource_info],
994+
architectures = link_output.architectures,
995+
)
996+
924997
# Save additional library details for the XCFramework's root info plist.
925998
available_libraries.append(_available_library_dictionary(
926999
architectures = link_output.architectures,
@@ -938,6 +1011,7 @@ bundle_id on the target.
9381011
framework_archive_merge_zips = framework_archive_merge_zips,
9391012
framework_output_files = framework_output_files,
9401013
framework_output_groups = framework_output_groups,
1014+
frameworks_by_platform_and_environment = frameworks_by_platform_and_environment,
9411015
)
9421016

9431017
def _create_xcframework_root_infoplist(
@@ -1138,6 +1212,7 @@ def _apple_xcframework_impl(ctx):
11381212
# TODO(b/72148898): Remove this when dossier based signing becomes the default.
11391213
features = ctx.features
11401214
features.append("disable_legacy_signing")
1215+
disabled_features = ctx.disabled_features
11411216

11421217
_validate_resource_attrs(
11431218
all_attrs = ctx.attr,
@@ -1218,9 +1293,11 @@ def _apple_xcframework_impl(ctx):
12181293
apple_mac_toolchain_info = apple_mac_toolchain_info,
12191294
apple_xplat_toolchain_info = apple_xplat_toolchain_info,
12201295
bundle_name = bundle_name,
1296+
cc_configured_features_init = features_support.make_cc_configured_features_init(ctx),
12211297
cc_toolchain_forwarder = ctx.split_attr._cc_toolchain_forwarder,
12221298
config_vars = config_vars,
12231299
cpp_fragment = cpp_fragment,
1300+
disabled_features = disabled_features,
12241301
environment_plist_files = environment_plist_files,
12251302
executable_name = executable_name,
12261303
families_required = families_required,
@@ -1276,6 +1353,11 @@ def _apple_xcframework_impl(ctx):
12761353
platform_type = None,
12771354
),
12781355
new_applexcframeworkbundleinfo(),
1356+
XCFrameworkDepsInfo(
1357+
frameworks_by_platform_and_environment = (
1358+
bundled_artifacts.frameworks_by_platform_and_environment,
1359+
),
1360+
),
12791361
DefaultInfo(
12801362
files = depset(
12811363
[outputs_archive],
@@ -1545,6 +1627,7 @@ def _apple_static_xcframework_impl(ctx):
15451627
# TODO(b/72148898): Remove this when dossier based signing becomes the default.
15461628
features = ctx.features
15471629
features.append("disable_legacy_signing")
1630+
disabled_features = ctx.disabled_features
15481631

15491632
archive_result = linking_support.register_static_library_archive_action(
15501633
ctx = ctx,
@@ -1582,6 +1665,7 @@ def _apple_static_xcframework_impl(ctx):
15821665
cc_toolchain_forwarder = ctx.split_attr._cc_toolchain_forwarder,
15831666
config_vars = config_vars,
15841667
cpp_fragment = cpp_fragment,
1668+
disabled_features = disabled_features,
15851669
environment_plist_files = environment_plist_files,
15861670
executable_name = executable_name,
15871671
families_required = families_required,

0 commit comments

Comments
 (0)