Skip to main content
Glama
apple_xcframework.bzl9.8 kB
# Copyright (c) Meta Platforms, Inc. and affiliates. # # This source code is licensed under both the MIT license found in the # LICENSE-MIT file in the root directory of this source tree and the Apache # License, Version 2.0 found in the LICENSE-APACHE file in the root directory # of this source tree. load("@prelude//apple:apple_bundle_types.bzl", "AppleBundleInfo") load("@prelude//apple:apple_common.bzl", "apple_common") load("@prelude//apple:apple_toolchain_types.bzl", "AppleToolsInfo") load("@prelude//user:rule_spec.bzl", "RuleRegistrationSpec") # Metadata about XCFramework XCFrameworkInfo = provider( fields = { # Name of supplied framework. For frameworks that define # modules this should be the name of the module "name": provider_field(str), }, ) def _get_any_framework_dep(framework_deps: [dict[str, Dependency], Dependency, None]) -> [Dependency, None]: if not type(framework_deps) == "dict": return framework_deps if len(framework_deps) == 0: return None return sorted(framework_deps.items())[0][1] def _get_framework_name(ctx: AnalysisContext) -> str: if ctx.attrs.framework_name != None: return ctx.attrs.framework_name if ctx.attrs.framework_name_from_product_name: framework = _get_any_framework_dep(ctx.attrs.framework) if framework == None: fail("Cannot find framework name") return framework[AppleBundleInfo].binary_name fail("Cannot find framework name") def _apple_xcframework_impl(ctx: AnalysisContext) -> list[Provider]: apple_tools = ctx.attrs._apple_tools[AppleToolsInfo] framework_name = _get_framework_name(ctx) xcframework_dir = ctx.actions.declare_output(framework_name + ".xcframework", dir = True) xcframework_command = cmd_args([ apple_tools.xcframework_maker, "--output-path", xcframework_dir.as_output(), "--name", framework_name, ]) for arch in ctx.attrs.framework: framework_dep = ctx.attrs.framework[arch] framework_paths = framework_dep[DefaultInfo].default_outputs if len(framework_paths) > 1: fail("xcframework's framework target {} must only produce one output".format(framework_dep.label)) xcframework_command.add("--framework-path") xcframework_command.add(arch) xcframework_command.add(framework_paths[0]) if ctx.attrs.include_dsym: dsym_dep = framework_dep[DefaultInfo].sub_targets["dsym"] dsym_path = dsym_dep[DefaultInfo].default_outputs xcframework_command.add("--dsym-path") xcframework_command.add(arch) xcframework_command.add(dsym_path) ctx.actions.run(xcframework_command, category = "apple_xcframework") return [ DefaultInfo(default_output = xcframework_dir), XCFrameworkInfo(name = framework_name), ] def _strip_os_sdk_and_runtime_constraints(platform: PlatformInfo, refs: struct) -> dict[TargetLabel, ConstraintValueInfo]: return { constraint_setting_label: constraint_setting_value for (constraint_setting_label, constraint_setting_value) in platform.configuration.constraints.items() if constraint_setting_label not in [refs.os[ConstraintSettingInfo].label, refs.sdk[ConstraintSettingInfo].label, refs.universal[ConstraintSettingInfo].label, refs.runtime[ConstraintSettingInfo].label] } # provides a map of os-platform to cpu architectures # so we can identify when universal binaries can be created instead of # two separate frameworks # # e.g. input of ["ios-arm64", "iphonesimulator-x86_64", "iphonesimulator-arm64"] # will produce {"ios": ["arm64"], "iphonesimulator": ["arm64", "x86_64"]} def _normalize_platforms(platforms: list[str]) -> dict[str, list[str]]: result = {} for platform in platforms: plat_list = platform.split("-") plat_type = plat_list[0] plat_archs = plat_list[1:] previous_archs = result.get(plat_type, []) result[plat_type] = sorted(plat_archs + previous_archs) return result def _apple_xcframework_framework_attrib_split_transition_impl( platform: PlatformInfo, refs: struct, attrs: struct) -> dict[str, PlatformInfo]: result = {} new_platforms = _normalize_platforms(attrs.platforms).items() for os_value, cpu_values in new_platforms: updated_constraints = _strip_os_sdk_and_runtime_constraints(platform, refs) canonical_platform_suffix = "" if os_value == "macos": canonical_platform_prefix = "macos" updated_constraints[refs.os[ConstraintSettingInfo].label] = refs.macos[ConstraintValueInfo] elif os_value == "iphoneos": canonical_platform_prefix = "ios" updated_constraints[refs.os[ConstraintSettingInfo].label] = refs.ios[ConstraintValueInfo] updated_constraints[refs.sdk[ConstraintSettingInfo].label] = refs.ios_device_sdk[ConstraintValueInfo] elif os_value == "watchos": canonical_platform_prefix = "watchos" updated_constraints[refs.os[ConstraintSettingInfo].label] = refs.watchos[ConstraintValueInfo] updated_constraints[refs.sdk[ConstraintSettingInfo].label] = refs.watchos_device_sdk[ConstraintValueInfo] elif os_value == "iphonesimulator": canonical_platform_prefix = "ios" canonical_platform_suffix = "simulator" updated_constraints[refs.os[ConstraintSettingInfo].label] = refs.ios[ConstraintValueInfo] updated_constraints[refs.sdk[ConstraintSettingInfo].label] = refs.ios_simulator_sdk[ConstraintValueInfo] elif os_value == "watchossimulator": canonical_platform_prefix = "watchos" canonical_platform_suffix = "simulator" updated_constraints[refs.os[ConstraintSettingInfo].label] = refs.watchos[ConstraintValueInfo] updated_constraints[refs.sdk[ConstraintSettingInfo].label] = refs.watchos_simulator_sdk[ConstraintValueInfo] elif os_value == "maccatalyst": canonical_platform_prefix = "ios" canonical_platform_suffix = "maccatalyst" updated_constraints[refs.os[ConstraintSettingInfo].label] = refs.ios[ConstraintValueInfo] updated_constraints[refs.sdk[ConstraintSettingInfo].label] = refs.maccatalyst_sdk[ConstraintValueInfo] updated_constraints[refs.runtime[ConstraintSettingInfo].label] = refs.maccatalyst_runtime[ConstraintValueInfo] else: fail("Unsupported OS value {} in apple_xcframework() platforms.".format(os_value)) cpu_constraint_name = refs.cpu[ConstraintSettingInfo].label if len(cpu_values) > 1: updated_constraints[refs.universal[ConstraintSettingInfo].label] = refs.universal_enabled[ConstraintValueInfo] elif cpu_values[0] == "arm64": updated_constraints[cpu_constraint_name] = refs.arm64[ConstraintValueInfo] elif cpu_values[0] == "x86_64": updated_constraints[cpu_constraint_name] = refs.x86_64[ConstraintValueInfo] else: fail("Unsupported CPU value {} in apple_xcframework().".format(cpu_values[0])) new_cfg = ConfigurationInfo( constraints = updated_constraints, values = platform.configuration.values, ) canonical_platform_name = canonical_platform_prefix + "-" + "_".join(cpu_values) if len(canonical_platform_suffix) > 0: canonical_platform_name += "-" + canonical_platform_suffix result.update({canonical_platform_name: PlatformInfo( label = canonical_platform_name + "_transition", configuration = new_cfg, )}) return result framework_split_transition = transition( impl = _apple_xcframework_framework_attrib_split_transition_impl, refs = { "arm32": "config//cpu/constraints:arm32", "arm64": "config//cpu/constraints:arm64", "cpu": "config//cpu/constraints:cpu", "ios": "config//os/constraints:iphoneos", "ios_device_sdk": "config//os/sdk/apple/constraints:iphoneos", "ios_simulator_sdk": "config//os/sdk/apple/constraints:iphonesimulator", "maccatalyst_runtime": "config//runtime/constraints:maccatalyst", "maccatalyst_sdk": "config//os/sdk/apple/constraints:maccatalyst", "macos": "config//os/constraints:macos", "os": "config//os/constraints:os", "runtime": "config//runtime/constraints:runtime", "sdk": "config//os/sdk/apple/constraints:_", "swift_library_evolution": "config//features/apple/constraints:swift_library_evolution", "swift_library_evolution_enabled": "config//features/apple/constraints:swift_library_evolution_enabled", "universal": "config//cpu/constraints:universal", "universal_enabled": "config//cpu/constraints:universal-enabled", "watchos": "config//os/constraints:watchos", "watchos_device_sdk": "config//os/sdk/apple/constraints:watchos", "watchos_simulator_sdk": "config//os/sdk/apple/constraints:watchsimulator", "x86_64": "config//cpu/constraints:x86_64", }, attrs = [ "platforms", ], split = True, ) registration_spec = RuleRegistrationSpec( name = "apple_xcframework", impl = _apple_xcframework_impl, attrs = { "framework": attrs.split_transition_dep(cfg = framework_split_transition), "framework_name": attrs.option(attrs.string(), default = None), "framework_name_from_product_name": attrs.bool(default = False), "include_dsym": attrs.option(attrs.bool(), default = None), "platforms": attrs.list(attrs.string(), default = []), } | apple_common.apple_tools_arg(), )

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/systeminit/si'

If you have feedback or need assistance with the MCP directory API, please join our Discord server