Skip to content

Commit 0122729

Browse files
authored
rules_swift patch: point macOS platform_lib_dir at usr/lib/swift/macosx
Swift.org macOS toolchains store their runtime libraries under usr/lib/swift/macosx/ (Apple's SDK name), not usr/lib/swift/macos/ (the Bazel @platforms//os:macos name). rules_swift 4.0.0-rc4's _swift_unix_linkopts_cc_info uses the latter, causing -L to point at a non-existent directory and ld to fail with undefined swiftCompatibility{56,Concurrency,Packs} symbols on macOS. Rewrite platform_lib_dir to `usr/lib/swift/macosx` on the macOS branch of the existing patch so the -L / -Wl,-rpath resolve to a real dir that already gets materialized into the sandbox via swift_tools' `additional_inputs = glob(["usr/lib/swift/**", ...])`.
1 parent 967e298 commit 0122729

1 file changed

Lines changed: 62 additions & 22 deletions

File tree

misc/bazel/patches/rules_swift/macos-linkopts.patch

Lines changed: 62 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,64 @@
1-
Skip Linux-only linkopts when generating macOS Swift toolchain linker inputs.
1+
Emit macOS-appropriate linkopts when generating macOS Swift toolchain
2+
linker inputs.
23

34
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).
5+
`swift_toolchain(...)` for macOS whose implicit linker inputs are produced
6+
by `_swift_unix_linkopts_cc_info`. That function has two problems on macOS:
117

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.
8+
1. It unconditionally emits Linux/ELF-only flags -- `swiftrt.o`,
9+
`-lstdc++`, `-lrt`, `-ldl`, `-static-libgcc` -- plus a Linux-shaped
10+
runtime path (`{arch}/swiftrt.o` with `arch = "aarch64"`, but the
11+
macOS toolchain lays out `usr/lib/swift/macosx/` without `swiftrt.o`
12+
at all and uses `arm64` for Apple Silicon).
1813

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:
14+
2. It builds the Swift runtime library path as
15+
`{toolchain_root}/lib/swift/{os}` using the `os` value passed in from
16+
`_swift_toolchain_impl`, which is `"macos"` (the Bazel
17+
`@platforms//os:macos` name). But a Swift.org macOS toolchain -- the
18+
one rules_swift materializes via `swift_tools`' `additional_inputs =
19+
glob(["usr/lib/swift/**", ...])` -- actually stores its libraries
20+
under `usr/lib/swift/`**`macosx`**`/` (Apple's SDK name), not
21+
`usr/lib/swift/macos/`. `-L .../usr/lib/swift/macos` therefore points
22+
at a non-existent directory, so `libswiftCompatibility56.a`,
23+
`libswiftCompatibilityConcurrency.a`,
24+
`libswiftCompatibilityPacks.a` (auto-linked via `LC_LINKER_OPTION`
25+
records in swiftc-emitted `.o` files) can't be resolved, and their
26+
symbols end up undefined.
27+
28+
On macOS the Apple linker handles Swift runtime initialization
29+
automatically via `LC_LINKER_OPTION` autolinking and
30+
`__DATA,__mod_init_func`, so `swiftrt.o` is neither present nor needed.
31+
The Linux-specific system libraries (`-lrt`, `-ldl`, `-lstdc++`,
32+
`-static-libgcc`) also don't exist. The only linkopts that carry over
33+
are the toolchain library search path and rpath -- rewritten to point
34+
at `macosx` -- so downstream binaries can locate `libswiftCore.dylib`
35+
and the compatibility static archives.
36+
37+
Without this patch, linking any `swift_library`-dependent Rust binary
38+
(e.g. `//unified/swift-syntax-rs:swift-syntax-parse`) on macOS fails
39+
with either:
2140

2241
clang: error: no such file or directory:
2342
'external/rules_swift+.../usr/lib/swift/macos/aarch64/swiftrt.o'
2443

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.
44+
(problem 1, pre-patch), or:
45+
46+
ld: warning: search path
47+
'external/rules_swift+.../usr/lib/swift/macos' not found
48+
ld: warning: Could not find or use auto-linked library
49+
'swiftCompatibility56': library 'swiftCompatibility56' not found
50+
Undefined symbols for architecture arm64: ...
51+
ld: symbol(s) not found for architecture arm64
52+
53+
(problem 2, if only problem 1 is fixed).
54+
55+
This should be fixed upstream: rules_swift's standalone toolchain
56+
extension needs a macOS-aware `_swift_unix_linkopts_cc_info`. Until
57+
then, we patch the module locally so macOS consumers can build.
2858

2959
--- a/swift/toolchains/swift_toolchain.bzl
3060
+++ b/swift/toolchains/swift_toolchain.bzl
31-
@@ -411,25 +411,38 @@
61+
@@ -411,25 +411,48 @@
3262
toolchain_root = toolchain_root,
3363
)
3464

@@ -57,9 +87,19 @@ module locally so macOS consumers can build.
5787
+ # __DATA,__mod_init_func; swiftrt.o is neither present in the
5888
+ # toolchain layout nor needed. The Linux-specific system libraries
5989
+ # (-lrt, -ldl, -lstdc++, -static-libgcc) also don't exist here.
90+
+ #
91+
+ # Also, a Swift.org macOS toolchain stores its libraries under
92+
+ # `usr/lib/swift/macosx/` (Apple's SDK name), not the Bazel
93+
+ # `os = "macos"` name that `_swift_toolchain_impl` passes in. Rewrite
94+
+ # `platform_lib_dir` to point at `macosx` so `-L` and `-Wl,-rpath`
95+
+ # resolve to a real directory (and thus `libswiftCompatibility*.a`,
96+
+ # `libswiftCore.dylib`, etc. can be found by the linker).
97+
+ macos_platform_lib_dir = "{toolchain_root}/lib/swift/macosx".format(
98+
+ toolchain_root = toolchain_root,
99+
+ )
60100
+ linkopts = [
61-
+ "-L{}".format(platform_lib_dir),
62-
+ "-Wl,-rpath,{}".format(platform_lib_dir),
101+
+ "-L{}".format(macos_platform_lib_dir),
102+
+ "-Wl,-rpath,{}".format(macos_platform_lib_dir),
63103
+ ] + [
64104
+ "-Wl,-rpath,{}".format(rpath)
65105
+ for rpath in additional_rpaths

0 commit comments

Comments
 (0)