summaryrefslogtreecommitdiff
path: root/chromium/docs/mac_lld.md
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/docs/mac_lld.md')
-rw-r--r--chromium/docs/mac_lld.md126
1 files changed, 126 insertions, 0 deletions
diff --git a/chromium/docs/mac_lld.md b/chromium/docs/mac_lld.md
new file mode 100644
index 00000000000..85b919ed320
--- /dev/null
+++ b/chromium/docs/mac_lld.md
@@ -0,0 +1,126 @@
+# LLD for Mac builds
+
+*Disclaimer* We don't use LLD for Mac builds. Using it is not supported, and
+if you try to use it, it likely won't work. Only keep reading if you want to
+work on the build.
+
+## Background
+
+Chromium uses [LLD](https://lld.llvm.org/) as linker on all platforms,
+except when targeting macOS or iOS. LLD is faster than other ELF linkers (ELF
+is the executable file format used on most OSs, including Linux, Android,
+Chrome OS, Fuchsia), and it's faster than other COFF linkers (the executable
+file format on Windows).
+
+ld64, the standard Mach-O linker (the executable file format on iOS and macOS),
+is on the other hand already fairly fast and works well, so there are fewer
+advantages to using LLD here. (Having said that, LLD is currently 4x faster
+at linking Chromium Framework than ld64 in symbol\_level=0 release builds,
+despite ld64 being already fast. Maybe that's due to LLD not yet doing
+critical things and it will get slower, but at the moment it's faster than
+ld64.)
+
+LLD does have a few advantages unrelated to speed, however:
+
+- It's developed in the LLVM repository, and we ship it in our clang package
+ (except on macOS, where it's not in the default clang package but an opt-in
+ download instead). We can fix issues upstream and quickly deploy fixed
+ versions, instead of having to wait for Xcode releases (which is where ld64
+ ships).
+
+- For the same reason, it has a much simpler LTO setup: Clang and LLD both link
+ in the same LLVM libraries that are built at the same revision, and compiler
+ and linker bitcodes are interopable for that reason. With ld64, the LTO code
+ has to be built as a plugin that's loaded by the linker.
+
+- LLD/Mach-O supports "LLVM-y" features that the ELF and COFF LLDs support as
+ well, such as thin archives, colored diagnostics, and response files
+ (ld64 supports this too as of Xcode 12, but we had to wait many years for it,
+ and it's currently [too crashy](https://crbug.com/1147968) to be usable).
+
+For that reason, it's possible to opt in to LLD for macOS builds (not for
+iOS builds, and that's intentionally not in scope).
+
+A background note: There are two versions of LLD upstream: The newer ports
+that are nowadays used for ELF and COFF, and an older design that's still the
+default Mach-O LLD. There's however an effort underway to write a new Mach-O
+LLD that's built on the same design as the ELF and COFF ports. Chromium Mac
+builds uses the new Mach-O port of LLD ("`ld64.lld.darwinnew`").
+
+Just like the LLD ELF port tries to be commandline-compatible with other ELF
+linkers and the LLD COFF port tries to be commandline-compatible with the
+Visual Studio linker link.exe, the LLD Mach-O port tries to be
+commandline-compatible with ld64. This means LLD accepts different flags on
+different platforms.
+
+## Current status and known issues
+
+A `symbol_level = 0` `is_debug = false` `use_lld = true` build produces
+a mostly-working Chromium.app, but there are open issues and missing features:
+
+- LLD does not yet have any ARM support
+ - relocations are missing
+ ([in-progress patch](https://reviews.llvm.org/D88629))
+ - ad-hoc code signing is missing
+- LLD produces bad debug info, and LLD-linked binaries don't yet show C++
+ source code in a debugger ([bug](https://llvm.org/PR48714)]
+- LLD doesn't produce unwind info, so code relying on exceptions doesn't work
+ ([bug](https://llvm.org/PR48389))
+- We haven't tried actually running any other binaries, so chances are many
+ other tests fail
+- LLD doesn't yet implement `-dead_strip`, leading to many linker warnings
+- LLD doesn't yet implement deduplication (aka "ICF")
+- LLD doesn't yet call graph profile sort
+- LLD doesn't yet implement `-exported_symbol` or `-exported_symbols_list`,
+ leading to some linker warnings
+
+## Opting in
+
+1. First, obtain lld. Do either of:
+
+ 1. run `src/tools/clang/scripts/update.py --package=lld_mac` to download a
+ prebuilt lld binary.
+ 2. build `lld` and `llvm-ar` locally and copy it to
+ `third_party/llvm-build/Relase+Asserts/bin`. Also run
+ `ln -s lld third_party/llvm-build/Release+Asserts/bin/ld64.lld.darwinnew`.
+
+ You have to do this again every time `runhooks` updates the clang
+ package.
+
+ The prebuilt might work less well than a more up-to-date, locally-built
+ version -- see the list of open issues above for details. If anything is
+ marked "fixed upstream", then the fix is upstream but not yet in the
+ prebuilt lld binary.
+
+2. Add `use_lld = true` to your args.gn
+
+3. Then just build normally.
+
+`use_lld = true` makes the build use thin archives. For that reason, `use_lld`
+also switches from `libtool` to `llvm-ar`.
+
+## Creating stand-alone repros for bugs
+
+For simple cases, LLD's `--reproduce=foo.tar` flag / `LLD_REPRODUCE=foo.tar`
+env var is sufficient.
+
+See "Note to self:" [here](https://bugs.llvm.org/show_bug.cgi?id=48657#c0) for
+making a repro file that involved the full app and framework bundles.
+
+Locally, apply this patch before building chrome to make a repro that can
+be used with both lld and ld (useful for making comparisons):
+
+ diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
+ index 5ea2f2130abb..ed871642cee9 100644
+ --- a/build/config/compiler/BUILD.gn
+ +++ b/build/config/compiler/BUILD.gn
+ @@ -1780,7 +1780,7 @@ config("export_dynamic") {
+ config("thin_archive") {
+ # The macOS and iOS default linker ld64 does not support reading thin
+ # archives.
+ - if ((is_posix && !is_nacl && (!is_apple || use_lld)) || is_fuchsia) {
+ + if ((is_posix && !is_nacl && (!is_apple)) || is_fuchsia) {
+ arflags = [ "-T" ]
+ } else if (is_win && use_lld) {
+ arflags = [ "/llvmlibthin" ]
+