diff --git a/MODULE.bazel b/MODULE.bazel index 0584af40dc69..be1ec97cfd99 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -31,13 +31,8 @@ bazel_dep(name = "gazelle", version = "0.50.0") bazel_dep(name = "rules_dotnet", version = "0.21.5-codeql.1") bazel_dep(name = "googletest", version = "1.17.0.bcr.2") bazel_dep(name = "rules_rust", version = "0.69.0") -bazel_dep(name = "rules_swift", version = "4.0.0-rc5") +bazel_dep(name = "rules_swift", version = "4.0.0-rc5-codeql.1") bazel_dep(name = "swift-syntax", version = "603.0.2") - -# Needed so we can `use_repo` `local_config_xcode` and -# `local_config_apple_cc_toolchains` below (referenced by the per-target -# Xcode-config transition in `unified/swift-syntax-rs/xcode_transition.bzl`). -bazel_dep(name = "apple_support", version = "2.8.0") bazel_dep(name = "zstd", version = "1.5.7.bcr.1") bazel_dep(name = "buildifier_prebuilt", version = "6.4.0", dev_dependency = True) @@ -223,10 +218,7 @@ use_repo( "swift-resource-dir-macos", ) -# Swift toolchain for building `unified/swift-syntax-rs`. On Linux we register -# a hermetic swift.org toolchain as the exec toolchain; on macOS `rules_swift` -# auto-registers `xcode_swift_toolchain` (host Xcode + OS-provided Swift -# runtime), which is not hermetic. +# Hermetic swift.org toolchain for building `unified/swift-syntax-rs`. # # The version is pinned as a literal rather than read from # `unified/swift-syntax-rs/.swift-version` via `swift_version_file`: the latter @@ -244,20 +236,14 @@ use_repo( swift, "swift_toolchain", "swift_toolchain_ubuntu22.04", + "swift_toolchain_xcode", ) register_toolchains( "@swift_toolchain//:swift_toolchain_exec_ubuntu22.04", + "@swift_toolchain//:swift_toolchain_exec_xcode", ) -# `apple_support`'s xcode_config and CC toolchains, needed by the Xcode -# transition in `unified/swift-syntax-rs/xcode_transition.bzl`. -xcode_configure = use_extension("@apple_support//xcode:xcode_configure.bzl", "xcode_configure_extension") -use_repo(xcode_configure, "local_config_xcode") - -apple_cc_configure = use_extension("@apple_support//crosstool:setup.bzl", "apple_cc_configure_extension") -use_repo(apple_cc_configure, "local_config_apple_cc_toolchains") - node = use_extension("@rules_nodejs//nodejs:extensions.bzl", "node") node.toolchain( name = "nodejs", diff --git a/misc/bazel/registry/modules/rules_swift/4.0.0-rc5-codeql.1/MODULE.bazel b/misc/bazel/registry/modules/rules_swift/4.0.0-rc5-codeql.1/MODULE.bazel new file mode 100644 index 000000000000..f83ac395da02 --- /dev/null +++ b/misc/bazel/registry/modules/rules_swift/4.0.0-rc5-codeql.1/MODULE.bazel @@ -0,0 +1,79 @@ +"""rules_swift MODULE.bazel file""" + +module( + name = "rules_swift", + version = "4.0.0-rc5-codeql.1", + bazel_compatibility = [">=8.0.0"], + compatibility_level = 3, +) + +bazel_dep(name = "abseil-cpp", version = "20250814.1") +bazel_dep(name = "apple_support", version = "2.8.0") +bazel_dep(name = "bazel_linux_packages", version = "0.4.1") +bazel_dep(name = "bazel_features", version = "1.51.0") +bazel_dep(name = "bazel_skylib", version = "1.7.1") +bazel_dep(name = "nlohmann_json", version = "3.12.0.bcr.1") +bazel_dep(name = "platforms", version = "0.0.11") +bazel_dep(name = "protobuf", version = "34.0.bcr.1") +bazel_dep(name = "rules_cc", version = "0.2.14") +bazel_dep(name = "rules_shell", version = "0.3.0") +bazel_dep(name = "swift_argument_parser", version = "1.7.0") + +apt = use_extension("@bazel_linux_packages//apt:extensions.bzl", "apt") +apt.ubuntu( + name = "swift_ubuntu22.04_sysroot", + architectures = ["amd64"], + lockfile = "//swift/internal/extensions:ubuntu22.04_sysroot.lock.json", + packages = [ + "libc6-dev", + "libcurl4-openssl-dev", + "libstdc++-11-dev", + "libxml2-dev", + "linux-libc-dev", + "zlib1g-dev", + ], + suites = ["jammy"], +) +apt.ubuntu( + name = "swift_ubuntu22.04_aarch64_sysroot", + architectures = ["arm64"], + lockfile = "//swift/internal/extensions:ubuntu22.04_aarch64_sysroot.lock.json", + packages = [ + "libc6-dev", + "libcurl4-openssl-dev", + "libstdc++-11-dev", + "libxml2-dev", + "linux-libc-dev", + "zlib1g-dev", + ], + suites = ["jammy"], +) +use_repo( + apt, + "swift_ubuntu22.04_aarch64_sysroot", + "swift_ubuntu22.04_sysroot", +) + +swift_autoconfiguration = use_repo_rule("//swift/internal:swift_autoconfiguration.bzl", "swift_autoconfiguration") + +swift_autoconfiguration(name = "rules_swift_local_config") + +http_archive = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + +http_archive( + name = "rules_swift_index_import_5_8", + build_file = "//third_party:rules_swift_index_import/BUILD.overlay", + canonical_id = "index-import-5.8", + sha256 = "28c1ffa39d99e74ed70623899b207b41f79214c498c603915aef55972a851a15", + urls = ["https://github.com/MobileNativeFoundation/index-import/releases/download/5.8.0.1/index-import.tar.gz"], +) + +http_archive( + name = "rules_swift_index_import_6_1", + build_file = "//third_party:rules_swift_index_import/BUILD.overlay", + canonical_id = "index-import-6.1", + sha256 = "9a54fc1674af6031125a9884480a1e31e1bcf48b8f558b3e8bcc6b6fcd6e8b61", + urls = ["https://github.com/MobileNativeFoundation/index-import/releases/download/6.1.0.1/index-import.tar.gz"], +) + +register_toolchains("//swift/toolchains:all") diff --git a/misc/bazel/registry/modules/rules_swift/4.0.0-rc5-codeql.1/patches/register_downloaded_macos_toolchain.patch b/misc/bazel/registry/modules/rules_swift/4.0.0-rc5-codeql.1/patches/register_downloaded_macos_toolchain.patch new file mode 100644 index 000000000000..029f78c06f03 --- /dev/null +++ b/misc/bazel/registry/modules/rules_swift/4.0.0-rc5-codeql.1/patches/register_downloaded_macos_toolchain.patch @@ -0,0 +1,103 @@ +diff --git a/swift/internal/extensions/toolchains.bzl b/swift/internal/extensions/toolchains.bzl +--- a/swift/internal/extensions/toolchains.bzl ++++ b/swift/internal/extensions/toolchains.bzl +@@ -132,12 +132,11 @@ def toolchains_for_platform(platform, toolchain_repository): + toolchain_repository = toolchain_repository, + ) + +- if platform != "xcode": +- content += _EXEC_TOOLCHAIN_PLATFORM.format( +- exec_compatible_with = _exec_compatible_with_for_platform(platform), +- platform = platform, +- toolchain_repository = toolchain_repository, +- ) ++ content += _EXEC_TOOLCHAIN_PLATFORM.format( ++ exec_compatible_with = _exec_compatible_with_for_platform(platform), ++ platform = platform, ++ toolchain_repository = toolchain_repository, ++ ) + + if platform in ( + "ubuntu22.04", +diff --git a/swift/toolchains/swift_toolchain.bzl b/swift/toolchains/swift_toolchain.bzl +--- a/swift/toolchains/swift_toolchain.bzl ++++ b/swift/toolchains/swift_toolchain.bzl +@@ -605,10 +605,14 @@ def _parse_target_system_name(*, arch, os, target_system_name): + """Returns the target system name set by the CC toolchain or attempts to create one based on the OS and arch.""" + + if target_system_name and target_system_name != "local": ++ if os == "macos" and target_system_name.endswith(("-macos", "-macosx")): ++ return target_system_name + "10.15" + return target_system_name + + if os == "linux": + return "%s-unknown-linux-gnu" % arch ++ elif os == "macos": ++ return "%s-apple-macos10.15" % arch + elif os == "windows": + # The MSVC cc toolchain reports a `target_gnu_system_name` of "local", + # so synthesize the triple. +@@ -706,5 +710,16 @@ def _swift_toolchain_impl(ctx): + elif ctx.attr.os == "none": + swift_linkopts_cc_info = CcInfo() ++ elif ctx.attr.os == "macos": ++ macos_linkopts = ["-L{}".format(paths.join(toolchain_root, "lib/swift/macosx"))] ++ if sdkroot: ++ macos_linkopts.append("-L{}".format(paths.join(sdkroot, "usr/lib/swift"))) ++ swift_linkopts_cc_info = _swift_sdk_linkopts_cc_info( ++ ctx.label, ++ macos_linkopts, ++ ctx.attr.swift_tools[SwiftToolsInfo].additional_inputs if ctx.attr.swift_tools else [], ++ ) ++ dynamic_runtime_cc_info = None ++ static_runtime_cc_info = None + elif ctx.attr.os == "android": + if not sdkroot: + fail("Android toolchain requires a sysroot to be set, either via the `sdkroot` attribute or by using a CC toolchain that provides one.") +diff --git a/swift/internal/extensions/toolchain.BUILD b/swift/internal/extensions/toolchain.BUILD +--- a/swift/internal/extensions/toolchain.BUILD ++++ b/swift/internal/extensions/toolchain.BUILD +@@ -333,17 +333,22 @@ swift_toolchain( + features = [ + "swift._supports_upcoming_features", + "swift.no_embed_debug_module", +- "swift.use_autolink_extract", +- "swift.lld_gc_workaround", +- "swift.use_module_wrap", + # TODO: This should be removed so that private headers can be used with + # explicit modules, but the build targets for CgRPC need to be cleaned up + # first because they contain C++ code. + "swift.module_map_no_private_headers", +- ], ++ ] + select({ ++ "@platforms//os:linux": [ ++ "swift.lld_gc_workaround", ++ "swift.use_autolink_extract", ++ "swift.use_module_wrap", ++ ], ++ "//conditions:default": [], ++ }), + os = select({ + "@platforms//os:linux": "linux", + "@platforms//os:macos": "macos", + }), + parsed_version = "{swift_version}", ++ sdkroot = "{macos_sdkroot}", + static_runtime = select({ +diff --git a/swift/internal/extensions/standalone_toolchain.bzl b/swift/internal/extensions/standalone_toolchain.bzl +--- a/swift/internal/extensions/standalone_toolchain.bzl ++++ b/swift/internal/extensions/standalone_toolchain.bzl +@@ -91,11 +91,13 @@ def _standalone_toolchain_impl(repository_ctx): + strip_prefix = filename.removesuffix(".tar.gz"), + ) + ++ macos_sdkroot = _run(repository_ctx, ["xcrun", "--sdk", "macosx", "--show-sdk-path"]) if repository_ctx.attr.platform == "xcode" else "" + repository_ctx.file(".swift-version", repository_ctx.attr.swift_version) + repository_ctx.template( + "BUILD.bazel", + repository_ctx.attr._build_template, + substitutions = { ++ "{macos_sdkroot}": macos_sdkroot, + "{swift_version}": repository_ctx.attr.swift_version, + }, + ) diff --git a/misc/bazel/registry/modules/rules_swift/4.0.0-rc5-codeql.1/source.json b/misc/bazel/registry/modules/rules_swift/4.0.0-rc5-codeql.1/source.json new file mode 100644 index 000000000000..fd5c4f2047e7 --- /dev/null +++ b/misc/bazel/registry/modules/rules_swift/4.0.0-rc5-codeql.1/source.json @@ -0,0 +1,8 @@ +{ + "integrity": "sha256-Ly2lS4AlZJMiyqAxKHyCB+2pGeP5aYkQ6zv8QheeSTI=", + "url": "https://github.com/bazelbuild/rules_swift/releases/download/4.0.0-rc5/rules_swift.4.0.0-rc5.tar.gz", + "patches": { + "register_downloaded_macos_toolchain.patch": "sha256-kFzGyE1MhhiDxUfEzRPUTahvycyy+VNgPzQ5I44zRYc=" + }, + "patch_strip": 1 +} diff --git a/misc/bazel/registry/modules/rules_swift/metadata.json b/misc/bazel/registry/modules/rules_swift/metadata.json new file mode 100644 index 000000000000..188799c9dbf9 --- /dev/null +++ b/misc/bazel/registry/modules/rules_swift/metadata.json @@ -0,0 +1,11 @@ +{ + "homepage": "https://github.com/bazelbuild/rules_swift", + "maintainers": [], + "repository": [ + "github:bazelbuild/rules_swift" + ], + "versions": [ + "4.0.0-rc5-codeql.1" + ], + "yanked_versions": {} +} diff --git a/unified/swift-syntax-rs/BUILD.bazel b/unified/swift-syntax-rs/BUILD.bazel index 95f644b200f4..91a28dc40505 100644 --- a/unified/swift-syntax-rs/BUILD.bazel +++ b/unified/swift-syntax-rs/BUILD.bazel @@ -1,9 +1,9 @@ load("@rules_cc//cc:defs.bzl", "cc_library") load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_library", "rust_test") +load("@rules_swift//swift:swift.bzl", "swift_library") load("//unified:platforms.bzl", "UNIFIED_SUPPORTED_PLATFORMS") load(":swift_runtime.bzl", "swift_runtime_libs") load(":swift_runtime_linking.bzl", "swift_runtime_linking") -load(":xcode_transition.bzl", "xcode_transition_swift_library") package(default_visibility = ["//visibility:public"]) @@ -34,7 +34,7 @@ cc_library( ) # Swift FFI shim: wraps swift-syntax and exposes a small C ABI. -xcode_transition_swift_library( +swift_library( name = "swift_syntax_ffi", srcs = ["swift/Sources/SwiftSyntaxFFI/SwiftSyntaxFFI.swift"], module_name = "SwiftSyntaxFFI", diff --git a/unified/swift-syntax-rs/README.md b/unified/swift-syntax-rs/README.md index f4e84e18f361..299fc40951a6 100644 --- a/unified/swift-syntax-rs/README.md +++ b/unified/swift-syntax-rs/README.md @@ -174,26 +174,20 @@ Requirements: - **`clang`** must be installed on the runner. `rules_swift` requires the Bazel CC toolchain to use clang; the repo's `.bazelrc` already sets `--repo_env=CC=clang`, so no extra flags are needed. -- The registered Swift toolchains cover **ubuntu24.04 / x86_64** and - **macOS / `xcode`** (Apple Silicon and Intel). Bazel selects the toolchain - matching the host. Targets are marked `target_compatible_with` these two - OSes, so on Windows Bazel skips them cleanly. -- **macOS only:** the Swift toolchain comes from the host Xcode installation - (`rules_swift` auto-registers `xcode_swift_toolchain`), which also needs - Xcode's CC toolchain and xcode_config; these are applied to the Swift - target via an incoming-edge Starlark transition (see - [`xcode_transition.bzl`](xcode_transition.bzl)), so other targets on macOS - keep using Bazel's default CC toolchain. +- The registered Swift toolchains cover **ubuntu22.04 / x86_64** and + **macOS** (Apple Silicon and Intel). Bazel selects the toolchain matching the + host. Targets are marked `target_compatible_with` these two OSes, so on + Windows Bazel skips them cleanly. +- **macOS only:** `rules_swift` downloads the pinned Swift toolchain from + swift.org. The Bazel C++ toolchain must still provide the macOS SDK, but a + full Xcode installation is not required. The Swift compiler version is kept in sync across three places: the [`.swift-version`](.swift-version) file (read by the local `cargo`/`swift build` and by [swiftly](https://www.swift.org/swiftly/)), the literal `swift_version` pinned on `swift.toolchain(...)` in the root `MODULE.bazel` (the hermetic -swift.org **Linux** Bazel toolchain), and the `swift-syntax` release in -`swift/Package.swift`. On **macOS** the version is *not* pinned by the Bazel -build: `rules_swift` auto-registers the host `xcode_swift_toolchain`, which uses -whichever Swift ships with the installed Xcode. So the pin governs Linux (and -local) builds, while the macOS compiler version depends on the host Xcode. +swift.org Bazel toolchain), and the `swift-syntax` release in +`swift/Package.swift`. (The Bazel toolchain pins a literal rather than reading `.swift-version` via `swift_version_file`, because the latter makes the module extension read a diff --git a/unified/swift-syntax-rs/xcode_transition.bzl b/unified/swift-syntax-rs/xcode_transition.bzl deleted file mode 100644 index 9783c0fc8719..000000000000 --- a/unified/swift-syntax-rs/xcode_transition.bzl +++ /dev/null @@ -1,92 +0,0 @@ -"""Per-target Xcode configuration for `//unified/swift-syntax-rs` on macOS. - -`rules_swift`'s auto-registered `xcode_swift_toolchain` reads -`cc_toolchain.target_gnu_system_name`, which is literally "local" on -Bazel's built-in `local_config_cc`. To make it usable we need: - -- `--xcode_version_config=@local_config_xcode//:host_xcodes` — selects - `apple_support`'s xcode_config (matches `rules_swift`'s `system_sdk` keys). -- `--extra_toolchains=@local_config_apple_cc_toolchains//:all` — forces - `apple_support`'s CC toolchain ahead of `local_config_cc`. - -Applied via an incoming-edge Starlark transition on the `swift_library` -target only (via the `xcode_transition_swift_library` macro), so downstream -Rust targets and the rest of the repo stay on the default CC toolchain and -the `@local_config_*` repos are not materialized otherwise. No-op off macOS. -""" - -load("@rules_cc//cc/common:cc_info.bzl", "CcInfo") -load("@rules_swift//swift:swift.bzl", "swift_library") -load("//misc/bazel:os.bzl", "os_select") - -_XCODE_VERSION_CONFIG = "//command_line_option:xcode_version_config" -_EXTRA_TOOLCHAINS = "//command_line_option:extra_toolchains" - -def _transition_impl(settings, attr): - if attr.os != "macos": - return {} - else: - return { - _XCODE_VERSION_CONFIG: "@local_config_xcode//:host_xcodes", - _EXTRA_TOOLCHAINS: ( - list(settings[_EXTRA_TOOLCHAINS]) + - ["@local_config_apple_cc_toolchains//:all"] - ), - } - -_xcode_transition = transition( - implementation = _transition_impl, - inputs = [_EXTRA_TOOLCHAINS], - outputs = [_XCODE_VERSION_CONFIG, _EXTRA_TOOLCHAINS], -) - -def _wrapper_impl(ctx): - src = ctx.attr.actual[0] - - # Forward the providers a downstream `rust_*` target reads from `deps`: - # `DefaultInfo`, `CcInfo` (linking info), and `OutputGroupInfo`. - providers = [src[DefaultInfo]] - for p in (CcInfo, OutputGroupInfo): - if p in src: - providers.append(src[p]) - return providers - -_xcode_transition_swift_library_rule = rule( - implementation = _wrapper_impl, - attrs = { - "actual": attr.label( - mandatory = True, - cfg = _xcode_transition, - providers = [CcInfo], - ), - "os": attr.string(mandatory = True), - "_allowlist_function_transition": attr.label( - default = "@bazel_tools//tools/allowlists/function_transition_allowlist", - ), - }, -) - -def xcode_transition_swift_library(name, visibility = None, tags = None, target_compatible_with = None, **kwargs): - """`swift_library` wrapped in the macOS Xcode-config transition. - - Emits a private inner `_impl_` `swift_library` (tagged `manual`) - and a public `name` that applies the transition on macOS and forwards - the inner target's providers. Downstream `rust_*` targets depend on - `name` as usual; only the `swift_library` sub-graph flips toolchain. - """ - inner_name = "_impl_%s" % name - swift_library( - name = inner_name, - visibility = ["//visibility:private"], - tags = (tags or []) + ["manual"], - target_compatible_with = target_compatible_with, - **kwargs - ) - _xcode_transition_swift_library_rule( - name = name, - visibility = visibility, - tags = tags, - target_compatible_with = target_compatible_with, - actual = ":" + inner_name, - os = os_select(linux = "linux", macos = "macos", default = "other"), - )