Skip to content

Commit 1a49d04

Browse files
dzbarskyrrbutani
authored andcommitted
Always use LLD on darwin
1 parent e047cfc commit 1a49d04

File tree

2 files changed

+31
-59
lines changed

2 files changed

+31
-59
lines changed

toolchain/cc_toolchain_config.bzl

Lines changed: 28 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -136,22 +136,23 @@ def cc_toolchain_config(
136136
"--target=" + target_system_name,
137137
"-lm",
138138
"-no-canonical-prefixes",
139+
"-fuse-ld=lld",
139140
]
140141

142+
if exec_os == "darwin":
143+
# These will get expanded by osx_cc_wrapper's `sanitize_option`
144+
link_flags.append("--ld-path=ld.lld" if is_xcompile else "--ld-path=ld64.lld")
145+
141146
# Similar to link_flags, but placed later in the command line such that
142147
# unused symbols are not stripped.
143148
link_libs = []
144149
libunwind_link_flags = []
145150
compiler_rt_link_flags = []
146151

147-
# Flags for ar.
148-
archive_flags = []
152+
is_darwin_exec_and_target = exec_os == "darwin" and not is_xcompile
149153

150-
# Linker flags:
151-
if exec_os == "darwin" and not is_xcompile:
152-
# lld is experimental for Mach-O, so we use the native ld64 linker.
153-
# TODO: How do we cross-compile from Linux to Darwin?
154-
use_lld = False
154+
# Linker and archive flags
155+
if is_darwin_exec_and_target:
155156
link_flags.extend([
156157
"-headerpad_max_install_names",
157158
"-fobjc-link-runtime",
@@ -163,21 +164,15 @@ def cc_toolchain_config(
163164
# Pre-installed libtool on macOS has -static as default, but llvm-libtool-darwin needs it
164165
# explicitly. cc_common.create_link_variables does not automatically add this either if
165166
# output_file arg to it is None.
166-
archive_flags.extend([
167-
"-static",
168-
])
167+
archive_flags = ["-static"]
169168
else:
170-
# Note that for xcompiling from darwin to linux, the native ld64 is
171-
# not an option because it is not a cross-linker, so lld is the
172-
# only option.
173-
use_lld = True
174169
link_flags.extend([
175-
"-fuse-ld=lld",
176170
"-Wl,--build-id=md5",
177171
"-Wl,--hash-style=gnu",
178172
"-Wl,-z,relro,-z,now",
179173
])
180174
use_libtool = False
175+
archive_flags = []
181176

182177
# Flags related to C++ standard.
183178
# The linker has no way of knowing if there are C++ objects; so we
@@ -201,21 +196,7 @@ def cc_toolchain_config(
201196
# https://github.com/llvm/llvm-project/commit/0556138624edf48621dd49a463dbe12e7101f17d
202197
cxx_flags.append("-Xclang")
203198
cxx_flags.append("-fno-cxx-modules")
204-
if use_lld:
205-
# For single-platform builds, we can statically link the bundled
206-
# libraries.
207-
link_flags.extend([
208-
"-l:libc++.a",
209-
"-l:libc++abi.a",
210-
])
211-
compiler_rt_link_flags = ["-rtlib=compiler-rt"]
212-
libunwind_link_flags = [
213-
"-l:libunwind.a",
214-
# To support libunwind.
215-
"-lpthread",
216-
"-ldl",
217-
]
218-
else:
199+
if is_darwin_exec_and_target:
219200
# Several system libraries on macOS dynamically link libc++ and
220201
# libc++abi, so static linking them becomes a problem. We need to
221202
# ensure that they are dynamic linked from the system sysroot and
@@ -233,7 +214,20 @@ def cc_toolchain_config(
233214
"-Bstatic",
234215
"-lunwind",
235216
]
236-
217+
else:
218+
# For single-platform builds, we can statically link the bundled
219+
# libraries.
220+
link_flags.extend([
221+
"-l:libc++.a",
222+
"-l:libc++abi.a",
223+
])
224+
compiler_rt_link_flags = ["-rtlib=compiler-rt"]
225+
libunwind_link_flags = [
226+
"-l:libunwind.a",
227+
# To support libunwind.
228+
"-lpthread",
229+
"-ldl",
230+
]
237231
elif stdlib == "libc++":
238232
cxx_flags = [
239233
"-std=" + cxx_standard,
@@ -287,7 +281,7 @@ def cc_toolchain_config(
287281
"dwp": tools_path_prefix + "llvm-dwp",
288282
"gcc": wrapper_bin_prefix + "cc_wrapper.sh",
289283
"gcov": tools_path_prefix + "llvm-profdata",
290-
"ld": tools_path_prefix + "ld.lld" if use_lld else "/usr/bin/ld",
284+
"ld": tools_path_prefix + "ld.lld",
291285
"llvm-cov": tools_path_prefix + "llvm-cov",
292286
"llvm-profdata": tools_path_prefix + "llvm-profdata",
293287
"nm": tools_path_prefix + "llvm-nm",
@@ -300,9 +294,8 @@ def cc_toolchain_config(
300294
# This was added to `lld` in this patch: http://reviews.llvm.org/D18814
301295
#
302296
# The oldest version of LLVM that we support is 6.0.0 which was released
303-
# after the above patch was merged, so we just set this to `True` when
304-
# `lld` is being used as the linker.
305-
supports_start_end_lib = use_lld
297+
# after the above patch was merged, so we just set this to `True`.
298+
supports_start_end_lib = True
306299

307300
# Replace flags with any user-provided overrides.
308301
if compiler_configuration["compile_flags"] != None:

toolchain/osx_cc_wrapper.sh.tpl

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ function sanitize_option() {
7373
local -r opt=$1
7474
if [[ ${opt} == */cc_wrapper.sh ]]; then
7575
printf "%s" "${execroot_path}%{toolchain_path_prefix}bin/clang"
76-
elif [[ ${opt} == "-fuse-ld=ld64.lld" ]]; then
76+
elif [[ ${opt} == "--ld-path=ld.lld" ]]; then
77+
echo "--ld-path=${execroot_abs_path}%{toolchain_path_prefix}bin/ld.lld"
78+
elif [[ ${opt} == "--ld-path=ld64.lld" ]]; then
7779
echo "--ld-path=${execroot_abs_path}%{toolchain_path_prefix}bin/ld64.lld"
7880
elif [[ ${opt} =~ ^-fsanitize-(ignore|black)list=[^/] ]]; then
7981
# shellcheck disable=SC2206
@@ -88,9 +90,6 @@ cmd=()
8890
for ((i = 0; i <= $#; i++)); do
8991
if [[ ${!i} == @* ]]; then
9092
while IFS= read -r opt; do
91-
if [[ ${opt} == "-fuse-ld=ld64.lld" ]]; then
92-
cmd+=("-fuse-ld=lld")
93-
fi
9493
opt="$(
9594
set -e
9695
sanitize_option "${opt}"
@@ -108,26 +107,6 @@ for ((i = 0; i <= $#; i++)); do
108107
fi
109108
done
110109

111-
# On macOS, we use ld as the linker for single-platform builds (i.e., when not
112-
# cross-compiling). Some applications may remove /usr/bin from PATH before
113-
# calling this script, which would make /usr/bin/ld unreachable. For example,
114-
# rules_rust does not set PATH (unless the user explicitly sets PATH in env
115-
# through attributes) [1] when calling rustc, and rustc does not replace an
116-
# unset PATH with a reasonable default either ([2], [3]), which results in CC
117-
# being called with PATH={sysroot}/{rust_lib}/bin. Note that rules_cc [4] and
118-
# rules_go [5] do ensure that /usr/bin is in PATH.
119-
# [1]: https://github.com/bazelbuild/rules_rust/blob/e589105b4e8181dd1d0d8ccaa0cf3267efb06e86/cargo/cargo_build_script.bzl#L66-L68
120-
# [2]: https://github.com/rust-lang/rust/blob/1c03f0d0ba4fee54b7aa458f4d3ad989d8bf7b34/compiler/rustc_session/src/session.rs#L804-L813
121-
# [3]: https://github.com/rust-lang/rust/blob/1c03f0d0ba4fee54b7aa458f4d3ad989d8bf7b34/compiler/rustc_codegen_ssa/src/back/link.rs#L640-L645
122-
# [4]: https://cs.opensource.google/bazel/bazel/+/master:src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java;l=529;drc=72caead7b428fd50164079956ec368fc54a9567c
123-
# [5]: https://github.com/bazelbuild/rules_go/blob/63dfd99403076331fef0775d52a8039d502d4115/go/private/context.bzl#L434
124-
# Let's restore /usr/bin to PATH in such cases. Note that /usr/bin is not a
125-
# writeable directory on macOS even with sudo privileges, so it should be safe
126-
# to add it to PATH even when the application wants to use a very strict PATH.
127-
if [[ ":${PATH}:" != *":/usr/bin:"* ]]; then
128-
PATH="${PATH}:/usr/bin"
129-
fi
130-
131110
# Call the C++ compiler.
132111
"${cmd[@]}"
133112

0 commit comments

Comments
 (0)