Skip to content

Commit 967e298

Browse files
authored
Patch rules_swift to skip Linux-only linkopts on macOS
1 parent e452647 commit 967e298

3 files changed

Lines changed: 105 additions & 0 deletions

File tree

‎MODULE.bazel‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,19 @@ bazel_dep(name = "googletest", version = "1.17.0.bcr.2")
3333
bazel_dep(name = "rules_rust", version = "0.69.0")
3434
bazel_dep(name = "rules_swift", version = "4.0.0-rc4")
3535
bazel_dep(name = "swift-syntax", version = "602.0.0.bcr.2")
36+
37+
# rules_swift 4.0.0-rc4's standalone toolchain extension unconditionally
38+
# emits Linux/ELF-only linker flags (swiftrt.o, -lstdc++, -lrt, -ldl,
39+
# -static-libgcc) for its macOS toolchain, which breaks any binary linked
40+
# via `swift_library` on macOS. Apply a local patch that skips those flags
41+
# when the toolchain OS is macos. See the patch header and
42+
# `misc/bazel/patches/rules_swift/macos-linkopts.patch` for details.
43+
single_version_override(
44+
module_name = "rules_swift",
45+
patch_strip = 1,
46+
patches = ["//misc/bazel/patches/rules_swift:macos-linkopts.patch"],
47+
version = "4.0.0-rc4",
48+
)
3649
bazel_dep(name = "zstd", version = "1.5.7.bcr.1")
3750

3851
bazel_dep(name = "buildifier_prebuilt", version = "6.4.0", dev_dependency = True)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
exports_files(
2+
glob(["*.patch"]),
3+
visibility = ["//visibility:public"],
4+
)
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
Skip Linux-only linkopts when generating macOS Swift toolchain linker inputs.
2+
3+
rules_swift 4.0.0-rc4's standalone toolchain extension registers a
4+
`swift_toolchain(...)` for macOS whose implicit linker inputs are produced by
5+
`_swift_unix_linkopts_cc_info`. That function unconditionally emits
6+
Linux/ELF-only flags -- `swiftrt.o`, `-lstdc++`, `-lrt`, `-ldl`,
7+
`-static-libgcc` -- plus a Linux-shaped runtime path
8+
(`{arch}/swiftrt.o` with `arch = "aarch64"`, but the macOS toolchain lays
9+
out `usr/lib/swift/macos/` without `swiftrt.o` at all and uses `arm64` for
10+
Apple Silicon).
11+
12+
On macOS the Apple linker handles Swift runtime initialization automatically
13+
via `LC_LINKER_OPTION` autolinking and `__DATA,__mod_init_func`, so
14+
`swiftrt.o` is neither present nor needed. The other flags are also
15+
Linux-specific. The only linkopts that carry over are the toolchain library
16+
search path and rpath so downstream binaries can locate
17+
`libswiftCore.dylib` etc.
18+
19+
Without this patch, linking any `swift_library`-dependent Rust binary (e.g.
20+
`//unified/swift-syntax-rs:swift-syntax-parse`) on macOS fails with:
21+
22+
clang: error: no such file or directory:
23+
'external/rules_swift+.../usr/lib/swift/macos/aarch64/swiftrt.o'
24+
25+
This should be fixed upstream: rules_swift's standalone toolchain extension
26+
needs a macOS-aware `_swift_unix_linkopts_cc_info`. Until then, we patch the
27+
module locally so macOS consumers can build.
28+
29+
--- a/swift/toolchains/swift_toolchain.bzl
30+
+++ b/swift/toolchains/swift_toolchain.bzl
31+
@@ -411,25 +411,38 @@
32+
toolchain_root = toolchain_root,
33+
)
34+
35+
- runtime_object_path = "{platform_lib_dir}/{cpu}/swiftrt.o".format(
36+
- cpu = cpu,
37+
- platform_lib_dir = platform_lib_dir,
38+
- )
39+
-
40+
- linkopts = [
41+
- "-pie",
42+
- "-L{}".format(platform_lib_dir),
43+
- "-Wl,-rpath,{}".format(platform_lib_dir),
44+
- "-lm",
45+
- "-lstdc++",
46+
- "-lrt",
47+
- "-ldl",
48+
- runtime_object_path,
49+
- "-static-libgcc",
50+
- ] + [
51+
- "-Wl,-rpath,{}".format(rpath)
52+
- for rpath in additional_rpaths
53+
- ]
54+
+ if os == "macos":
55+
+ # On macOS, Apple's linker handles Swift runtime initialization
56+
+ # automatically via LC_LINKER_OPTION autolinking and
57+
+ # __DATA,__mod_init_func; swiftrt.o is neither present in the
58+
+ # toolchain layout nor needed. The Linux-specific system libraries
59+
+ # (-lrt, -ldl, -lstdc++, -static-libgcc) also don't exist here.
60+
+ linkopts = [
61+
+ "-L{}".format(platform_lib_dir),
62+
+ "-Wl,-rpath,{}".format(platform_lib_dir),
63+
+ ] + [
64+
+ "-Wl,-rpath,{}".format(rpath)
65+
+ for rpath in additional_rpaths
66+
+ ]
67+
+ else:
68+
+ runtime_object_path = "{platform_lib_dir}/{cpu}/swiftrt.o".format(
69+
+ cpu = cpu,
70+
+ platform_lib_dir = platform_lib_dir,
71+
+ )
72+
+ linkopts = [
73+
+ "-pie",
74+
+ "-L{}".format(platform_lib_dir),
75+
+ "-Wl,-rpath,{}".format(platform_lib_dir),
76+
+ "-lm",
77+
+ "-lstdc++",
78+
+ "-lrt",
79+
+ "-ldl",
80+
+ runtime_object_path,
81+
+ "-static-libgcc",
82+
+ ] + [
83+
+ "-Wl,-rpath,{}".format(rpath)
84+
+ for rpath in additional_rpaths
85+
+ ]
86+
87+
return CcInfo(
88+
linking_context = cc_common.create_linking_context(

0 commit comments

Comments
 (0)