Repository navigation
Link LLD's COFF, ELF and Mach-O linkers into talac - #116
Conversation
talac started lld-link, cc or clang as separate programs to link an executable, and wrote the import libraries of a Windows executable by running lld-link /lib. It now links lldCOFF, lldELF, lldMachO and lldCommon statically and runs them in its own process. - A Windows executable is linked by LLD's lld-link with the plan's arguments and needs nothing from the host; its import libraries (kernel32 for TalaRT's archive, talart.dll for the shared library) are written by llvm::object::writeImportLibrary. - A Linux, macOS or BSD executable needs the start-up objects and the C library of its target, which a C compiler knows the places of. talac runs `clang -###` with the plan's arguments, which prints the command line of the linker without running anything, and runs that command line with LLD's ELF or Mach-O linker. A cross target asks clang with --target; a host target is given its triple too. When no clang is on PATH, a host target is linked by cc and its own linker as before. - LinkerCommandOf reads the linker's command line from the driver's output (quoted words, backslash escapes, the last command whose program is a linker); LinkPlanTests read clang output of Linux, macOS and a Windows host. Building: llvm.bzl finds LLD's libraries and headers beside LLVM or in LLD_ROOT (`brew --prefix lld` on macOS), adds the LLVM components LLD uses (all targets, LTO, DTLTO where LLVM has it, debug info, option, TextAPI, the Windows drivers and manifest), and exposes @llvm//:lld with the libraries in link order. LLVM's release for Windows names zlib, zstd and libxml2 among its system libraries without shipping them, so the Windows build takes them from the Bazel Central Registry. The macOS job installs the lld formula. The Linux hosts need the libc++ toolchain with LLD (#115) pinned before this can build there. LldTests, a new native suite, write import libraries for x64 and arm64, check that a refused link reports LLD's messages and that LLD links again afterwards, and link a Windows executable from an object LLVM generates in the test; on a Windows host the executable runs and returns its entry's 42. Locally on Windows: lld_tests 3/12, link_plan_tests 9/103, verify-abi and the Go helper tests pass.
Homebrew's lld formula builds LLD with BUILD_SHARED_LIBS=ON: its libraries are dylibs over libLLVM.dylib, and linking them would put a second copy of LLVM into talac beside the static one. The macOS job now builds lldCommon, lldCOFF, lldELF and lldMachO as static libraries from the source release of the same LLVM version, against Homebrew's LLVM, the way the formula builds LLD, caches them per version and runner, and names them through LLD_ROOT. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
LinkerCommandOf took the name of the program with std::filesystem, which does not treat a backslash as a separator on POSIX, so the parser depended on the host and failed on macOS for the test that reads the output of a Windows host. It now cuts at either separator and drops .exe itself.
Revision 2 of the Linux toolchain carries LLD's static libraries, which talac now links, and is published from main. The helpers and both Containerfiles take its archives by their digests.
The branch already carries the cross-linking work that main received. Its changelog entry named lld-link and cc, which the linkers inside talac have replaced, so the entry keeps what still holds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
std::rand is not thread safe, which clang-tidy refuses, and without a seed it names the same directory in every run. LLVM makes one that is unique.
|
Self-review: LLD's COFF, ELF and Mach-O linkers are linked into talac statically, and |
Link LLD's COFF, ELF and Mach-O linkers into talac
talac started lld-link, cc or clang as separate programs to link an
executable, and wrote the import libraries of a Windows executable by
running lld-link /lib. It now links lldCOFF, lldELF, lldMachO and
lldCommon statically and runs them in its own process.
arguments and needs nothing from the host; its import libraries
(kernel32 for TalaRT's archive, talart.dll for the shared library) are
written by llvm::object::writeImportLibrary.
library of its target, which a C compiler knows the places of. talac
runs
clang -###with the plan's arguments, which prints the commandline of the linker without running anything, and runs that command line
with LLD's ELF or Mach-O linker. A cross target asks clang with
--target; a host target is given its triple too. When no clang is on
PATH, a host target is linked by cc and its own linker as before.
output (quoted words, backslash escapes, the last command whose program
is a linker); LinkPlanTests read clang output of Linux, macOS and a
Windows host.
Building: llvm.bzl finds LLD's libraries and headers beside LLVM or in
LLD_ROOT (
brew --prefix lldon macOS), adds the LLVM components LLDuses (all targets, LTO, DTLTO where LLVM has it, debug info, option,
TextAPI, the Windows drivers and manifest), and exposes @llvm//:lld with
the libraries in link order. LLVM's release for Windows names zlib, zstd
and libxml2 among its system libraries without shipping them, so the
Windows build takes them from the Bazel Central Registry. The macOS job
installs the lld formula. The Linux hosts need the libc++ toolchain with
LLD (#115) pinned before this can build there.
LldTests, a new native suite, write import libraries for x64 and arm64,
check that a refused link reports LLD's messages and that LLD links again
afterwards, and link a Windows executable from an object LLVM generates in
the test; on a Windows host the executable runs and returns its entry's
42. Locally on Windows: lld_tests 3/12, link_plan_tests 9/103,
verify-abi and the Go helper tests pass.