diff options
Diffstat (limited to 'chromium/docs/mac_lld.md')
-rw-r--r-- | chromium/docs/mac_lld.md | 126 |
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" ] + |