Skip to main content
Glama
swift_sdk_pcm_compilation.bzl11 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_error_handler.bzl", "apple_build_error_handler") load("@prelude//apple:apple_utility.bzl", "expand_relative_prefixed_sdk_path", "get_disable_pch_validation_flags") load(":apple_sdk_modules_utility.bzl", "get_compiled_sdk_clang_deps_tset") load( ":swift_debug_info_utils.bzl", "extract_and_merge_clang_debug_infos", ) load(":swift_sdk_flags.bzl", "get_sdk_flags") load(":swift_toolchain.bzl", "get_swift_toolchain_info_dep") load(":swift_toolchain_types.bzl", "SdkUncompiledModuleInfo", "SwiftCompiledModuleInfo", "SwiftCompiledModuleTset", "SwiftToolchainInfo", "WrappedSdkCompiledModuleInfo") def get_shared_pcm_compilation_args(module_name: str) -> cmd_args: cmd = cmd_args() cmd.add([ "-emit-pcm", "-module-name", module_name, "-Xfrontend", "-disable-implicit-swift-modules", "-Xcc", "-fno-implicit-modules", "-Xcc", "-fno-implicit-module-maps", # Embed all input files into the PCM so we don't need to include module map files when # building remotely. # https://github.com/apple/llvm-project/commit/fb1e7f7d1aca7bcfc341e9214bda8b554f5ae9b6 "-Xcc", "-Xclang", "-Xcc", "-fmodules-embed-all-files", # Set the base directory of the pcm file to the working directory, which ensures # all paths serialized in the PCM are relative. "-Xcc", "-Xclang", "-Xcc", "-fmodule-file-home-is-cwd", # We cannot set an empty Swift working directory as that would end up serializing # absolute header search paths in the PCM. Instead unset the clang working directory # to avoid serializing it as an absolute path. "-Xcc", "-working-directory=", # AssetsLibrary is shipping with a #warning, which we shouldn't error on when compiling # the SDK module. I don't think this is actually avoidable or removable until the next xcode major version "-Xcc", "-Wno-error=#warnings", # When compiling PCMs with the new Swift driver, we need to manually set -file-compilation-dir. # If not defined, the driver will append this path automatically, # resulting in the emission of absolute paths in the PCMs. "-file-compilation-dir", ".", ]) cmd.add(get_disable_pch_validation_flags()) return cmd def _remove_path_components_from_right(path: str, count: int): path_components = path.split("/") removed_path = "/".join(path_components[0:-count]) return removed_path def _add_sdk_module_search_path(cmd, uncompiled_sdk_module_info, swift_toolchain_info): modulemap_path = uncompiled_sdk_module_info.input_relative_path # If this input is a framework we need to search above the # current framework location, otherwise we include the # modulemap root. if uncompiled_sdk_module_info.is_framework: frameworks_dir_path = _remove_path_components_from_right(modulemap_path, 3) expanded_path = expand_relative_prefixed_sdk_path(swift_toolchain_info, frameworks_dir_path) else: module_root_path = _remove_path_components_from_right(modulemap_path, 1) expanded_path = expand_relative_prefixed_sdk_path(swift_toolchain_info, module_root_path) cmd.add([ "-Xcc", ("-F" if uncompiled_sdk_module_info.is_framework else "-I"), "-Xcc", cmd_args(expanded_path), ]) def get_swift_sdk_pcm_anon_targets( ctx: AnalysisContext, enable_cxx_interop: bool, uncompiled_sdk_deps: list[Dependency], swift_cxx_args: list[str]): # We include the Swift deps here too as we need # to include their transitive clang deps. return [ (_swift_sdk_pcm_compilation, { "dep": module_dep, "enable_cxx_interop": enable_cxx_interop, "name": module_dep.label, "swift_cxx_args": swift_cxx_args, "_swift_toolchain": get_swift_toolchain_info_dep(ctx), }) for module_dep in uncompiled_sdk_deps ] def _swift_sdk_pcm_compilation_impl(ctx: AnalysisContext) -> [Promise, list[Provider]]: def k(sdk_pcm_deps_providers) -> list[Provider]: uncompiled_sdk_module_info = ctx.attrs.dep[SdkUncompiledModuleInfo] sdk_deps_tset = get_compiled_sdk_clang_deps_tset(ctx, sdk_pcm_deps_providers) # We pass in Swift and Clang SDK module deps to get the transitive # Clang dependencies compiled with the correct Swift cxx args. For # Swift modules we just want to pass up the clang deps. if uncompiled_sdk_module_info.is_swiftmodule: return [ DefaultInfo(), WrappedSdkCompiledModuleInfo( clang_deps = sdk_deps_tset, clang_debug_info = extract_and_merge_clang_debug_infos(ctx, sdk_pcm_deps_providers), ), ] module_name = uncompiled_sdk_module_info.module_name swift_toolchain = ctx.attrs._swift_toolchain[SwiftToolchainInfo] cmd = cmd_args(swift_toolchain.compiler) argsfile_cmd = cmd_args(uncompiled_sdk_module_info.partial_cmd) argsfile_cmd.add(get_sdk_flags(ctx)) argsfile_cmd.add(swift_toolchain.compiler_flags) if swift_toolchain.resource_dir: argsfile_cmd.add([ "-resource-dir", swift_toolchain.resource_dir, ]) if not swift_toolchain.supports_relative_resource_dir: # When the compiler does not correctly serialize builtin header paths # we need to specify the CWD as a search path to find the headers. argsfile_cmd.add([ "-Xcc", "-I.", ]) argsfile_cmd.add(sdk_deps_tset.project_as_args("clang_module_file_flags")) # For SDK modules we need to set a few more args argsfile_cmd.add([ "-Xcc", "-Xclang", "-Xcc", "-emit-module", "-Xcc", "-Xclang", "-Xcc", "-fsystem-module", ]) argsfile_cmd.add(ctx.attrs.swift_cxx_args) if ctx.attrs.enable_cxx_interop: # The stdlib headers have deprecation warnings set when targeting # more recent versions. These warnings get serialized in the # modules and make it impossible to import the std module, so # suppress them during compilation instead. argsfile_cmd.add([ "-Xcc", "-D_LIBCPP_DISABLE_DEPRECATION_WARNINGS", ]) if module_name == "Darwin": # The Darwin module requires special handling with cxx interop # to ensure that it does not include the c++ headers. The module # is marked with [no_undeclared_includes] which will prevent # including headers declared in other modulemaps. So that the # cxx modules are visible we need to pass the module map path # without the corresponding module file, which we cannot build # until the Darwin module is available. argsfile_cmd.add([ "-Xcc", cmd_args(swift_toolchain.sdk_path, format = "-fmodule-map-file={}/usr/include/c++/v1/module.modulemap"), ]) _add_sdk_module_search_path(argsfile_cmd, uncompiled_sdk_module_info, swift_toolchain) shell_quoted_args = cmd_args(argsfile_cmd, quote = "shell") argsfile, _ = ctx.actions.write("sdk_pcm_compile_argsfile", shell_quoted_args, allow_args = True) cmd.add(cmd_args(argsfile, format = "@{}", delimiter = "")) cmd.add(cmd_args(hidden = [argsfile_cmd])) expanded_modulemap_path_cmd = expand_relative_prefixed_sdk_path( swift_toolchain, uncompiled_sdk_module_info.input_relative_path, ) pcm_output = ctx.actions.declare_output(module_name + ".pcm") cmd.add([ "-o", pcm_output.as_output(), expanded_modulemap_path_cmd, ]) ctx.actions.run( cmd, category = "sdk_swift_pcm_compile", identifier = module_name, # Swift compiler requires unique inodes for all input files. unique_input_inodes = True, error_handler = apple_build_error_handler, ) # Construct the args needed to be passed to the clang importer clang_deps_args = cmd_args() clang_deps_args.add("-Xcc") clang_deps_args.add( cmd_args( [ "-fmodule-file=", module_name, "=", pcm_output, ], delimiter = "", ), ) clang_deps_args.add("-Xcc") clang_deps_args.add( cmd_args( [ "-fmodule-map-file=", expanded_modulemap_path_cmd, ], delimiter = "", ), ) compiled_sdk = SwiftCompiledModuleInfo( clang_module_file_args = clang_deps_args, is_framework = uncompiled_sdk_module_info.is_framework, is_sdk_module = True, is_swiftmodule = False, module_name = module_name, output_artifact = pcm_output, clang_modulemap = expanded_modulemap_path_cmd, ) return [ DefaultInfo(), WrappedSdkCompiledModuleInfo( clang_deps = ctx.actions.tset(SwiftCompiledModuleTset, value = compiled_sdk, children = [sdk_deps_tset]), clang_debug_info = extract_and_merge_clang_debug_infos(ctx, sdk_pcm_deps_providers, [pcm_output]), ), ] # Compile the transitive clang module deps of this target. deps = ctx.attrs.dep[SdkUncompiledModuleInfo].cxx_deps if ctx.attrs.enable_cxx_interop else ctx.attrs.dep[SdkUncompiledModuleInfo].deps clang_module_deps = get_swift_sdk_pcm_anon_targets( ctx, ctx.attrs.enable_cxx_interop, deps, ctx.attrs.swift_cxx_args, ) return ctx.actions.anon_targets(clang_module_deps).promise.map(k) _swift_sdk_pcm_compilation = rule( impl = _swift_sdk_pcm_compilation_impl, attrs = { "dep": attrs.dep(), "enable_cxx_interop": attrs.bool(), "swift_cxx_args": attrs.list(attrs.string(), default = []), "_swift_toolchain": attrs.dep(), }, )

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