Skip to main content
Glama
prebuilt_apple_framework.bzl12 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//:artifact_tset.bzl", "ArtifactInfoTag", "ArtifactTSet", "make_artifact_tset", ) load("@prelude//apple:apple_utility.bzl", "get_base_swiftinterface_compilation_flags") load("@prelude//apple/swift:apple_sdk_modules_utility.bzl", "is_sdk_modules_provided") load( "@prelude//apple/swift:swift_compilation.bzl", "SwiftDependencyInfo", "create_swift_dependency_info", "get_external_debug_info_tsets", "get_swift_framework_anonymous_targets", ) load("@prelude//apple/swift:swift_pcm_compilation.bzl", "compile_framework_pcm") load( "@prelude//apple/swift:swift_pcm_compilation_types.bzl", "SwiftPCMUncompiledInfo", ) load("@prelude//apple/swift:swift_swiftinterface_compilation.bzl", "compile_swiftinterface_common") load("@prelude//apple/swift:swift_toolchain_types.bzl", "SwiftToolchainInfo") load("@prelude//apple/swift:swift_types.bzl", "FrameworkImplicitSearchPathInfo", "get_implicit_framework_search_path_providers") load("@prelude//cxx:cxx_context.bzl", "get_cxx_toolchain_info") load( "@prelude//cxx:cxx_library_utility.bzl", "cxx_attr_exported_linker_flags", "cxx_attr_preferred_linkage", "cxx_platform_supported", ) load( "@prelude//cxx:preprocessor.bzl", "CPreprocessor", "CPreprocessorArgs", "cxx_inherited_preprocessor_infos", "cxx_merge_cpreprocessors", ) load("@prelude//cxx:target_sdk_version.bzl", "get_target_triple", "get_unversioned_target_triple") load( "@prelude//linking:link_groups.bzl", "merge_link_group_lib_info", ) load( "@prelude//linking:link_info.bzl", "LibOutputStyle", "LinkInfo", "LinkInfos", "create_merged_link_info", ) load( "@prelude//linking:linkable_graph.bzl", "create_linkable_graph", "create_linkable_graph_node", "create_linkable_node", ) load( "@prelude//linking:shared_libraries.bzl", "SharedLibraryInfo", "merge_shared_libraries", ) load("@prelude//linking:strip.bzl", "strip_object") load("@prelude//utils:utils.bzl", "filter_and_map_idx") load(":apple_bundle_types.bzl", "AppleBundleInfo", "AppleBundleTypeDefault") load(":apple_dsym.bzl", "DSYM_SUBTARGET") load(":apple_frameworks.bzl", "to_framework_name") load(":apple_toolchain_types.bzl", "AppleToolchainInfo", "AppleToolsInfo") load(":apple_utility.bzl", "get_apple_stripped_attr_value_with_default_fallback") load(":debug.bzl", "AppleDebuggableInfo") def prebuilt_apple_framework_impl(ctx: AnalysisContext) -> [list[Provider], Promise]: def get_prebuilt_apple_framework_providers(deps_providers) -> list[Provider]: providers = [] framework_directory_artifact = ctx.attrs.framework framework_name = to_framework_name(framework_directory_artifact.basename) # Check this rule's `supported_platforms_regex` with the current platform. if cxx_platform_supported(ctx): # Sandbox the framework, to avoid leaking other frameworks via search paths. framework_dir = ctx.actions.symlinked_dir( "Frameworks", {framework_name + ".framework": framework_directory_artifact}, ) # Add framework & pp info from deps. inherited_pp_info = cxx_inherited_preprocessor_infos(ctx.attrs.deps) providers.append(cxx_merge_cpreprocessors( ctx, [CPreprocessor(args = CPreprocessorArgs(args = ["-F", framework_dir]))], inherited_pp_info, )) # Add framework to link args. # TODO(T110378120): Support shared linking for mac targets: # https://fburl.com/code/pqrtt1qr. args = [] args.extend(cxx_attr_exported_linker_flags(ctx)) args.extend(["-F", framework_dir]) args.extend(["-framework", framework_name]) link = LinkInfo( name = framework_name, pre_flags = args, ) link_info = LinkInfos(default = link) providers.append(create_merged_link_info( ctx, get_cxx_toolchain_info(ctx).pic_behavior, {output_style: link_info for output_style in LibOutputStyle}, )) # Create, augment and provide the linkable graph. linkable_graph = create_linkable_graph( ctx, node = create_linkable_graph_node( ctx, linkable_node = create_linkable_node( ctx, preferred_linkage = cxx_attr_preferred_linkage(ctx), link_infos = {output_style: link_info for output_style in LibOutputStyle}, # TODO(cjhopman): this should be set to non-None default_soname = None, ), excluded = {ctx.label: None}, ), ) providers.append(linkable_graph) providers.append(merge_link_group_lib_info(deps = ctx.attrs.deps)) providers.append(merge_shared_libraries(ctx.actions, deps = filter_and_map_idx(SharedLibraryInfo, ctx.attrs.deps))) # The default output is the provided framework. sub_targets = { "distribution": _sanitize_framework_for_app_distribution(ctx, framework_directory_artifact) + providers, } if ctx.attrs.dsyms: sub_targets[DSYM_SUBTARGET] = [DefaultInfo(default_outputs = ctx.attrs.dsyms)] providers.append(AppleDebuggableInfo(dsyms = ctx.attrs.dsyms, debug_info_tset = ArtifactTSet())) providers.append(DefaultInfo(default_output = framework_directory_artifact, sub_targets = sub_targets)) providers.append(AppleBundleInfo( bundle = framework_directory_artifact, bundle_type = AppleBundleTypeDefault, skip_copying_swift_stdlib = True, contains_watchapp = None, extra_codesign_paths = ctx.attrs.extra_codesign_paths, )) if ctx.attrs.modular: pcm_provider = _create_uncompiled_pcm_module_info(ctx, framework_directory_artifact, framework_name) providers.append(pcm_provider) # Since not all frameworks expose a swiftinterface, we use the `contains_swift` attribute to determine if one is available. if ctx.attrs.contains_swift: swift_dependency_info = _compile_swiftinterface( ctx, framework_name, pcm_provider, deps_providers, framework_directory_artifact, ) providers.append(swift_dependency_info) implicit_search_path_tset = get_implicit_framework_search_path_providers( ctx, cmd_args("-F", cmd_args(framework_directory_artifact, parent = 1)), ctx.attrs.deps, ) providers.append( FrameworkImplicitSearchPathInfo(tset = implicit_search_path_tset), ) return providers # We cannot determine whether Swift Explicit modules are enabled at this point. # Therefore, we always return providers for both Implicit and Explicit modules, if SDK modules are available. # This approach is safe and won't trigger compilation of swiftinterfaces or pcm modules, # as no upper-level targets will depend on the artifacts from these compilations. swift_toolchain = ctx.attrs._apple_toolchain[SwiftToolchainInfo] if is_sdk_modules_provided(swift_toolchain): return get_swift_framework_anonymous_targets(ctx, get_prebuilt_apple_framework_providers) else: return get_prebuilt_apple_framework_providers([]) def _create_uncompiled_pcm_module_info(ctx: AnalysisContext, framework_directory_artifact: Artifact, framework_name: str) -> SwiftPCMUncompiledInfo: exported_pp_info = CPreprocessor( headers = [], modular_args = [], args = CPreprocessorArgs(args = [ cmd_args(["-F", cmd_args(framework_directory_artifact, parent = 1)], delimiter = ""), ]), modulemap_path = cmd_args(framework_directory_artifact, "/Modules/module.modulemap", delimiter = ""), ) return SwiftPCMUncompiledInfo( name = framework_name, is_transient = False, exported_preprocessor = exported_pp_info, exported_deps = ctx.attrs.deps, propagated_preprocessor_args_cmd = cmd_args([]), uncompiled_sdk_modules = ctx.attrs.sdk_modules, ) def _compile_swiftinterface( ctx: AnalysisContext, framework_name: str, pcm_provider: SwiftPCMUncompiledInfo, deps_providers, framework_directory_artifact: Artifact) -> SwiftDependencyInfo: # To compile the framework's swiftinterface, the PCM module must be precompiled first. compiled_underlying_pcm = compile_framework_pcm( ctx, framework_name, pcm_provider, deps_providers, ["-target", get_target_triple(ctx)], ) partial_cmd = get_base_swiftinterface_compilation_flags(framework_name) swiftinterface_path = cmd_args( framework_directory_artifact, "/Modules/", framework_name, ".swiftmodule/" + get_unversioned_target_triple(ctx) + ".swiftinterface", delimiter = "", ) swift_compiled_module, _ = compile_swiftinterface_common( ctx, ctx.attrs.deps, True, # is_framework framework_name, partial_cmd, deps_providers, swiftinterface_path, "prebuilt_framework_swiftinterface_compilation", compiled_underlying_pcm, ) debug_info_tset = make_artifact_tset( actions = ctx.actions, artifacts = [swift_compiled_module.output_artifact, compiled_underlying_pcm.output_artifact], children = get_external_debug_info_tsets(False, ctx.attrs.deps), label = ctx.label, tags = [ArtifactInfoTag("swiftmodule")], ) swift_dependency_info = create_swift_dependency_info( ctx, ctx.attrs.deps, deps_providers, swift_compiled_module, debug_info_tset, False, ) return swift_dependency_info def _sanitize_framework_for_app_distribution(ctx: AnalysisContext, framework_directory_artifact: Artifact) -> list[Provider]: framework_name = to_framework_name(framework_directory_artifact.basename) bundle_for_app_distribution = ctx.actions.declare_output(framework_name + ".framework", dir = True) apple_tools = ctx.attrs._apple_tools[AppleToolsInfo] framework_sanitize_command = cmd_args([ apple_tools.framework_sanitizer, "--input", framework_directory_artifact, "--output", bundle_for_app_distribution.as_output(), ]) if get_apple_stripped_attr_value_with_default_fallback(ctx): strip_args = cmd_args("-x") stripped = strip_object(ctx, ctx.attrs._apple_toolchain[AppleToolchainInfo].cxx_toolchain_info, framework_directory_artifact.project(framework_name), strip_args, "framework_distribution") framework_sanitize_command.add("--replacement-binary", stripped) ctx.actions.run(framework_sanitize_command, category = "sanitize_prebuilt_apple_framework") providers = [DefaultInfo(default_output = bundle_for_app_distribution)] providers.append(AppleBundleInfo( bundle = bundle_for_app_distribution, bundle_type = AppleBundleTypeDefault, skip_copying_swift_stdlib = True, contains_watchapp = None, extra_codesign_paths = ctx.attrs.extra_codesign_paths, )) return providers

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