Skip to content

Commit 305c5c5

Browse files
authored
Always use LLD on darwin (#380)
It sounds like a few folks have tried the `-fuse-ld=lld` option and it works for them, so let's try to roll it out more broadly. Fixes: #212 Fixes #324
1 parent cebf1ed commit 305c5c5

File tree

2 files changed

+33
-63
lines changed

2 files changed

+33
-63
lines changed

toolchain/cc_toolchain_config.bzl

Lines changed: 30 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,13 @@ def cc_toolchain_config(
193193
link_flags = [
194194
"--target=" + target_system_name,
195195
"-no-canonical-prefixes",
196+
"-fuse-ld=lld",
196197
]
197198

199+
if exec_os == "darwin":
200+
# These will get expanded by osx_cc_wrapper's `sanitize_option`
201+
link_flags.append("--ld-path=ld.lld" if is_xcompile else "--ld-path=ld64.lld")
202+
198203
stdlib = compiler_configuration["stdlib"]
199204
if stdlib != "none":
200205
link_flags.extend([
@@ -207,45 +212,33 @@ def cc_toolchain_config(
207212
libunwind_link_flags = []
208213
compiler_rt_link_flags = []
209214

210-
# Flags for ar.
211-
archive_flags = []
215+
is_darwin_exec_and_target = exec_os == "darwin" and not is_xcompile
212216

213217
# Linker flags:
214-
if exec_os == "darwin" and not is_xcompile:
215-
# lld is experimental for Mach-O, so we use the native ld64 linker.
216-
# TODO: How do we cross-compile from Linux to Darwin?
217-
use_lld = False
218+
if is_darwin_exec_and_target:
218219
link_flags.extend([
219220
"-headerpad_max_install_names",
220221
"-fobjc-link-runtime",
221222
])
222223

223224
# Use the bundled libtool (llvm-libtool-darwin).
224225
use_libtool = True
225-
226-
# Pre-installed libtool on macOS has -static as default, but llvm-libtool-darwin needs it
227-
# explicitly. cc_common.create_link_variables does not automatically add this either if
228-
# output_file arg to it is None.
229-
archive_flags.extend([
230-
"-static",
231-
])
232226
elif target_arch in ["wasm32", "wasm64"]:
233227
# lld is invoked as wasm-ld for WebAssembly targets.
234-
use_lld = True
235228
use_libtool = False
236229
else:
237-
# Note that for xcompiling from darwin to linux, the native ld64 is
238-
# not an option because it is not a cross-linker, so lld is the
239-
# only option.
240-
use_lld = True
241230
link_flags.extend([
242-
"-fuse-ld=lld",
243231
"-Wl,--build-id=md5",
244232
"-Wl,--hash-style=gnu",
245233
"-Wl,-z,relro,-z,now",
246234
])
247235
use_libtool = False
248236

237+
# Pre-installed libtool on macOS has -static as default, but llvm-libtool-darwin needs it
238+
# explicitly. cc_common.create_link_variables does not automatically add this either if
239+
# output_file arg to it is None.
240+
archive_flags = ["-static"] if is_darwin_exec_and_target else []
241+
249242
# Flags related to C++ standard.
250243
# The linker has no way of knowing if there are C++ objects; so we
251244
# always link C++ libraries.
@@ -259,21 +252,7 @@ def cc_toolchain_config(
259252
"-std=" + cxx_standard,
260253
"-stdlib=libc++",
261254
]
262-
if use_lld:
263-
# For single-platform builds, we can statically link the bundled
264-
# libraries.
265-
link_flags.extend([
266-
"-l:libc++.a",
267-
"-l:libc++abi.a",
268-
])
269-
compiler_rt_link_flags = ["-rtlib=compiler-rt"]
270-
libunwind_link_flags = [
271-
"-l:libunwind.a",
272-
# To support libunwind.
273-
"-lpthread",
274-
"-ldl",
275-
]
276-
else:
255+
if is_darwin_exec_and_target:
277256
# Several system libraries on macOS dynamically link libc++ and
278257
# libc++abi, so static linking them becomes a problem. We need to
279258
# ensure that they are dynamic linked from the system sysroot and
@@ -291,6 +270,20 @@ def cc_toolchain_config(
291270
"-Bstatic",
292271
"-lunwind",
293272
]
273+
else:
274+
# For single-platform builds, we can statically link the bundled
275+
# libraries.
276+
link_flags.extend([
277+
"-l:libc++.a",
278+
"-l:libc++abi.a",
279+
])
280+
compiler_rt_link_flags = ["-rtlib=compiler-rt"]
281+
libunwind_link_flags = [
282+
"-l:libunwind.a",
283+
# To support libunwind.
284+
"-lpthread",
285+
"-ldl",
286+
]
294287

295288
elif stdlib == "libc++":
296289
cxx_flags = [
@@ -368,7 +361,7 @@ def cc_toolchain_config(
368361
"dwp": tools_path_prefix + "llvm-dwp",
369362
"gcc": wrapper_bin_prefix + "cc_wrapper.sh",
370363
"gcov": tools_path_prefix + "llvm-profdata",
371-
"ld": tools_path_prefix + "ld.lld" if use_lld else "/usr/bin/ld",
364+
"ld": tools_path_prefix + "ld.lld",
372365
"llvm-cov": tools_path_prefix + "llvm-cov",
373366
"llvm-profdata": tools_path_prefix + "llvm-profdata",
374367
"nm": tools_path_prefix + "llvm-nm",
@@ -382,9 +375,8 @@ def cc_toolchain_config(
382375
# This was added to `lld` in this patch: http://reviews.llvm.org/D18814
383376
#
384377
# The oldest version of LLVM that we support is 6.0.0 which was released
385-
# after the above patch was merged, so we just set this to `True` when
386-
# `lld` is being used as the linker.
387-
supports_start_end_lib = use_lld
378+
# after the above patch was merged, so we just set this to `True`.
379+
supports_start_end_lib = True
388380

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

toolchain/osx_cc_wrapper.sh.tpl

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,9 @@ function sanitize_option() {
131131
local -r opt=$1
132132
if [[ ${opt} == */cc_wrapper.sh ]]; then
133133
printf "%s" "${toolchain_path_prefix}bin/clang"
134-
elif [[ ${opt} == "-fuse-ld=ld64.lld" ]]; then
135-
echo "--ld-path=${toolchain_path_prefix_abs}bin/ld64.lld"
134+
elif [[ ${opt} == "--ld-path=ld.lld" || ${opt} == "--ld-path=ld64.lld" ]]; then
135+
local ld_name=${opt#--ld-path=}
136+
echo "--ld-path=${toolchain_path_prefix_abs}bin/${ld_name}"
136137
elif [[ ${opt} =~ ^-fsanitize-(ignore|black)list=[^/] ]] && [[ ${script_dir} == /* ]]; then
137138
# shellcheck disable=SC2206
138139
parts=(${opt/=/ }) # Split flag name and value into array.
@@ -149,9 +150,6 @@ for ((i = 0; i <= $#; i++)); do
149150
tmpfile=$(mktemp)
150151
CLEANUP_FILES+=("${tmpfile}")
151152
while IFS= read -r opt; do
152-
if [[ ${opt} == "-fuse-ld=ld64.lld" ]]; then
153-
echo "-fuse-ld=lld" >>"${tmpfile}"
154-
fi
155153
opt="$(
156154
set -e
157155
sanitize_option "${opt}"
@@ -169,26 +167,6 @@ for ((i = 0; i <= $#; i++)); do
169167
fi
170168
done
171169

172-
# On macOS, we use ld as the linker for single-platform builds (i.e., when not
173-
# cross-compiling). Some applications may remove /usr/bin from PATH before
174-
# calling this script, which would make /usr/bin/ld unreachable. For example,
175-
# rules_rust does not set PATH (unless the user explicitly sets PATH in env
176-
# through attributes) [1] when calling rustc, and rustc does not replace an
177-
# unset PATH with a reasonable default either ([2], [3]), which results in CC
178-
# being called with PATH={sysroot}/{rust_lib}/bin. Note that rules_cc [4] and
179-
# rules_go [5] do ensure that /usr/bin is in PATH.
180-
# [1]: https://github.com/bazelbuild/rules_rust/blob/e589105b4e8181dd1d0d8ccaa0cf3267efb06e86/cargo/cargo_build_script.bzl#L66-L68
181-
# [2]: https://github.com/rust-lang/rust/blob/1c03f0d0ba4fee54b7aa458f4d3ad989d8bf7b34/compiler/rustc_session/src/session.rs#L804-L813
182-
# [3]: https://github.com/rust-lang/rust/blob/1c03f0d0ba4fee54b7aa458f4d3ad989d8bf7b34/compiler/rustc_codegen_ssa/src/back/link.rs#L640-L645
183-
# [4]: https://cs.opensource.google/bazel/bazel/+/master:src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java;l=529;drc=72caead7b428fd50164079956ec368fc54a9567c
184-
# [5]: https://github.com/bazelbuild/rules_go/blob/63dfd99403076331fef0775d52a8039d502d4115/go/private/context.bzl#L434
185-
# Let's restore /usr/bin to PATH in such cases. Note that /usr/bin is not a
186-
# writeable directory on macOS even with sudo privileges, so it should be safe
187-
# to add it to PATH even when the application wants to use a very strict PATH.
188-
if [[ ":${PATH}:" != *":/usr/bin:"* ]]; then
189-
PATH="${PATH}:/usr/bin"
190-
fi
191-
192170
# Call the C++ compiler.
193171
"${cmd[@]}"
194172

0 commit comments

Comments
 (0)