From 9a6d29c4ba5df4bd5089edb0f7f0fcf8688ad80c Mon Sep 17 00:00:00 2001 From: Adin Cebic Date: Wed, 8 Jul 2026 08:19:14 +0200 Subject: [PATCH 1/4] Cross compile to Linux --- MODULE.bazel | 8 +- doc/standalone_toolchain.md | 30 +++ .../static_linux/BUILD.bazel | 32 +++ .../cross_compilation/static_linux/README.md | 11 ++ .../Sources/Greeter/Greeter.swift | 14 ++ .../Sources/HelloStaticLinux/main.swift | 3 + .../static_linux/static_linux.MODULE.bazel | 20 ++ swift/BUILD | 2 + swift/extensions.bzl | 140 ++++++++++++-- .../extensions/swift_sdk_releases.bzl | 26 +++ swift/internal/extensions/swift_sdks.bzl | 183 +++++++++++++++++- swift/internal/extensions/toolchains.bzl | 40 +++- swift/toolchains/BUILD | 11 ++ test/fixtures/toolchains/BUILD | 119 ++++++++++++ test/fixtures/toolchains/fake_tool.sh | 2 + .../toolchains/static_linux_cc_uses_libcxx.cc | 6 + test/swift_toolchain_tests.bzl | 38 ++++ test/utils_tests.bzl | 29 ++- 18 files changed, 681 insertions(+), 33 deletions(-) create mode 100644 examples/cross_compilation/static_linux/BUILD.bazel create mode 100644 examples/cross_compilation/static_linux/README.md create mode 100644 examples/cross_compilation/static_linux/Sources/Greeter/Greeter.swift create mode 100644 examples/cross_compilation/static_linux/Sources/HelloStaticLinux/main.swift create mode 100644 examples/cross_compilation/static_linux/static_linux.MODULE.bazel create mode 100644 test/fixtures/toolchains/fake_tool.sh create mode 100644 test/fixtures/toolchains/static_linux_cc_uses_libcxx.cc diff --git a/MODULE.bazel b/MODULE.bazel index 6b6a74319..94f1e71b7 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -145,8 +145,6 @@ http_archive( urls = ["https://github.com/MobileNativeFoundation/index-import/releases/download/6.1.0.1/index-import.tar.gz"], ) -register_toolchains("//swift/toolchains:all") - system_sdk = use_extension("//swift:extensions.bzl", "system_sdk") system_sdk.configure_sdks( # NOTE: This doesn't apply to downstream repos @@ -219,6 +217,12 @@ register_toolchains( include("//examples/cross_compilation/android_app:android.MODULE.bazel") include("//examples/cross_compilation/wasm:wasm.MODULE.bazel") +include("//examples/cross_compilation/static_linux:static_linux.MODULE.bazel") + +# Keep broad built-in Linux toolchains after Static Linux SDK toolchains: +# Static Linux platforms are also `@platforms//os:linux`, and Bazel chooses the +# first compatible toolchain. +register_toolchains("//swift/toolchains:all") # Dev dependencies bazel_dep(name = "bazel_skylib_gazelle_plugin", version = "1.5.0", dev_dependency = True) diff --git a/doc/standalone_toolchain.md b/doc/standalone_toolchain.md index ee7e5d256..413bf70fd 100644 --- a/doc/standalone_toolchain.md +++ b/doc/standalone_toolchain.md @@ -238,6 +238,36 @@ linked statically from the SDK, so the reactor is a self-contained See `examples/cross_compilation/wasm` for an end to end example. +## Building for Static Linux + +The `swift` module extension can also download the Static Linux Swift SDK, +which defines matching Swift and C/C++ toolchains targeting +`x86_64-swift-linux-musl` and `aarch64-swift-linux-musl`. + +Add the `static_linux_sdk` tag, referencing the `toolchain` tag by name (the +Swift module format is not stable across compiler versions, so the SDK is +always downloaded for exactly the toolchain's version): + +```bzl +swift.static_linux_sdk(toolchain_name = "swift_toolchain") + +register_toolchains( + "@swift_toolchain//:swift_toolchain_static_linux_x86_64_xcode", + "@swift_toolchain//:cc_toolchain_static_linux_x86_64_xcode", +) +``` + +Then build with a platform that has `@platforms//os:linux`, +`@platforms//cpu:x86_64` or `@platforms//cpu:aarch64`, and +`@rules_swift//swift/toolchains:static_linux` constraints. + +Register Static Linux SDK toolchains before any generic same-architecture Linux +Swift toolchains (for example `//swift/toolchains:all`). Static Linux platforms +still carry `@platforms//os:linux`, so a generic Linux toolchain can also match; +Bazel uses registration order to choose among compatible toolchains. + +See `examples/cross_compilation/static_linux` for an end to end example. + ## Using the extension from a non-root module The extension is intended for the root module — it fails if a non-root diff --git a/examples/cross_compilation/static_linux/BUILD.bazel b/examples/cross_compilation/static_linux/BUILD.bazel new file mode 100644 index 000000000..1a227f2ab --- /dev/null +++ b/examples/cross_compilation/static_linux/BUILD.bazel @@ -0,0 +1,32 @@ +load("//examples/embedded:transition.bzl", "transition_binary") +load("//swift:swift.bzl", "swift_binary", "swift_library") + +platform( + name = "static-linux-x86_64", + constraint_values = [ + "@platforms//cpu:x86_64", + "@platforms//os:linux", + "//swift/toolchains:static_linux", + ], +) + +swift_library( + name = "Greeter", + srcs = ["Sources/Greeter/Greeter.swift"], + module_name = "Greeter", +) + +# This only builds for the Static Linux SDK platform configured by the +# transition below, so the //examples/... wildcard skips it on a host platform. +swift_binary( + name = "HelloStaticLinux", + srcs = ["Sources/HelloStaticLinux/main.swift"], + target_compatible_with = ["//swift/toolchains:static_linux"], + deps = [":Greeter"], +) + +transition_binary( + name = "hello_static_linux", + binary = ":HelloStaticLinux", + platform = ":static-linux-x86_64", +) diff --git a/examples/cross_compilation/static_linux/README.md b/examples/cross_compilation/static_linux/README.md new file mode 100644 index 000000000..073901dd7 --- /dev/null +++ b/examples/cross_compilation/static_linux/README.md @@ -0,0 +1,11 @@ +# Building Swift for Static Linux + +A simple executable that cross-compiles Swift to a fully static musl binary with +the Static Linux Swift SDK. See `doc/standalone_toolchain.md` for the toolchain +setup. + +## Build + +```sh +bazel build //examples/cross_compilation/static_linux:hello_static_linux +``` diff --git a/examples/cross_compilation/static_linux/Sources/Greeter/Greeter.swift b/examples/cross_compilation/static_linux/Sources/Greeter/Greeter.swift new file mode 100644 index 000000000..4993d1ca3 --- /dev/null +++ b/examples/cross_compilation/static_linux/Sources/Greeter/Greeter.swift @@ -0,0 +1,14 @@ +/// A plain `swift_library` used as a normal dependency of the Static Linux +/// executable. Nothing in here is platform-specific; it is compiled for +/// whichever platform the depending target is built for. +public struct Greeter { + private let subject: String + + public init(subject: String) { + self.subject = subject + } + + public func greeting() -> String { + return "Hello, \(subject)!" + } +} diff --git a/examples/cross_compilation/static_linux/Sources/HelloStaticLinux/main.swift b/examples/cross_compilation/static_linux/Sources/HelloStaticLinux/main.swift new file mode 100644 index 000000000..d3d59ccf6 --- /dev/null +++ b/examples/cross_compilation/static_linux/Sources/HelloStaticLinux/main.swift @@ -0,0 +1,3 @@ +import Greeter + +print(Greeter(subject: "Static Linux").greeting()) diff --git a/examples/cross_compilation/static_linux/static_linux.MODULE.bazel b/examples/cross_compilation/static_linux/static_linux.MODULE.bazel new file mode 100644 index 000000000..70c9f63b3 --- /dev/null +++ b/examples/cross_compilation/static_linux/static_linux.MODULE.bazel @@ -0,0 +1,20 @@ +swift = use_extension("//swift:extensions.bzl", "swift", dev_dependency = True) +swift.static_linux_sdk(toolchain_name = "swift_toolchain") + +register_toolchains( + # Register Static Linux before the broad built-in Linux toolchains in the + # root MODULE.bazel; Static Linux platforms are also @platforms//os:linux. + "@swift_toolchain//:cc_toolchain_static_linux_aarch64_ubuntu22.04", + "@swift_toolchain//:cc_toolchain_static_linux_aarch64_ubuntu22.04-aarch64", + "@swift_toolchain//:cc_toolchain_static_linux_aarch64_xcode", + "@swift_toolchain//:cc_toolchain_static_linux_x86_64_ubuntu22.04", + "@swift_toolchain//:cc_toolchain_static_linux_x86_64_ubuntu22.04-aarch64", + "@swift_toolchain//:cc_toolchain_static_linux_x86_64_xcode", + "@swift_toolchain//:swift_toolchain_static_linux_aarch64_ubuntu22.04", + "@swift_toolchain//:swift_toolchain_static_linux_aarch64_ubuntu22.04-aarch64", + "@swift_toolchain//:swift_toolchain_static_linux_aarch64_xcode", + "@swift_toolchain//:swift_toolchain_static_linux_x86_64_ubuntu22.04", + "@swift_toolchain//:swift_toolchain_static_linux_x86_64_ubuntu22.04-aarch64", + "@swift_toolchain//:swift_toolchain_static_linux_x86_64_xcode", + dev_dependency = True, +) diff --git a/swift/BUILD b/swift/BUILD index caa50d2bc..ecf8dcd24 100644 --- a/swift/BUILD +++ b/swift/BUILD @@ -23,6 +23,8 @@ bzl_library( deps = [ "//swift/internal/extensions:standalone_toolchain", "//swift/internal/extensions:swift_releases", + "//swift/internal/extensions:swift_sdk_releases", + "//swift/internal/extensions:swift_sdks", "//swift/internal/extensions:toolchains", ], ) diff --git a/swift/extensions.bzl b/swift/extensions.bzl index 4e43318d1..97f18f086 100644 --- a/swift/extensions.bzl +++ b/swift/extensions.bzl @@ -19,17 +19,21 @@ load("//swift/internal/extensions:swift_releases.bzl", "SWIFT_RELEASES") load( "//swift/internal/extensions:swift_sdk_releases.bzl", "SWIFT_SDK_RELEASES", + "static_linux_sdk_download_url", "swift_sdk_download_url", ) load( "//swift/internal/extensions:swift_sdks.bzl", "ANDROID_ARCHS", + "STATIC_LINUX_ARCHS", "swift_android_sdk_repository", + "swift_static_linux_sdk_repository", "swift_wasm_sdk_repository", ) load( "//swift/internal/extensions:toolchains.bzl", "android_sdk_toolchains_for_platform", + "static_linux_sdk_toolchains_for_platform", "toolchains_for_platform", "toolchains_repository", "wasm_sdk_toolchains_for_platform", @@ -116,6 +120,62 @@ def _setup_wasm_sdk(*, tag, toolchain_name, swift_version, platforms): ) return build_file_content +def _setup_static_linux_sdk(*, tag, toolchain_name, swift_version, platforms): + """Creates the repositories for a `swift.static_linux_sdk` tag. + + Args: + tag: The `static_linux_sdk` tag. + toolchain_name: The name of the `swift.toolchain` tag the SDK extends. + swift_version: The Swift release version of that toolchain. + platforms: The host platforms the toolchain was created for. + + Returns: + BUILD file content with the `toolchain` declarations to add to the + toolchains hub repository. + """ + release = None + if swift_version in SWIFT_SDK_RELEASES: + release = SWIFT_SDK_RELEASES[swift_version].get("static_linux") + + sdk_version = tag.sdk_version + if not sdk_version: + if not release: + fail("No known Static Linux Swift SDK version for Swift `{}`. Please provide sdk_version.".format( + swift_version, + )) + sdk_version = release["version"] + + sha256 = tag.sha256 + if not sha256: + if not release: + fail("No known Static Linux Swift SDK for version `{}`. Please choose one of {}, or provide the SDK's sha256 and sdk_version.".format( + swift_version, + SWIFT_SDK_RELEASES.keys(), + )) + if sdk_version != release["version"]: + fail("No known checksum for Static Linux Swift SDK version `{}` for Swift `{}`. Please provide sha256 when overriding sdk_version.".format( + sdk_version, + swift_version, + )) + sha256 = release["sha256"] + + build_file_content = "" + for platform in platforms: + repository_name = "{}_static_linux_sdk_{}".format(toolchain_name, platform) + swift_static_linux_sdk_repository( + name = repository_name, + sha256 = sha256, + swift_version = swift_version, + toolchain_repo = "{}_{}".format(toolchain_name, platform), + url = static_linux_sdk_download_url(swift_version, sdk_version), + ) + build_file_content += static_linux_sdk_toolchains_for_platform( + platform = platform, + sdk_repository = repository_name, + archs = STATIC_LINUX_ARCHS, + ) + return build_file_content + def _sdk_tags_by_toolchain_name(tags, kind): """Groups SDK tags by the toolchain they extend, rejecting duplicates.""" tags_by_name = {} @@ -146,23 +206,27 @@ def _standalone_toolchain_impl(module_ctx): root_module.tags.wasm_sdk, "wasm_sdk", ) + static_linux_sdk_tags = _sdk_tags_by_toolchain_name( + root_module.tags.static_linux_sdk, + "static_linux_sdk", + ) toolchain_names = [ toolchain.name for toolchain in root_module.tags.toolchain ] - for toolchain_name in android_sdk_tags: - if toolchain_name not in toolchain_names: - fail("The `android_sdk` tag references unknown toolchain `{}`. Please use the name of a `toolchain` tag: {}".format( - toolchain_name, - toolchain_names, - )) - for toolchain_name in wasm_sdk_tags: - if toolchain_name not in toolchain_names: - fail("The `wasm_sdk` tag references unknown toolchain `{}`. Please use the name of a `toolchain` tag: {}".format( - toolchain_name, - toolchain_names, - )) + for kind, tags in ( + ("android_sdk", android_sdk_tags), + ("wasm_sdk", wasm_sdk_tags), + ("static_linux_sdk", static_linux_sdk_tags), + ): + for toolchain_name in tags: + if toolchain_name not in toolchain_names: + fail("The `{}` tag references unknown toolchain `{}`. Please use the name of a `toolchain` tag: {}".format( + kind, + toolchain_name, + toolchain_names, + )) toolchains_build_file_content = "" for toolchain in root_module.tags.toolchain: @@ -211,6 +275,13 @@ def _standalone_toolchain_impl(module_ctx): swift_version = swift_version, platforms = platforms, ) + if toolchain.name in static_linux_sdk_tags: + toolchains_build_file_content += _setup_static_linux_sdk( + tag = static_linux_sdk_tags[toolchain.name], + toolchain_name = toolchain.name, + swift_version = swift_version, + platforms = platforms, + ) toolchains_repository( name = toolchain.name, @@ -257,6 +328,50 @@ and defines Swift and C++ toolchains targeting `wasm32-unknown-wasip1`. """, ) +_static_linux_sdk = tag_class( + attrs = { + "sdk_version": attr.string( + doc = """\ +The Static Linux SDK version in the artifact bundle filename. May be omitted +for Swift/SDK version pairs known to this version of rules_swift. If this +overrides the known SDK version, `sha256` must also be provided. +""", + ), + "sha256": attr.string( + doc = """\ +The expected SHA-256 of the SDK artifact bundle. May be omitted only for +Swift/SDK version pairs known to this version of rules_swift. +""", + ), + "toolchain_name": attr.string( + doc = "The name of the `toolchain` tag to add this Swift SDK to.", + mandatory = True, + ), + }, + doc = """\ +Downloads the Static Linux Swift SDK matching a `toolchain` tag's Swift version +and defines Swift and C++ toolchains targeting `x86_64-swift-linux-musl` and +`aarch64-swift-linux-musl`. + +Register the generated toolchains for the host platforms you build on, e.g.: + +```starlark +register_toolchains( + "@swift_toolchain//:swift_toolchain_static_linux_x86_64_xcode", + "@swift_toolchain//:cc_toolchain_static_linux_x86_64_xcode", +) +``` + +and build with a platform that has `@platforms//os:linux`, +`@platforms//cpu:x86_64` (or `aarch64`), and +`@rules_swift//swift/toolchains:static_linux` constraints. + +On Linux hosts, register the Static Linux SDK toolchains before generic +same-architecture Linux Swift toolchains, since both can match a Static Linux +platform and Bazel chooses by registration order. +""", +) + _toolchain = tag_class(attrs = { "name": attr.string( doc = "Repository name of the generated toolchain", @@ -278,6 +393,7 @@ swift = module_extension( implementation = _standalone_toolchain_impl, tag_classes = { "android_sdk": _android_sdk, + "static_linux_sdk": _static_linux_sdk, "toolchain": _toolchain, "wasm_sdk": _wasm_sdk, }, diff --git a/swift/internal/extensions/swift_sdk_releases.bzl b/swift/internal/extensions/swift_sdk_releases.bzl index ae0a28a50..bb28baddb 100644 --- a/swift/internal/extensions/swift_sdk_releases.bzl +++ b/swift/internal/extensions/swift_sdk_releases.bzl @@ -14,6 +14,10 @@ https://www.swift.org/api/v1/install/releases.json. SWIFT_SDK_RELEASES = { "6.3.2": { "android": "939e933549d12d28f2e0bf71019d734d309859e9773c572657ce565a81f85d68", + "static_linux": { + "sha256": "3fd798bef6f4408f1ea5a6f94ce4d4052830c4326ab85ebc04f983f01b3da407", + "version": "0.1.0", + }, "wasm": "a61f0584c93283589f8b2f42db05c1f9a182b506c2957271402992655591dd7c", }, } @@ -39,3 +43,25 @@ def swift_sdk_download_url(swift_version, sdk): sdk = sdk, version = swift_version, ) + +def static_linux_sdk_download_url(swift_version, sdk_version): + """Returns the download URL for a Static Linux Swift SDK artifact bundle. + + Args: + swift_version: The Swift release version (e.g. "6.3.2"). + sdk_version: The Static Linux SDK version (e.g. "0.1.0"). + + Returns: + The URL of the `.artifactbundle.tar.gz` for the given release. + """ + if "-snapshot-" in swift_version: + fail("Swift SDKs are only supported for release versions, got `{}`".format( + swift_version, + )) + return ( + "https://download.swift.org/swift-{version}-release/static-sdk/" + + "swift-{version}-RELEASE/swift-{version}-RELEASE_static-linux-{sdk_version}.artifactbundle.tar.gz" + ).format( + sdk_version = sdk_version, + version = swift_version, + ) diff --git a/swift/internal/extensions/swift_sdks.bzl b/swift/internal/extensions/swift_sdks.bzl index 1ccad94d4..b77dd84fa 100644 --- a/swift/internal/extensions/swift_sdks.bzl +++ b/swift/internal/extensions/swift_sdks.bzl @@ -3,12 +3,12 @@ A "Swift SDK" is an artifact bundle published by swift.org for cross-compiling Swift to a platform the host toolchain cannot target by itself (the bundles that `swift sdk install` consumes). The per-platform extensions (`android_sdk`, -`wasm_sdk`) define repository rules that download such a bundle and generate a -`swift_toolchain` for the target; this module holds the helpers and BUILD-file -templates they share. Android's C/C++ compilation and linking go through a -separately registered Android cc toolchain (e.g. `@androidndk//:all`), while the -WebAssembly repository also generates a rules_cc `cc_toolchain` that drives the -paired toolchain's clang. +`wasm_sdk`, `static_linux_sdk`) define repository rules that download such a +bundle and generate a `swift_toolchain` for the target; this module holds the +helpers and BUILD-file templates they share. Android's C/C++ compilation and +linking go through a separately registered Android cc toolchain (e.g. +`@androidndk//:all`), while the WebAssembly and Static Linux repositories also +generate rules_cc `cc_toolchain` targets that drive the paired toolchain's clang. Because the Swift module format is not stable across compiler versions, a Swift SDK must come from exactly the same release as the host toolchain it is paired @@ -52,9 +52,9 @@ swift_tools( ) """ -# The WebAssembly repository also generates a rules_cc cc_toolchain, so its -# BUILD header needs the rules_cc toolchain loads. -_WASM_BUILD_HEADER_TEMPLATE = """\ +# Some SDK repositories also generate a rules_cc cc_toolchain, so their BUILD +# header needs the rules_cc toolchain loads. +_CC_BUILD_HEADER_TEMPLATE = """\ load("@rules_cc//cc/toolchains:args.bzl", "cc_args") load("@rules_cc//cc/toolchains:make_variable.bzl", "cc_make_variable") load("@rules_cc//cc/toolchains:tool.bzl", "cc_tool") @@ -207,6 +207,29 @@ def _download_sdk_bundle(repository_ctx): )) return bundles[0] +def _relative_metadata_path(value, field, triple): + """Validates a path read from SDK metadata.""" + if type(value) != "string" or not value: + fail("Expected `{}` for `{}` in swift-sdk.json to be a non-empty string.".format( + field, + triple, + )) + if value.startswith("/") or ".." in value.split("/"): + fail("Expected `{}` for `{}` in swift-sdk.json to be a relative path below the SDK directory, got `{}`.".format( + field, + triple, + value, + )) + return value + +def _static_linux_resource_path(target_settings, triple): + resource_path = target_settings.get("swiftStaticResourcesPath") + field = "swiftStaticResourcesPath" + if not resource_path: + resource_path = target_settings.get("swiftResourcesPath") + field = "swiftResourcesPath" + return _relative_metadata_path(resource_path, field, triple) + def _common_attrs(): return { "sha256": attr.string( @@ -347,7 +370,7 @@ def _swift_wasm_sdk_impl(repository_ctx): wasi_sdk = sdk_dir + "/WASI.sdk" resource_dir = sdk_dir + "/swift.xctoolchain/usr/lib/swift_static" - build_content = _WASM_BUILD_HEADER_TEMPLATE.format( + build_content = _CC_BUILD_HEADER_TEMPLATE.format( bundle_dir = bundle_dir, compiler_inputs = _build_list([ ":sdk_files", @@ -434,3 +457,143 @@ toolchain's compiler. """, implementation = _swift_wasm_sdk_impl, ) + +# The architectures the Static Linux Swift SDK provides resources for and that +# `@platforms//cpu` can express. +STATIC_LINUX_ARCHS = ["aarch64", "x86_64"] + +def _swift_static_linux_sdk_impl(repository_ctx): + bundle_dir = _download_sdk_bundle(repository_ctx) + toolchain_repo = repository_ctx.attr.toolchain_repo + + repo_root = "external/" + repository_ctx.name + sdk_dir_relative = "{}/{}/swift-linux-musl".format( + bundle_dir, + bundle_dir.removesuffix(".artifactbundle"), + ) + if not repository_ctx.path(sdk_dir_relative + "/swift-sdk.json").exists: + fail("The Static Linux Swift SDK bundle has an unexpected layout; " + + "missing {}/{}/swift-sdk.json".format(repo_root, sdk_dir_relative)) + swift_sdk_metadata = json.decode( + repository_ctx.read(sdk_dir_relative + "/swift-sdk.json"), + ) + target_triples = swift_sdk_metadata.get("targetTriples") + if type(target_triples) != "dict": + fail("The Static Linux Swift SDK bundle has an unexpected layout; " + + "swift-sdk.json is missing `targetTriples`.") + + build_content = _CC_BUILD_HEADER_TEMPLATE.format( + bundle_dir = bundle_dir, + compiler_inputs = _build_list([ + ":sdk_files", + "@{}//:swift_sdk_compiler_inputs".format(toolchain_repo), + ]), + toolchain_repo = toolchain_repo, + ) + + build_content += _CC_TOOLCHAIN_TEMPLATE.format( + ar = "@{}//:usr/bin/llvm-ar".format(toolchain_repo), + clang = "@{}//:usr/bin/clang".format(toolchain_repo), + clang_data = _build_list([ + ":sdk_files", + "@{}//:swift_sdk_linker_inputs".format(toolchain_repo), + ]), + ) + + for arch in STATIC_LINUX_ARCHS: + triple = "{}-swift-linux-musl".format(arch) + suffix = "static_linux_{}".format(arch) + target_settings = target_triples.get(triple) + if type(target_settings) != "dict": + fail("The Static Linux Swift SDK bundle does not define target triple `{}`.".format( + triple, + )) + sdkroot_relative = "{}/{}".format( + sdk_dir_relative, + _relative_metadata_path( + target_settings.get("sdkRootPath"), + "sdkRootPath", + triple, + ), + ) + resource_dir_relative = "{}/{}".format( + sdk_dir_relative, + _static_linux_resource_path(target_settings, triple), + ) + sdkroot = "{}/{}".format(repo_root, sdkroot_relative) + if not repository_ctx.path(sdkroot_relative).exists: + fail("The Static Linux Swift SDK bundle has an unexpected layout; " + + "missing " + sdkroot) + resource_dir = "{}/{}".format(repo_root, resource_dir_relative) + if not repository_ctx.path(resource_dir_relative).exists: + fail("The Static Linux Swift SDK bundle has an unexpected layout; " + + "missing " + resource_dir) + linux_static_dir = resource_dir + "/linux-static" + + build_content += _SWIFT_TOOLCHAIN_TEMPLATE.format( + arch = arch, + copts = _build_list([ + "-resource-dir", + resource_dir, + ]), + features = _build_list([ + "swift.module_map_no_private_headers", + "swift.no_embed_debug_module", + "swift.use_autolink_extract", + ]), + linker_inputs = _build_list([":sdk_files"]), + # These are the runtime objects and libraries that `swiftc` adds + # for a Static Linux executable; see + # `swift_static/linux-static/static-executable-args.lnk` in the SDK. + linkopts = _build_list([ + "{}/{}/swiftrt.o".format(linux_static_dir, arch), + "-L{}".format(linux_static_dir), + "-static", + "-lswiftCore", + "-lswift_RegexParser", + "-Wl,-u,pthread_self", + "-Wl,-u,pthread_once", + "-Wl,-u,pthread_key_create", + "-ldispatch", + "-lBlocksRuntime", + "-lpthread", + "-ldl", + "-lc++", + "-lm", + ]), + os = "linux", + sdkroot = sdkroot, + suffix = suffix, + swift_version = repository_ctx.attr.swift_version, + ) + + build_content += _CC_TOOLCHAIN_FOR_TARGET_TEMPLATE.format( + args = _build_list([ + "--target=" + triple, + "--sysroot=" + sdkroot, + "-resource-dir", + resource_dir + "/clang", + ]), + link_args = _build_list([ + "-fuse-ld=lld", + # Pure C++ final links do not see the Swift toolchain's + # linkopts, so the companion CC toolchain must provide the C++ + # runtime itself. + "-static", + "-lc++", + ]), + suffix = suffix, + triple = triple, + ) + + repository_ctx.file("BUILD.bazel", build_content) + +swift_static_linux_sdk_repository = repository_rule( + attrs = _common_attrs(), + doc = """\ +Downloads the Static Linux Swift SDK artifact bundle and defines Swift and C++ +toolchains that target `{aarch64,x86_64}-swift-linux-musl` using a standalone +host toolchain's compiler. +""", + implementation = _swift_static_linux_sdk_impl, +) diff --git a/swift/internal/extensions/toolchains.bzl b/swift/internal/extensions/toolchains.bzl index cb6916ba7..51a80618c 100644 --- a/swift/internal/extensions/toolchains.bzl +++ b/swift/internal/extensions/toolchains.bzl @@ -55,7 +55,7 @@ toolchain( ) """ -_WASM_SDK_TOOLCHAIN_PLATFORM = """ +_CC_SDK_TOOLCHAIN_PLATFORM = """ # Swift SDK toolchains from repository: `{sdk_repository}` toolchain( name = "swift_toolchain_{target}_{platform}", @@ -66,12 +66,6 @@ toolchain( visibility = ["//visibility:public"], ) -# The paired rules_cc toolchain drives the SDK bundle's own clang for the C -# side of the build (unlike Android, where the cc toolchain comes from the -# separately registered NDK). It only resolves for this wasm target platform, -# and because root-module registrations take precedence in toolchain -# resolution, a consumer who registers their own wasm cc toolchain wins over -# this one automatically. toolchain( name = "cc_toolchain_{target}_{platform}", exec_compatible_with = {exec_compatible_with}, @@ -141,7 +135,7 @@ def wasm_sdk_toolchains_for_platform(platform, sdk_repository): Returns: BUILD file content declaring the Swift and C++ toolchains. """ - return _WASM_SDK_TOOLCHAIN_PLATFORM.format( + return _CC_SDK_TOOLCHAIN_PLATFORM.format( exec_compatible_with = _exec_compatible_with_for_platform(platform), platform = platform, sdk_repository = sdk_repository, @@ -153,6 +147,36 @@ def wasm_sdk_toolchains_for_platform(platform, sdk_repository): target_suffix = "wasm32", ) +def static_linux_sdk_toolchains_for_platform(platform, sdk_repository, archs): + """Returns `toolchain` declarations for a Static Linux Swift SDK. + + Args: + platform: The platform name (e.g. "xcode" or "ubuntu22.04") whose + standalone toolchain the SDK is paired with. + sdk_repository: The name of the repository created by + `swift_static_linux_sdk_repository`. + archs: The Static Linux architectures ("aarch64", "x86_64") to declare + toolchains for. + + Returns: + BUILD file content declaring the Swift and C++ toolchains. + """ + content = "" + for arch in archs: + content += _CC_SDK_TOOLCHAIN_PLATFORM.format( + exec_compatible_with = _exec_compatible_with_for_platform(platform), + platform = platform, + sdk_repository = sdk_repository, + target = "static_linux_" + arch, + target_compatible_with = [ + "@platforms//os:linux", + "@platforms//cpu:" + arch, + "@rules_swift//swift/toolchains:static_linux", + ], + target_suffix = "static_linux_" + arch, + ) + return content + def _toolchains_impl(repository_ctx): repository_ctx.file("BUILD.bazel", repository_ctx.attr.build_file_content) diff --git a/swift/toolchains/BUILD b/swift/toolchains/BUILD index 10964bc03..b92a6d2f9 100644 --- a/swift/toolchains/BUILD +++ b/swift/toolchains/BUILD @@ -11,6 +11,17 @@ load( licenses(["notice"]) +constraint_setting( + name = "swift_sdk", + visibility = ["//visibility:public"], +) + +constraint_value( + name = "static_linux", + constraint_setting = ":swift_sdk", + visibility = ["//visibility:public"], +) + toolchain( name = "linux-swift-toolchain_x86_64", exec_compatible_with = [ diff --git a/test/fixtures/toolchains/BUILD b/test/fixtures/toolchains/BUILD index 0c2f2013c..9c61e964f 100644 --- a/test/fixtures/toolchains/BUILD +++ b/test/fixtures/toolchains/BUILD @@ -1,8 +1,25 @@ +load("@rules_cc//cc:cc_binary.bzl", "cc_binary") +load("@rules_cc//cc/toolchains:args.bzl", "cc_args") +load("@rules_cc//cc/toolchains:make_variable.bzl", "cc_make_variable") +load("@rules_cc//cc/toolchains:tool.bzl", "cc_tool") +load("@rules_cc//cc/toolchains:tool_map.bzl", "cc_tool_map") +load("@rules_cc//cc/toolchains:toolchain.bzl", "cc_toolchain") load( "//swift/toolchains:swift_toolchain.bzl", "swift_toolchain", ) +exports_files(["fake_tool.sh"]) + +platform( + name = "linux_musl_x86_64", + constraint_values = [ + "@platforms//cpu:x86_64", + "@platforms//os:linux", + "//swift/toolchains:static_linux", + ], +) + swift_toolchain( name = "_toolchain_macos_arm64_with_sdkroot", arch = "arm64", @@ -18,3 +35,105 @@ toolchain( toolchain = ":_toolchain_macos_arm64_with_sdkroot", toolchain_type = "//toolchains:toolchain_type", ) + +cc_tool( + name = "fake_clang", + src = "fake_tool.sh", + tags = ["manual"], +) + +cc_tool_map( + name = "cc_tools_static_linux_x86_64", + tags = ["manual"], + tools = { + "@rules_cc//cc/toolchains/actions:ar_actions": ":fake_clang", + "@rules_cc//cc/toolchains/actions:assembly_actions": ":fake_clang", + "@rules_cc//cc/toolchains/actions:c_compile": ":fake_clang", + "@rules_cc//cc/toolchains/actions:cpp_compile_actions": ":fake_clang", + "@rules_cc//cc/toolchains/actions:link_actions": ":fake_clang", + }, +) + +cc_args( + name = "cc_args_static_linux_x86_64", + actions = [ + "@rules_cc//cc/toolchains/actions:compile_actions", + "@rules_cc//cc/toolchains/actions:link_actions", + ], + args = [ + "--target=x86_64-swift-linux-musl", + "--sysroot=static-sdk-root", + ], +) + +cc_args( + name = "cc_link_args_static_linux_x86_64", + actions = [ + "@rules_cc//cc/toolchains/actions:link_actions", + ], + args = [ + "-lc++", + ], +) + +cc_make_variable( + name = "cc_target_triple_static_linux_x86_64", + value = "x86_64-swift-linux-musl", + variable_name = "CC_TARGET_TRIPLE", +) + +cc_toolchain( + name = "_cc_toolchain_static_linux_x86_64", + args = [ + ":cc_args_static_linux_x86_64", + ":cc_link_args_static_linux_x86_64", + ], + compiler = "clang", + enabled_features = [ + "@rules_cc//cc/toolchains/args/archiver_flags:feature", + "@rules_cc//cc/toolchains/args/libraries_to_link:feature", + "@rules_cc//cc/toolchains/args/link_flags:feature", + ], + make_variables = [ + ":cc_target_triple_static_linux_x86_64", + ], + tool_map = ":cc_tools_static_linux_x86_64", +) + +toolchain( + name = "cc_toolchain_static_linux_x86_64", + toolchain = ":_cc_toolchain_static_linux_x86_64", + toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", +) + +cc_binary( + name = "static_linux_cc_uses_libcxx", + srcs = ["static_linux_cc_uses_libcxx.cc"], + tags = ["manual"], + visibility = ["//test:__pkg__"], +) + +swift_toolchain( + name = "_toolchain_static_linux_x86_64", + arch = "x86_64", + copts = [ + "-resource-dir", + "static-resource-root", + ], + features = [ + "swift.use_autolink_extract", + ], + linker_inputs = [":fake_tool.sh"], + linkopts = ["-static"], + os = "linux", + parsed_version = "6.3.2", + root = ".", + sdkroot = "static-sdk-root", + version_file = ".swift_version", +) + +toolchain( + name = "toolchain_static_linux_x86_64", + toolchain = ":_toolchain_static_linux_x86_64", + toolchain_type = "//toolchains:toolchain_type", +) diff --git a/test/fixtures/toolchains/fake_tool.sh b/test/fixtures/toolchains/fake_tool.sh new file mode 100644 index 000000000..ecdbef95d --- /dev/null +++ b/test/fixtures/toolchains/fake_tool.sh @@ -0,0 +1,2 @@ +#!/bin/sh +exit 1 diff --git a/test/fixtures/toolchains/static_linux_cc_uses_libcxx.cc b/test/fixtures/toolchains/static_linux_cc_uses_libcxx.cc new file mode 100644 index 000000000..c547ad99d --- /dev/null +++ b/test/fixtures/toolchains/static_linux_cc_uses_libcxx.cc @@ -0,0 +1,6 @@ +#include + +int main() { + std::string value = "static-linux"; + return value.empty(); +} diff --git a/test/swift_toolchain_tests.bzl b/test/swift_toolchain_tests.bzl index 4a4d77d9b..cd1067406 100644 --- a/test/swift_toolchain_tests.bzl +++ b/test/swift_toolchain_tests.bzl @@ -11,6 +11,15 @@ toolchain_macos_arm64_with_sdkroot_test = make_action_command_line_test_rule( }, ) +toolchain_static_linux_x86_64_test = make_action_command_line_test_rule( + config_settings = { + "//command_line_option:extra_toolchains": [ + "//test/fixtures/toolchains:cc_toolchain_static_linux_x86_64", + "//test/fixtures/toolchains:toolchain_static_linux_x86_64", + ], + }, +) + def swift_toolchain_test_suite(name, tags = []): """Test suite for swift_toolchain's provider. @@ -29,6 +38,35 @@ def swift_toolchain_test_suite(name, tags = []): target_under_test = "//test/fixtures/basic:first", ) + toolchain_static_linux_x86_64_test( + name = "{}_static_linux_x86_64".format(name), + expected_argv = [ + "-target", + "x86_64-swift-linux-musl", + "-sdk", + "static-sdk-root", + "-resource-dir", + "static-resource-root", + "-Xcc", + "--target=x86_64-swift-linux-musl", + ], + mnemonic = "SwiftCompile", + tags = all_tags, + target_under_test = "//test/fixtures/basic:first", + ) + + toolchain_static_linux_x86_64_test( + name = "{}_static_linux_cc_links_libcxx".format(name), + expected_argv = [ + "--target=x86_64-swift-linux-musl", + "--sysroot=static-sdk-root", + "-lc++", + ], + mnemonic = "CppLink", + tags = all_tags, + target_under_test = "//test/fixtures/toolchains:static_linux_cc_uses_libcxx", + ) + native.test_suite( name = name, tags = all_tags, diff --git a/test/utils_tests.bzl b/test/utils_tests.bzl index 7a8530667..dc8229e46 100644 --- a/test/utils_tests.bzl +++ b/test/utils_tests.bzl @@ -12,7 +12,12 @@ load("//swift/internal:utils.bzl", "include_developer_search_paths") load("//swift/internal/extensions:standalone_toolchain.bzl", "get_download_url") # buildifier: disable=bzl-visibility -load("//swift/internal/extensions:swift_sdk_releases.bzl", "swift_sdk_download_url") +load( + "//swift/internal/extensions:swift_sdk_releases.bzl", + "SWIFT_SDK_RELEASES", + "static_linux_sdk_download_url", + "swift_sdk_download_url", +) def _include_developer_search_paths_test(ctx): env = unittest.begin(ctx) @@ -193,11 +198,33 @@ def _swift_sdk_download_url_test(ctx): swift_sdk_download_url_test = unittest.make(_swift_sdk_download_url_test) +def _static_linux_sdk_release_metadata_test(ctx): + env = unittest.begin(ctx) + + static_linux_release = SWIFT_SDK_RELEASES["6.3.2"]["static_linux"] + asserts.equals( + env, + "3fd798bef6f4408f1ea5a6f94ce4d4052830c4326ab85ebc04f983f01b3da407", + static_linux_release["sha256"], + ) + asserts.equals(env, "0.1.0", static_linux_release["version"]) + + asserts.equals( + env, + "https://download.swift.org/swift-6.3.2-release/static-sdk/swift-6.3.2-RELEASE/swift-6.3.2-RELEASE_static-linux-0.1.0.artifactbundle.tar.gz", + static_linux_sdk_download_url("6.3.2", "0.1.0"), + ) + + return unittest.end(env) + +static_linux_sdk_release_metadata_test = unittest.make(_static_linux_sdk_release_metadata_test) + def utils_test_suite(name): return unittest.suite( name, developer_dirs_linkopts_test, include_developer_search_paths_test, + static_linux_sdk_release_metadata_test, standalone_toolchain_download_url_test, swift_sdk_download_url_test, ) From a1fea1f162060b279103b6a2e0c541e279b433b3 Mon Sep 17 00:00:00 2001 From: Adin Cebic Date: Wed, 8 Jul 2026 14:02:27 +0200 Subject: [PATCH 2/4] read linker args from SDK file --- swift/extensions.bzl | 5 +- swift/internal/extensions/swift_sdks.bzl | 95 +++++++++++++++++++----- test/utils_tests.bzl | 77 +++++++++++++++++++ 3 files changed, 157 insertions(+), 20 deletions(-) diff --git a/swift/extensions.bzl b/swift/extensions.bzl index 97f18f086..daf6dd65c 100644 --- a/swift/extensions.bzl +++ b/swift/extensions.bzl @@ -334,7 +334,10 @@ _static_linux_sdk = tag_class( doc = """\ The Static Linux SDK version in the artifact bundle filename. May be omitted for Swift/SDK version pairs known to this version of rules_swift. If this -overrides the known SDK version, `sha256` must also be provided. +overrides the known SDK version, `sha256` must also be provided. Custom SDK +versions must preserve the standard Static Linux SDK artifact-bundle layout, +including the `swift-sdk.json` metadata; linker args are read from the SDK's +`linux-static/static-executable-args.lnk`. """, ), "sha256": attr.string( diff --git a/swift/internal/extensions/swift_sdks.bzl b/swift/internal/extensions/swift_sdks.bzl index b77dd84fa..1fa722e11 100644 --- a/swift/internal/extensions/swift_sdks.bzl +++ b/swift/internal/extensions/swift_sdks.bzl @@ -230,6 +230,74 @@ def _static_linux_resource_path(target_settings, triple): field = "swiftResourcesPath" return _relative_metadata_path(resource_path, field, triple) +def static_linux_linkopts_from_args( + *, + arch, + linux_static_dir, + args, + include_swiftrt = True): + """Returns linkopts using a Static Linux `static-executable-args.lnk` file. + + Args: + arch: The target architecture. + linux_static_dir: The execroot-relative `linux-static` resource + directory. + args: The parsed non-empty lines from `static-executable-args.lnk`. + include_swiftrt: If True, add the `swiftrt.o` path used by the current + Static Linux SDK layout. + + Returns: + Linkopts suitable for a C/C++ linker action. + """ + linkopts = [] + if include_swiftrt: + linkopts.append("{}/{}/swiftrt.o".format(linux_static_dir, arch)) + linkopts.append("-L{}".format(linux_static_dir)) + + linker_arg_expected = False + for arg in args: + if linker_arg_expected: + if arg.startswith("-undefined=") and arg != "-undefined=": + linkopts.append("-Wl,-u," + arg.removeprefix("-undefined=")) + else: + linkopts.extend(["-Xlinker", arg]) + linker_arg_expected = False + elif arg == "-Xlinker": + linker_arg_expected = True + else: + linkopts.append(arg) + + if linker_arg_expected: + linkopts.append("-Xlinker") + + return linkopts + +def _static_linux_linkopts_from_sdk( + repository_ctx, + *, + arch, + linux_static_dir, + linux_static_dir_relative, + repo_root): + swiftrt_relative = "{}/{}/swiftrt.o".format(linux_static_dir_relative, arch) + args_relative = linux_static_dir_relative + "/static-executable-args.lnk" + if not repository_ctx.path(args_relative).exists: + fail("The Static Linux Swift SDK bundle has an unexpected layout; " + + "missing {}/{}".format(repo_root, args_relative)) + + args = [] + for line in repository_ctx.read(args_relative).split("\n"): + arg = line.strip() + if arg and not arg.startswith("#"): + args.append(arg) + + return static_linux_linkopts_from_args( + arch = arch, + args = args, + include_swiftrt = repository_ctx.path(swiftrt_relative).exists, + linux_static_dir = linux_static_dir, + ) + def _common_attrs(): return { "sha256": attr.string( @@ -528,6 +596,7 @@ def _swift_static_linux_sdk_impl(repository_ctx): if not repository_ctx.path(resource_dir_relative).exists: fail("The Static Linux Swift SDK bundle has an unexpected layout; " + "missing " + resource_dir) + linux_static_dir_relative = resource_dir_relative + "/linux-static" linux_static_dir = resource_dir + "/linux-static" build_content += _SWIFT_TOOLCHAIN_TEMPLATE.format( @@ -542,25 +611,13 @@ def _swift_static_linux_sdk_impl(repository_ctx): "swift.use_autolink_extract", ]), linker_inputs = _build_list([":sdk_files"]), - # These are the runtime objects and libraries that `swiftc` adds - # for a Static Linux executable; see - # `swift_static/linux-static/static-executable-args.lnk` in the SDK. - linkopts = _build_list([ - "{}/{}/swiftrt.o".format(linux_static_dir, arch), - "-L{}".format(linux_static_dir), - "-static", - "-lswiftCore", - "-lswift_RegexParser", - "-Wl,-u,pthread_self", - "-Wl,-u,pthread_once", - "-Wl,-u,pthread_key_create", - "-ldispatch", - "-lBlocksRuntime", - "-lpthread", - "-ldl", - "-lc++", - "-lm", - ]), + linkopts = _build_list(_static_linux_linkopts_from_sdk( + repository_ctx, + arch = arch, + linux_static_dir = linux_static_dir, + linux_static_dir_relative = linux_static_dir_relative, + repo_root = repo_root, + )), os = "linux", sdkroot = sdkroot, suffix = suffix, diff --git a/test/utils_tests.bzl b/test/utils_tests.bzl index dc8229e46..cd23eef67 100644 --- a/test/utils_tests.bzl +++ b/test/utils_tests.bzl @@ -19,6 +19,12 @@ load( "swift_sdk_download_url", ) +# buildifier: disable=bzl-visibility +load( + "//swift/internal/extensions:swift_sdks.bzl", + "static_linux_linkopts_from_args", +) + def _include_developer_search_paths_test(ctx): env = unittest.begin(ctx) @@ -219,11 +225,82 @@ def _static_linux_sdk_release_metadata_test(ctx): static_linux_sdk_release_metadata_test = unittest.make(_static_linux_sdk_release_metadata_test) +def _static_linux_linkopts_from_args_test(ctx): + env = unittest.begin(ctx) + + args = [ + "-static", + "-lswiftCore", + "-lswift_RegexParser", + "-Xlinker", + "-undefined=pthread_self", + "-Xlinker", + "-undefined=pthread_once", + "-Xlinker", + "-undefined=pthread_key_create", + "-ldispatch", + "-lBlocksRuntime", + "-lpthread", + "-ldl", + "-lc++", + "-lm", + ] + + asserts.equals( + env, + [ + "external/static_linux_sdk/swift_static/linux-static/x86_64/swiftrt.o", + "-Lexternal/static_linux_sdk/swift_static/linux-static", + "-static", + "-lswiftCore", + "-lswift_RegexParser", + "-Wl,-u,pthread_self", + "-Wl,-u,pthread_once", + "-Wl,-u,pthread_key_create", + "-ldispatch", + "-lBlocksRuntime", + "-lpthread", + "-ldl", + "-lc++", + "-lm", + ], + static_linux_linkopts_from_args( + arch = "x86_64", + args = args, + linux_static_dir = "external/static_linux_sdk/swift_static/linux-static", + ), + ) + + asserts.equals( + env, + [ + "-Lexternal/static_linux_sdk/swift_static/linux-static", + "-Xlinker", + "--future-linker-arg", + "-Xlinker", + ], + static_linux_linkopts_from_args( + arch = "x86_64", + args = [ + "-Xlinker", + "--future-linker-arg", + "-Xlinker", + ], + include_swiftrt = False, + linux_static_dir = "external/static_linux_sdk/swift_static/linux-static", + ), + ) + + return unittest.end(env) + +static_linux_linkopts_from_args_test = unittest.make(_static_linux_linkopts_from_args_test) + def utils_test_suite(name): return unittest.suite( name, developer_dirs_linkopts_test, include_developer_search_paths_test, + static_linux_linkopts_from_args_test, static_linux_sdk_release_metadata_test, standalone_toolchain_download_url_test, swift_sdk_download_url_test, From 5ccdb153274debf31c9a749c4c4e4430a0d1d6ee Mon Sep 17 00:00:00 2001 From: Adin Cebic Date: Thu, 9 Jul 2026 10:28:25 +0200 Subject: [PATCH 3/4] Use real toolchain in tests --- swift/internal/extensions/swift_sdks.bzl | 13 ++- test/fixtures/toolchains/BUILD | 102 ----------------------- test/fixtures/toolchains/fake_tool.sh | 2 - test/swift_toolchain_tests.bzl | 12 +-- 4 files changed, 12 insertions(+), 117 deletions(-) delete mode 100644 test/fixtures/toolchains/fake_tool.sh diff --git a/swift/internal/extensions/swift_sdks.bzl b/swift/internal/extensions/swift_sdks.bzl index 1fa722e11..0699b54c9 100644 --- a/swift/internal/extensions/swift_sdks.bzl +++ b/swift/internal/extensions/swift_sdks.bzl @@ -223,12 +223,11 @@ def _relative_metadata_path(value, field, triple): return value def _static_linux_resource_path(target_settings, triple): - resource_path = target_settings.get("swiftStaticResourcesPath") - field = "swiftStaticResourcesPath" - if not resource_path: - resource_path = target_settings.get("swiftResourcesPath") - field = "swiftResourcesPath" - return _relative_metadata_path(resource_path, field, triple) + return _relative_metadata_path( + target_settings.get("swiftStaticResourcesPath"), + "swiftStaticResourcesPath", + triple, + ) def static_linux_linkopts_from_args( *, @@ -288,7 +287,7 @@ def _static_linux_linkopts_from_sdk( args = [] for line in repository_ctx.read(args_relative).split("\n"): arg = line.strip() - if arg and not arg.startswith("#"): + if arg: args.append(arg) return static_linux_linkopts_from_args( diff --git a/test/fixtures/toolchains/BUILD b/test/fixtures/toolchains/BUILD index 9c61e964f..c1327457e 100644 --- a/test/fixtures/toolchains/BUILD +++ b/test/fixtures/toolchains/BUILD @@ -1,16 +1,9 @@ load("@rules_cc//cc:cc_binary.bzl", "cc_binary") -load("@rules_cc//cc/toolchains:args.bzl", "cc_args") -load("@rules_cc//cc/toolchains:make_variable.bzl", "cc_make_variable") -load("@rules_cc//cc/toolchains:tool.bzl", "cc_tool") -load("@rules_cc//cc/toolchains:tool_map.bzl", "cc_tool_map") -load("@rules_cc//cc/toolchains:toolchain.bzl", "cc_toolchain") load( "//swift/toolchains:swift_toolchain.bzl", "swift_toolchain", ) -exports_files(["fake_tool.sh"]) - platform( name = "linux_musl_x86_64", constraint_values = [ @@ -36,104 +29,9 @@ toolchain( toolchain_type = "//toolchains:toolchain_type", ) -cc_tool( - name = "fake_clang", - src = "fake_tool.sh", - tags = ["manual"], -) - -cc_tool_map( - name = "cc_tools_static_linux_x86_64", - tags = ["manual"], - tools = { - "@rules_cc//cc/toolchains/actions:ar_actions": ":fake_clang", - "@rules_cc//cc/toolchains/actions:assembly_actions": ":fake_clang", - "@rules_cc//cc/toolchains/actions:c_compile": ":fake_clang", - "@rules_cc//cc/toolchains/actions:cpp_compile_actions": ":fake_clang", - "@rules_cc//cc/toolchains/actions:link_actions": ":fake_clang", - }, -) - -cc_args( - name = "cc_args_static_linux_x86_64", - actions = [ - "@rules_cc//cc/toolchains/actions:compile_actions", - "@rules_cc//cc/toolchains/actions:link_actions", - ], - args = [ - "--target=x86_64-swift-linux-musl", - "--sysroot=static-sdk-root", - ], -) - -cc_args( - name = "cc_link_args_static_linux_x86_64", - actions = [ - "@rules_cc//cc/toolchains/actions:link_actions", - ], - args = [ - "-lc++", - ], -) - -cc_make_variable( - name = "cc_target_triple_static_linux_x86_64", - value = "x86_64-swift-linux-musl", - variable_name = "CC_TARGET_TRIPLE", -) - -cc_toolchain( - name = "_cc_toolchain_static_linux_x86_64", - args = [ - ":cc_args_static_linux_x86_64", - ":cc_link_args_static_linux_x86_64", - ], - compiler = "clang", - enabled_features = [ - "@rules_cc//cc/toolchains/args/archiver_flags:feature", - "@rules_cc//cc/toolchains/args/libraries_to_link:feature", - "@rules_cc//cc/toolchains/args/link_flags:feature", - ], - make_variables = [ - ":cc_target_triple_static_linux_x86_64", - ], - tool_map = ":cc_tools_static_linux_x86_64", -) - -toolchain( - name = "cc_toolchain_static_linux_x86_64", - toolchain = ":_cc_toolchain_static_linux_x86_64", - toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", -) - cc_binary( name = "static_linux_cc_uses_libcxx", srcs = ["static_linux_cc_uses_libcxx.cc"], tags = ["manual"], visibility = ["//test:__pkg__"], ) - -swift_toolchain( - name = "_toolchain_static_linux_x86_64", - arch = "x86_64", - copts = [ - "-resource-dir", - "static-resource-root", - ], - features = [ - "swift.use_autolink_extract", - ], - linker_inputs = [":fake_tool.sh"], - linkopts = ["-static"], - os = "linux", - parsed_version = "6.3.2", - root = ".", - sdkroot = "static-sdk-root", - version_file = ".swift_version", -) - -toolchain( - name = "toolchain_static_linux_x86_64", - toolchain = ":_toolchain_static_linux_x86_64", - toolchain_type = "//toolchains:toolchain_type", -) diff --git a/test/fixtures/toolchains/fake_tool.sh b/test/fixtures/toolchains/fake_tool.sh deleted file mode 100644 index ecdbef95d..000000000 --- a/test/fixtures/toolchains/fake_tool.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -exit 1 diff --git a/test/swift_toolchain_tests.bzl b/test/swift_toolchain_tests.bzl index cd1067406..68424462e 100644 --- a/test/swift_toolchain_tests.bzl +++ b/test/swift_toolchain_tests.bzl @@ -13,9 +13,8 @@ toolchain_macos_arm64_with_sdkroot_test = make_action_command_line_test_rule( toolchain_static_linux_x86_64_test = make_action_command_line_test_rule( config_settings = { - "//command_line_option:extra_toolchains": [ - "//test/fixtures/toolchains:cc_toolchain_static_linux_x86_64", - "//test/fixtures/toolchains:toolchain_static_linux_x86_64", + "//command_line_option:platforms": [ + str(Label("//test/fixtures/toolchains:linux_musl_x86_64")), ], }, ) @@ -44,9 +43,9 @@ def swift_toolchain_test_suite(name, tags = []): "-target", "x86_64-swift-linux-musl", "-sdk", - "static-sdk-root", + "swift-linux-musl/musl-1.2.5.sdk/x86_64", "-resource-dir", - "static-resource-root", + "swift-linux-musl/musl-1.2.5.sdk/x86_64/usr/lib/swift_static", "-Xcc", "--target=x86_64-swift-linux-musl", ], @@ -59,7 +58,8 @@ def swift_toolchain_test_suite(name, tags = []): name = "{}_static_linux_cc_links_libcxx".format(name), expected_argv = [ "--target=x86_64-swift-linux-musl", - "--sysroot=static-sdk-root", + "--sysroot", + "swift-linux-musl/musl-1.2.5.sdk/x86_64", "-lc++", ], mnemonic = "CppLink", From e16626739507b0112c9fc70f65dba8e2c9c8f800 Mon Sep 17 00:00:00 2001 From: Adin Cebic Date: Fri, 10 Jul 2026 15:37:45 +0200 Subject: [PATCH 4/4] remove --- swift/internal/extensions/swift_sdks.bzl | 19 +------------------ test/utils_tests.bzl | 9 ++++++--- 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/swift/internal/extensions/swift_sdks.bzl b/swift/internal/extensions/swift_sdks.bzl index 0699b54c9..54d391070 100644 --- a/swift/internal/extensions/swift_sdks.bzl +++ b/swift/internal/extensions/swift_sdks.bzl @@ -252,24 +252,7 @@ def static_linux_linkopts_from_args( if include_swiftrt: linkopts.append("{}/{}/swiftrt.o".format(linux_static_dir, arch)) linkopts.append("-L{}".format(linux_static_dir)) - - linker_arg_expected = False - for arg in args: - if linker_arg_expected: - if arg.startswith("-undefined=") and arg != "-undefined=": - linkopts.append("-Wl,-u," + arg.removeprefix("-undefined=")) - else: - linkopts.extend(["-Xlinker", arg]) - linker_arg_expected = False - elif arg == "-Xlinker": - linker_arg_expected = True - else: - linkopts.append(arg) - - if linker_arg_expected: - linkopts.append("-Xlinker") - - return linkopts + return linkopts + args def _static_linux_linkopts_from_sdk( repository_ctx, diff --git a/test/utils_tests.bzl b/test/utils_tests.bzl index cd23eef67..721aee115 100644 --- a/test/utils_tests.bzl +++ b/test/utils_tests.bzl @@ -254,9 +254,12 @@ def _static_linux_linkopts_from_args_test(ctx): "-static", "-lswiftCore", "-lswift_RegexParser", - "-Wl,-u,pthread_self", - "-Wl,-u,pthread_once", - "-Wl,-u,pthread_key_create", + "-Xlinker", + "-undefined=pthread_self", + "-Xlinker", + "-undefined=pthread_once", + "-Xlinker", + "-undefined=pthread_key_create", "-ldispatch", "-lBlocksRuntime", "-lpthread",