@@ -422,20 +422,27 @@ def _create_xcframework_root_infoplist(
422422def _create_xcframework_bundle (
423423 * ,
424424 actions ,
425+ apple_fragment ,
426+ apple_mac_toolchain_info ,
427+ apple_xplat_toolchain_info ,
425428 bundle_name ,
426- bundletool ,
427429 framework_archive_files ,
428430 framework_archive_merge_files ,
429431 framework_archive_merge_zips = [],
430432 label_name ,
431433 output_archive ,
432- root_info_plist ):
434+ root_info_plist ,
435+ tree_artifact_enabled ,
436+ xcode_config ):
433437 """Generates the bundle archive for an XCFramework.
434438
435439 Args:
436440 actions: The actions providerx from `ctx.actions`.
441+ apple_fragment: An Apple fragment (ctx.fragments.apple).
442+ apple_mac_toolchain_info: The `AppleMacToolsToolchainInfo` provider from the mac toolchain.
443+ apple_xplat_toolchain_info: The `AppleXPlatToolsToolchainInfo` provider from the xplat
444+ toolchain.
437445 bundle_name: The name of the XCFramework bundle.
438- bundletool: A files to run for the bundle tool.
439446 framework_archive_files: A list of depsets referencing files to be used as inputs to the
440447 bundling action. This should include every archive referenced as a "src" of
441448 framework_archive_merge_zips.
@@ -451,6 +458,8 @@ def _create_xcframework_bundle(
451458 label_name: Name of the target being built.
452459 output_archive: The file representing the final bundled archive.
453460 root_info_plist: A `File` representing a fully formed root Info.plist for this XCFramework.
461+ tree_artifact_enabled: A boolean indicating whether tree artifact outputs are enabled.
462+ xcode_config: The `apple_common.XcodeVersionConfig` provider from the context.
454463 """
455464 bundletool_control_file = intermediates .file (
456465 actions = actions ,
@@ -471,17 +480,43 @@ def _create_xcframework_bundle(
471480 content = json .encode (bundletool_control ),
472481 )
473482
474- actions .run (
475- arguments = [bundletool_control_file .path ],
476- executable = bundletool ,
477- inputs = depset (
478- direct = [bundletool_control_file , root_info_plist ],
479- transitive = framework_archive_files ,
480- ),
481- mnemonic = "CreateXCFrameworkBundle" ,
482- outputs = [output_archive ],
483- progress_message = "Bundling %s" % label_name ,
484- )
483+ if tree_artifact_enabled :
484+ bundletool = apple_mac_toolchain_info .bundletool_experimental
485+ apple_support .run (
486+ actions = actions ,
487+ apple_fragment = apple_fragment ,
488+ arguments = [bundletool_control_file .path ],
489+ executable = bundletool ,
490+ execution_requirements = {
491+ # Added so that the output of this action is not cached remotely, in case multiple
492+ # developers sign the same artifact with different identities.
493+ "no-remote" : "1" ,
494+ # Unsure, but may be needed for keychain access, especially for files that live in
495+ # $HOME.
496+ "no-sandbox" : "1" ,
497+ },
498+ inputs = depset (
499+ direct = [bundletool_control_file , root_info_plist ],
500+ transitive = framework_archive_files ,
501+ ),
502+ mnemonic = "CreateXCFrameworkBundle" ,
503+ outputs = [output_archive ],
504+ progress_message = "Bundling %s" % label_name ,
505+ xcode_config = xcode_config ,
506+ )
507+ else :
508+ bundletool = apple_xplat_toolchain_info .bundletool
509+ actions .run (
510+ arguments = [bundletool_control_file .path ],
511+ executable = bundletool ,
512+ inputs = depset (
513+ direct = [bundletool_control_file , root_info_plist ],
514+ transitive = framework_archive_files ,
515+ ),
516+ mnemonic = "CreateXCFrameworkBundle" ,
517+ outputs = [output_archive ],
518+ progress_message = "Bundling %s" % label_name ,
519+ )
485520
486521def _apple_xcframework_impl (ctx ):
487522 """Implementation of apple_xcframework."""
@@ -492,12 +527,18 @@ def _apple_xcframework_impl(ctx):
492527 cc_toolchain_forwarder = ctx .split_attr ._cc_toolchain_forwarder
493528 executable_name = getattr (ctx .attr , "executable_name" , bundle_name )
494529 deps = ctx .split_attr .deps
530+ xcode_config = ctx .attr ._xcode_config [apple_common .XcodeVersionConfig ]
495531
532+ tree_artifact_enabled = False
533+ outputs_archive = ctx .outputs .archive
496534 if (apple_xplat_toolchain_info .build_settings .use_tree_artifacts_outputs or
497535 is_experimental_tree_artifact_enabled (config_vars = ctx .var )):
498- fail ("The apple_xcframework rule does not yet support the experimental tree artifact. " +
499- "Please ensure that the `apple.experimental.tree_artifact_outputs` variable is not " +
500- "set to 1 on the command line or in your active build configuration." )
536+ actions .write (
537+ output = ctx .outputs .archive ,
538+ content = "This is a dummy file because tree artifacts are enabled" ,
539+ )
540+ tree_artifact_enabled = True
541+ outputs_archive = actions .declare_directory (bundle_name + ".xcframework" )
501542
502543 # Add the disable_legacy_signing feature to the list of features
503544 # TODO(b/72148898): Remove this when dossier based signing becomes the default.
@@ -553,7 +594,7 @@ def _apple_xcframework_impl(ctx):
553594 deps = deps ,
554595 label_name = label .name ,
555596 link_result = link_result ,
556- xcode_config = ctx . attr . _xcode_config [ apple_common . XcodeVersionConfig ] ,
597+ xcode_config = xcode_config ,
557598 )
558599
559600 available_libraries = []
@@ -741,10 +782,25 @@ def _apple_xcframework_impl(ctx):
741782 for provider in processor_result .providers :
742783 # Save the framework archive.
743784 if getattr (provider , "archive" , None ):
744- # Repackage every archive found for bundle_merge_zips in the final bundler action.
745- framework_archive_merge_zips .append (
746- struct (src = provider .archive .path , dest = library_identifier ),
747- )
785+ # Repackage every archive found for bundle_merge_files or bundle_merge_zips in the
786+ # final bundler action, depending on whether tree artifacts are enabled.
787+ if tree_artifact_enabled :
788+ framework_archive_merge_files .append (
789+ struct (
790+ src = provider .archive .path ,
791+ dest = paths .join (
792+ library_identifier ,
793+ bundle_name + nested_bundle_extension ,
794+ ),
795+ ),
796+ )
797+ else :
798+ framework_archive_merge_zips .append (
799+ struct (
800+ src = provider .archive .path ,
801+ dest = library_identifier ,
802+ ),
803+ )
748804
749805 # Save a reference to those archives as file-friendly inputs to the bundler action.
750806 framework_archive_files .append (depset ([provider .archive ]))
@@ -775,25 +831,29 @@ def _apple_xcframework_impl(ctx):
775831 available_libraries = available_libraries ,
776832 plisttool = apple_mac_toolchain_info .plisttool ,
777833 rule_label = label ,
778- xcode_config = ctx . attr . _xcode_config [ apple_common . XcodeVersionConfig ] ,
834+ xcode_config = xcode_config ,
779835 )
780836
781837 _create_xcframework_bundle (
782838 actions = actions ,
839+ apple_fragment = ctx .fragments .apple ,
840+ apple_mac_toolchain_info = apple_mac_toolchain_info ,
841+ apple_xplat_toolchain_info = apple_xplat_toolchain_info ,
783842 bundle_name = bundle_name ,
784- bundletool = apple_xplat_toolchain_info .bundletool ,
785843 framework_archive_files = framework_archive_files ,
786844 framework_archive_merge_files = framework_archive_merge_files ,
787845 framework_archive_merge_zips = framework_archive_merge_zips ,
788846 label_name = label .name ,
789- output_archive = ctx . outputs . archive ,
847+ output_archive = outputs_archive ,
790848 root_info_plist = root_info_plist ,
849+ tree_artifact_enabled = tree_artifact_enabled ,
850+ xcode_config = xcode_config ,
791851 )
792852
793853 processor_output = [
794854 # Limiting the contents of AppleBundleInfo to what is necessary for testing and validation.
795855 new_applebundleinfo (
796- archive = ctx . outputs . archive ,
856+ archive = outputs_archive ,
797857 bundle_extension = ".xcframework" ,
798858 bundle_id = nested_bundle_id ,
799859 bundle_name = bundle_name ,
@@ -803,7 +863,7 @@ def _apple_xcframework_impl(ctx):
803863 ),
804864 new_applexcframeworkbundleinfo (),
805865 DefaultInfo (
806- files = depset ([ctx . outputs . archive ], transitive = framework_output_files ),
866+ files = depset ([outputs_archive ], transitive = framework_output_files ),
807867 ),
808868 OutputGroupInfo (
809869 ** outputs .merge_output_groups (
@@ -970,9 +1030,19 @@ def _apple_static_xcframework_impl(ctx):
9701030 requested_features = ctx .features ,
9711031 unsupported_features = ctx .disabled_features ,
9721032 )
973- outputs_archive = ctx .outputs .archive
9741033 xcode_config = ctx .attr ._xcode_config [apple_common .XcodeVersionConfig ]
9751034
1035+ tree_artifact_enabled = False
1036+ outputs_archive = ctx .outputs .archive
1037+ if (apple_xplat_toolchain_info .build_settings .use_tree_artifacts_outputs or
1038+ is_experimental_tree_artifact_enabled (config_vars = ctx .var )):
1039+ actions .write (
1040+ output = ctx .outputs .archive ,
1041+ content = "This is a dummy file because tree artifacts are enabled" ,
1042+ )
1043+ tree_artifact_enabled = True
1044+ outputs_archive = actions .declare_directory (bundle_name + ".xcframework" )
1045+
9761046 archive_result = linking_support .register_static_library_archive_action (
9771047 ctx = ctx ,
9781048 cc_toolchains = cc_toolchain_forwarder ,
@@ -1145,13 +1215,17 @@ def _apple_static_xcframework_impl(ctx):
11451215
11461216 _create_xcframework_bundle (
11471217 actions = actions ,
1218+ apple_fragment = apple_fragment ,
1219+ apple_mac_toolchain_info = apple_mac_toolchain_info ,
1220+ apple_xplat_toolchain_info = apple_xplat_toolchain_info ,
11481221 bundle_name = bundle_name ,
1149- bundletool = apple_xplat_toolchain_info .bundletool ,
11501222 framework_archive_files = framework_archive_files ,
11511223 framework_archive_merge_files = framework_archive_merge_files ,
11521224 label_name = label .name ,
11531225 output_archive = outputs_archive ,
11541226 root_info_plist = root_info_plist ,
1227+ tree_artifact_enabled = tree_artifact_enabled ,
1228+ xcode_config = xcode_config ,
11551229 )
11561230
11571231 return [
0 commit comments