Skip to content

Commit 5068712

Browse files
committed
Always use LLD on darwin
1 parent 6c57c24 commit 5068712

File tree

2 files changed

+31
-58
lines changed

2 files changed

+31
-58
lines changed

toolchain/cc_toolchain_config.bzl

Lines changed: 28 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -136,20 +136,22 @@ 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+
146+
141147
# Similar to link_flags, but placed later in the command line such that
142148
# unused symbols are not stripped.
143149
link_libs = []
144150

145-
# Flags for ar.
146-
archive_flags = []
151+
is_darwin_exec_and_target = exec_os == "darwin" and not is_xcompile
147152

148-
# Linker flags:
149-
if exec_os == "darwin" and not is_xcompile:
150-
# lld is experimental for Mach-O, so we use the native ld64 linker.
151-
# TODO: How do we cross-compile from Linux to Darwin?
152-
use_lld = False
153+
# Linker and archive flags
154+
if is_darwin_exec_and_target:
153155
link_flags.extend([
154156
"-headerpad_max_install_names",
155157
"-fobjc-link-runtime",
@@ -161,21 +163,15 @@ def cc_toolchain_config(
161163
# Pre-installed libtool on macOS has -static as default, but llvm-libtool-darwin needs it
162164
# explicitly. cc_common.create_link_variables does not automatically add this either if
163165
# output_file arg to it is None.
164-
archive_flags.extend([
165-
"-static",
166-
])
166+
archive_flags = ["-static"]
167167
else:
168-
# Note that for xcompiling from darwin to linux, the native ld64 is
169-
# not an option because it is not a cross-linker, so lld is the
170-
# only option.
171-
use_lld = True
172168
link_flags.extend([
173-
"-fuse-ld=lld",
174169
"-Wl,--build-id=md5",
175170
"-Wl,--hash-style=gnu",
176171
"-Wl,-z,relro,-z,now",
177172
])
178173
use_libtool = False
174+
archive_flags = []
179175

180176
# Flags related to C++ standard.
181177
# The linker has no way of knowing if there are C++ objects; so we
@@ -199,20 +195,7 @@ def cc_toolchain_config(
199195
# https://github.com/llvm/llvm-project/commit/0556138624edf48621dd49a463dbe12e7101f17d
200196
cxx_flags.append("-Xclang")
201197
cxx_flags.append("-fno-cxx-modules")
202-
if use_lld:
203-
# For single-platform builds, we can statically link the bundled
204-
# libraries.
205-
link_flags.extend([
206-
"-l:libc++.a",
207-
"-l:libc++abi.a",
208-
"-l:libunwind.a",
209-
# Compiler runtime features.
210-
"-rtlib=compiler-rt",
211-
# To support libunwind.
212-
"-lpthread",
213-
"-ldl",
214-
])
215-
else:
198+
if is_darwin_exec_and_target:
216199
# Several system libraries on macOS dynamically link libc++ and
217200
# libc++abi, so static linking them becomes a problem. We need to
218201
# ensure that they are dynamic linked from the system sysroot and
@@ -228,7 +211,19 @@ def cc_toolchain_config(
228211
"-Bdynamic",
229212
"-L{}lib".format(toolchain_path_prefix),
230213
])
231-
214+
else:
215+
# For single-platform builds, we can statically link the bundled
216+
# libraries.
217+
link_flags.extend([
218+
"-l:libc++.a",
219+
"-l:libc++abi.a",
220+
"-l:libunwind.a",
221+
# Compiler runtime features.
222+
"-rtlib=compiler-rt",
223+
# To support libunwind.
224+
"-lpthread",
225+
"-ldl",
226+
])
232227
elif stdlib == "libc++":
233228
cxx_flags = [
234229
"-std=" + cxx_standard,
@@ -282,7 +277,7 @@ def cc_toolchain_config(
282277
"dwp": tools_path_prefix + "llvm-dwp",
283278
"gcc": wrapper_bin_prefix + "cc_wrapper.sh",
284279
"gcov": tools_path_prefix + "llvm-profdata",
285-
"ld": tools_path_prefix + "ld.lld" if use_lld else "/usr/bin/ld",
280+
"ld": tools_path_prefix + "ld.lld",
286281
"llvm-cov": tools_path_prefix + "llvm-cov",
287282
"llvm-profdata": tools_path_prefix + "llvm-profdata",
288283
"nm": tools_path_prefix + "llvm-nm",
@@ -295,9 +290,8 @@ def cc_toolchain_config(
295290
# This was added to `lld` in this patch: http://reviews.llvm.org/D18814
296291
#
297292
# The oldest version of LLVM that we support is 6.0.0 which was released
298-
# after the above patch was merged, so we just set this to `True` when
299-
# `lld` is being used as the linker.
300-
supports_start_end_lib = use_lld
293+
# after the above patch was merged, so we just set this to `True`.
294+
supports_start_end_lib = True
301295

302296
# Replace flags with any user-provided overrides.
303297
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)