diff --git a/BUILD.bazel b/BUILD.bazel index b2e4ea806785..07027f4ad9a7 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -3,3 +3,11 @@ exports_files([ "Cargo.lock", "Cargo.toml", ]) + +constraint_setting(name = "swift_runtime_linkage") + +constraint_value( + name = "static_swift_runtime", + constraint_setting = ":swift_runtime_linkage", + visibility = ["//visibility:public"], +) diff --git a/MODULE.bazel b/MODULE.bazel index 91c871445eb4..6184b8c49cac 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -228,7 +228,7 @@ use_repo( # `unified/swift-syntax-rs` package is not loadable in that context. Keep this # in sync with `unified/swift-syntax-rs/.swift-version` (used by the `cargo` # build) and the `swift-syntax` release in `swift/Package.swift`. -swift = use_extension("@rules_swift//swift:extensions.bzl", "swift") +swift = use_extension("@rules_swift//swift:extensions.bzl", "swift", dev_dependency = True) swift.toolchain( name = "swift_toolchain", swift_version = "6.3.3", @@ -243,6 +243,7 @@ use_repo( register_toolchains( "@swift_toolchain//:swift_toolchain_exec_ubuntu22.04", "@swift_toolchain//:swift_toolchain_exec_xcode", + dev_dependency = True, ) node = use_extension("@rules_nodejs//nodejs:extensions.bzl", "node") diff --git a/misc/bazel/registry/modules/rules_swift/4.0.0-rc5-codeql.1/patches/external_static_runtime.patch b/misc/bazel/registry/modules/rules_swift/4.0.0-rc5-codeql.1/patches/external_static_runtime.patch new file mode 100644 index 000000000000..11f32aacd257 --- /dev/null +++ b/misc/bazel/registry/modules/rules_swift/4.0.0-rc5-codeql.1/patches/external_static_runtime.patch @@ -0,0 +1,242 @@ +diff --git a/swift/extensions.bzl b/swift/extensions.bzl +index b77f636..1255ba7 100644 +--- a/swift/extensions.bzl ++++ b/swift/extensions.bzl +@@ -191,6 +191,7 @@ def _standalone_toolchain_impl(module_ctx): + name = repository_name, + sha256 = sha256, + platform = platform, ++ static_runtime = toolchain.static_runtime if platform != "xcode" else None, + swift_version = swift_version, + ) + toolchains_build_file_content += toolchains_for_platform( +@@ -266,6 +267,9 @@ their hashes. For instance: + `bazel run @rules_swift//tools/swift-releases -- list 6.2.4` + """, + ), ++ "static_runtime": attr.label( ++ doc = "External static runtime package to attach to the generated execution toolchains.", ++ ), + "swift_version": attr.string(doc = "Version of the swift toolchain to be installed. Cannot be used concurrently with `swift_version_file`"), + "swift_version_file": attr.label(doc = "A label to the .swift_version file to use. Cannot be used concurrently with `swift_version`"), + }) +diff --git a/swift/internal/extensions/standalone_toolchain.bzl b/swift/internal/extensions/standalone_toolchain.bzl +index a1e09ea..1fcf56d 100644 +--- a/swift/internal/extensions/standalone_toolchain.bzl ++++ b/swift/internal/extensions/standalone_toolchain.bzl +@@ -105,6 +105,9 @@ def _standalone_toolchain_impl(repository_ctx): + "BUILD.bazel", + repository_ctx.attr._build_template, + substitutions = { ++ "{external_static_runtime}": ( ++ ' external_static_runtime = "{}",'.format(repository_ctx.attr.static_runtime) if repository_ctx.attr.static_runtime else "" ++ ), + "{macos_sdkroot}": macos_sdkroot, + "{swift_version}": repository_ctx.attr.swift_version, + }, +@@ -121,6 +124,9 @@ _STANDALONE_TOOLCHAIN_ATTRS = { + "sha256": attr.string( + doc = "The expected SHA-256 of the file downloaded. This must match the SHA-256 of the file downloaded.", + ), ++ "static_runtime": attr.label( ++ doc = "External static runtime package used by this execution toolchain.", ++ ), + "swift_version": attr.string( + doc = "Version of the swift toolchain to be installed.", + mandatory = True, +diff --git a/swift/internal/extensions/toolchain.BUILD b/swift/internal/extensions/toolchain.BUILD +index 1304dc2..ee77866 100644 +--- a/swift/internal/extensions/toolchain.BUILD ++++ b/swift/internal/extensions/toolchain.BUILD +@@ -364,6 +364,7 @@ swift_toolchain( + ), + "//conditions:default": [], + }), ++{external_static_runtime} + swift_tools = "tools", + version_file = ".swift-version", + ) +diff --git a/swift/toolchains/BUILD b/swift/toolchains/BUILD +index 1a8db31..fff0879 100644 +--- a/swift/toolchains/BUILD ++++ b/swift/toolchains/BUILD +@@ -155,6 +155,7 @@ bzl_library( + "//swift/internal:features", + "//swift/internal:providers", + "//swift/internal:target_triples", ++ "//swift/internal:toolchain_utils", + "//swift/internal:utils", + "//swift/internal:wmo", + "//swift/toolchains/config:action_config", +diff --git a/swift/toolchains/swift_toolchain.bzl b/swift/toolchains/swift_toolchain.bzl +index 9fc2a49..6f10573 100644 +--- a/swift/toolchains/swift_toolchain.bzl ++++ b/swift/toolchains/swift_toolchain.bzl +@@ -69,6 +69,11 @@ load( + "SwiftModuleAliasesInfo", + ) + load("//swift/internal:target_triples.bzl", "target_triples") ++load( ++ "//swift/internal:toolchain_utils.bzl", ++ "get_swift_toolchain", ++ "use_swift_toolchain", ++) + load( + "//swift/internal:utils.bzl", + "collect_cross_import_overlays", +@@ -101,6 +106,64 @@ load( + ) + load("//swift/toolchains/config:tool_config.bzl", "ToolConfigInfo") +- ++ ++SwiftStaticRuntimeInfo = provider( ++ fields = { ++ "copts": "Compiler options required to use the runtime.", ++ "files": "Runtime and SDK files required by compile and link actions.", ++ "linkopts": "Linker options required to link the runtime.", ++ "root": "Execution-root-relative path to the runtime SDK.", ++ }, ++) ++ ++def _swift_static_runtime_impl(ctx): ++ root = ctx.label.workspace_root ++ files = depset(ctx.files.files) ++ ++ def expand_root(options): ++ return [option.replace("{root}", root) for option in options] ++ ++ return [ ++ DefaultInfo(files = files), ++ SwiftStaticRuntimeInfo( ++ copts = expand_root(ctx.attr.copts), ++ files = files, ++ linkopts = expand_root(ctx.attr.linkopts), ++ root = root, ++ ), ++ ] ++ ++swift_static_runtime = rule( ++ implementation = _swift_static_runtime_impl, ++ attrs = { ++ "copts": attr.string_list(), ++ "files": attr.label_list(allow_files = True, mandatory = True), ++ "linkopts": attr.string_list(), ++ }, ++) ++ ++def _swift_runtime_impl(ctx): ++ runtime_cc_info = get_swift_toolchain(ctx).dynamic_runtime_cc_info ++ files = [] ++ if runtime_cc_info: ++ for linker_input in runtime_cc_info.linking_context.linker_inputs.to_list(): ++ for library in linker_input.libraries: ++ dynamic_library = getattr(library, "dynamic_library", None) ++ if dynamic_library: ++ files.append(dynamic_library) ++ runtime = depset(files) ++ providers = [DefaultInfo( ++ files = runtime, ++ runfiles = ctx.runfiles(transitive_files = runtime), ++ )] ++ if runtime_cc_info: ++ providers.append(runtime_cc_info) ++ return providers ++ ++swift_runtime = rule( ++ implementation = _swift_runtime_impl, ++ toolchains = use_swift_toolchain(), ++) ++ + def _swift_compile_resource_set(_os, inputs_size): + # The `os` argument is unused, but the Starlark API requires both + # positional arguments. +@@ -662,6 +725,7 @@ def _resolve_sdkroot(ctx, cc_toolchain): +- ++ + def _swift_toolchain_impl(ctx): + toolchain_root = ctx.attr.root ++ external_static_runtime = ctx.attr.external_static_runtime[SwiftStaticRuntimeInfo] if ctx.attr.external_static_runtime else None + cc_toolchain = find_cc_toolchain(ctx) + target_system_name = _parse_target_system_name( + arch = ctx.attr.arch, +@@ -684,7 +748,7 @@ def _swift_toolchain_impl(ctx): + "before invoking Bazel, or configure a Bazel LLVM CC toolchain. " + + "The current CC toolchain is configured to use '{}'.".format(cc_toolchain.compiler)) +- ++ +- sdkroot = _resolve_sdkroot(ctx, cc_toolchain) ++ sdkroot = external_static_runtime.root if external_static_runtime else _resolve_sdkroot(ctx, cc_toolchain) +- ++ + if ctx.attr.swift_tools: + if ctx.attr.swift_executable: +@@ -740,6 +804,18 @@ def _swift_toolchain_impl(ctx): + ctx.attr.linkopts, + ctx.files.linker_inputs, + ) ++ elif external_static_runtime: ++ swift_linkopts_cc_info = CcInfo( ++ linking_context = cc_common.create_linking_context( ++ linker_inputs = depset([ ++ cc_common.create_linker_input( ++ owner = ctx.label, ++ user_link_flags = depset(external_static_runtime.linkopts), ++ additional_inputs = external_static_runtime.files, ++ ), ++ ]), ++ ), ++ ) + else: + ( + swift_linkopts_cc_info, +@@ -763,6 +839,8 @@ def _swift_toolchain_impl(ctx): + swiftcopts.extend(ctx.attr._exec_copts[BuildSettingInfo].value) + else: + swiftcopts.extend(ctx.attr._copts[BuildSettingInfo].value) ++ if external_static_runtime: ++ swiftcopts.extend(external_static_runtime.copts) +- ++ + # Combine build mode features, autoconfigured features, and required + # features. +@@ -774,7 +852,7 @@ def _swift_toolchain_impl(ctx): + target_triple = target_triple, + )) +- ++ +- if apple_common.dotted_version(ctx.attr.parsed_version) >= apple_common.dotted_version("6.3"): ++ if not external_static_runtime and apple_common.dotted_version(ctx.attr.parsed_version) >= apple_common.dotted_version("6.3"): + requested_features.append(SWIFT_FEATURE__SUPPORTS_HERMETIC_SWIFTMODULE) +- ++ + requested_features.extend(ctx.features) +@@ -787,6 +865,8 @@ def _swift_toolchain_impl(ctx): + additional_tools = [ctx.file.version_file] + if ctx.attr.swift_tools: + additional_tools += ctx.attr.swift_tools[SwiftToolsInfo].additional_inputs ++ if external_static_runtime: ++ additional_tools += external_static_runtime.files.to_list() +- ++ + all_tool_configs = _all_tool_configs( + env = ctx.attr.env, +@@ -873,7 +953,7 @@ def _swift_toolchain_impl(ctx): + system_modules = collect_implicit_deps_providers([]), + implicit_system_modules = collect_implicit_deps_providers([]), + swift_worker = ctx.attr._worker[DefaultInfo].files_to_run, +- const_protocols_to_gather = ctx.file.const_protocols_to_gather, ++ const_protocols_to_gather = None if external_static_runtime else ctx.file.const_protocols_to_gather, + test_configuration = struct( + binary_name = "{name}", + env = env, +@@ -952,6 +1032,10 @@ context. + """, + allow_files = True, + ), ++ "external_static_runtime": attr.label( ++ doc = "External static Swift runtime and SDK to use instead of the compiler's runtimes.", ++ providers = [[SwiftStaticRuntimeInfo]], ++ ), + "static_runtime": attr.label_list( + doc = """\ + Static Swift runtime archives and supporting linker files that are passed to 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 index 4f98e32f3d62..8467cad623bc 100644 --- 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 @@ -2,7 +2,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-249WJ4YEH2HmxlvGftl4eD53792joKJx9Dh0j5eHAgo=" + "register_downloaded_macos_toolchain.patch": "sha256-249WJ4YEH2HmxlvGftl4eD53792joKJx9Dh0j5eHAgo=", + "external_static_runtime.patch": "sha256-VY8UPZjCdlLjDB4taEpRfENRlkw4pGNYD2MAgNFITC4=" }, "patch_strip": 1 } diff --git a/unified/BUILD.bazel b/unified/BUILD.bazel index 738a95b31552..d17a7c505669 100644 --- a/unified/BUILD.bazel +++ b/unified/BUILD.bazel @@ -42,10 +42,7 @@ codeql_pkg_files( codeql_pkg_files( name = "extractor-arch", exes = codeql_platform_select( - linux64 = [ - "//unified/extractor", - "//unified/swift-syntax-rs:swift_runtime_libs", - ], + linux64 = ["//unified/extractor"], linux_arm64 = ["//unified/extractor-unsupported-os:extractor"], osx64 = ["//unified/extractor"], win64 = ["//unified/extractor-unsupported-os:extractor"], diff --git a/unified/extractor/BUILD.bazel b/unified/extractor/BUILD.bazel index 7959ffe384ad..f8814c4572a1 100644 --- a/unified/extractor/BUILD.bazel +++ b/unified/extractor/BUILD.bazel @@ -13,10 +13,7 @@ codeql_rust_binary( "ast_types.yml", "swift_node_types.yml", ], - data = select({ - "@platforms//os:linux": ["//unified/swift-syntax-rs:swift_runtime_libs"], - "//conditions:default": [], - }), + data = ["//unified/swift-syntax-rs:swift_runtime"], proc_macro_deps = all_crate_deps( proc_macro = True, ), @@ -56,10 +53,7 @@ _TESTS = { "swift_node_types.yml", ] + spec["compile_data"], crate_root = "tests/%s.rs" % test_name, - data = spec["data"] + select({ - "@platforms//os:linux": ["//unified/swift-syntax-rs:swift_runtime_libs"], - "//conditions:default": [], - }), + data = spec["data"] + ["//unified/swift-syntax-rs:swift_runtime"], edition = "2024", proc_macro_deps = all_crate_deps( proc_macro = True, diff --git a/unified/swift-syntax-rs/BUILD.bazel b/unified/swift-syntax-rs/BUILD.bazel index 91a28dc40505..374d0d784f3a 100644 --- a/unified/swift-syntax-rs/BUILD.bazel +++ b/unified/swift-syntax-rs/BUILD.bazel @@ -1,38 +1,52 @@ 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("@rules_swift//swift/toolchains:swift_toolchain.bzl", "swift_runtime") load("//unified:platforms.bzl", "UNIFIED_SUPPORTED_PLATFORMS") -load(":swift_runtime.bzl", "swift_runtime_libs") -load(":swift_runtime_linking.bzl", "swift_runtime_linking") package(default_visibility = ["//visibility:public"]) -swift_runtime_libs( - name = "swift_runtime_libs", - toolchain = "@swift_toolchain_ubuntu22.04//:files", +config_setting( + name = "static_linux_runtime", + constraint_values = [ + "@platforms//os:linux", + "//:static_swift_runtime", + ], ) -swift_runtime_linking( - name = "_swift_runtime_cc_info", - target_compatible_with = ["@platforms//os:linux"], - visibility = ["//visibility:private"], +swift_runtime( + name = "_swift_runtime", ) -# On Linux, provide the downloaded Swift runtime at link time and look beside -# the executable for the copies bundled with the extractor at runtime. -cc_library( - name = "swift_runtime_linking", - linkopts = select({ - "@platforms//os:linux": ["-Wl,-rpath,$$ORIGIN"], - "//conditions:default": [], - }), - target_compatible_with = UNIFIED_SUPPORTED_PLATFORMS, - deps = select({ - "@platforms//os:linux": [":_swift_runtime_cc_info"], +filegroup( + name = "swift_runtime", + srcs = select({ + ":static_linux_runtime": [], + "@platforms//os:linux": [":_swift_runtime"], "//conditions:default": [], }), ) +cc_library( + name = "static_runtime_group_start", + linkopts = ["-Wl,--start-group"], + target_compatible_with = ["@platforms//os:linux"], +) + +cc_library( + name = "static_runtime_group_end", + linkopts = [ + "-lc", + "-ldl", + "-lm", + "-lpthread", + "-lrt", + "-lutil", + "-Wl,--end-group", + ], + target_compatible_with = ["@platforms//os:linux"], +) + # Swift FFI shim: wraps swift-syntax and exposes a small C ABI. swift_library( name = "swift_syntax_ffi", @@ -56,10 +70,21 @@ rust_library( ), edition = "2024", target_compatible_with = UNIFIED_SUPPORTED_PLATFORMS, - deps = [ - ":swift_runtime_linking", - ":swift_syntax_ffi", - ], + deps = select({ + ":static_linux_runtime": [ + # Keep these in linker order; sorting them produces an invalid group. + ":static_runtime_group_start", + ":swift_syntax_ffi", + ":static_runtime_group_end", + ], + "@platforms//os:linux": [ + ":_swift_runtime", + ":swift_syntax_ffi", + ], + "//conditions:default": [ + ":swift_syntax_ffi", + ], + }), ) # A debugging aid, for looking at the raw swift-syntax JSON for some input: @@ -68,10 +93,7 @@ rust_library( rust_binary( name = "swift-syntax-parse", srcs = ["src/main.rs"], - data = select({ - "@platforms//os:linux": [":swift_runtime_libs"], - "//conditions:default": [], - }), + data = [":swift_runtime"], edition = "2024", target_compatible_with = UNIFIED_SUPPORTED_PLATFORMS, deps = [":swift_syntax_rs"], @@ -81,10 +103,7 @@ rust_test( name = "swift_syntax_rs_test", size = "small", crate = ":swift_syntax_rs", - data = select({ - "@platforms//os:linux": [":swift_runtime_libs"], - "//conditions:default": [], - }), + data = [":swift_runtime"], edition = "2024", target_compatible_with = UNIFIED_SUPPORTED_PLATFORMS, ) diff --git a/unified/swift-syntax-rs/swift_runtime.bzl b/unified/swift-syntax-rs/swift_runtime.bzl deleted file mode 100644 index 899d97d71162..000000000000 --- a/unified/swift-syntax-rs/swift_runtime.bzl +++ /dev/null @@ -1,19 +0,0 @@ -"""Filter the Swift toolchain down to just its Linux runtime shared objects. - -The standalone toolchain's `:files` bundles the compiler, host libraries, clang -runtime, plugins, etc. For running a Swift-linked binary we only need the -runtime shared objects in `usr/lib/swift/linux/`. -""" - -def _swift_runtime_libs_impl(ctx): - libs = [ - f - for f in ctx.files.toolchain - if "/usr/lib/swift/linux/" in f.path and f.path.endswith(".so") - ] - return [DefaultInfo(files = depset(libs))] - -swift_runtime_libs = rule( - implementation = _swift_runtime_libs_impl, - attrs = {"toolchain": attr.label(allow_files = True)}, -) diff --git a/unified/swift-syntax-rs/swift_runtime_linking.bzl b/unified/swift-syntax-rs/swift_runtime_linking.bzl deleted file mode 100644 index ec2577d2e3df..000000000000 --- a/unified/swift-syntax-rs/swift_runtime_linking.bzl +++ /dev/null @@ -1,11 +0,0 @@ -"""Expose the selected Swift toolchain's dynamic runtime to native dependents.""" - -load("@rules_swift//swift:swift.bzl", "swift_common") - -def _swift_runtime_linking_impl(ctx): - return [swift_common.get_toolchain(ctx).dynamic_runtime_cc_info] - -swift_runtime_linking = rule( - implementation = _swift_runtime_linking_impl, - toolchains = swift_common.use_toolchain(), -)