Expand description
The linker command line, as a function of the target and the sysroot and nothing else.
Design: spec/cross-compile/11-linking.md section 11.3, which is a list of eight things a
system linker gets right by default on the machine it came with and gets wrong when it is asked
to link for another one.
§Why this is a pure function
Section 11.3 ends with the shape: (tuple, sysroot, options) -> argv, no environment reads, no
filesystem probing. That is not tidiness, it is what makes the highest consequence code in the
driver testable. A link line is the last thing that touches a binary and the first thing that
can quietly ruin it, and a function that reads the machine it runs on can only be tested on the
machine it runs on. This one is tested for every target in the table from any host, and
tests/link-lines is what it produced for each of them when it was last changed.
The mirror of that rule is the one crate::search enforces for headers: nothing from the host
reaches the line. No /usr/lib, no /lib64, no LIBRARY_PATH, and no start file found by
looking around. Every path here is either under the sysroot or something the user wrote on the
command line themselves, and nothing_on_the_line_comes_from_the_host is that as a test.
§What is not decided here
Which linker runs. spec/cross-compile/11-linking.md section 11.2 picks one per format and the
driver spawns it, and the arguments below are the ones ld, ld.lld and mold all read the
same way. That is a real constraint rather than an aspiration: -static-pie is a compiler driver
flag that none of the three linkers has, so the mode that means it is spelled out here as the
three flags a linker does understand.
§The two formats that have a line
ELF, and PE in mingw-w64’s environment. Both are written in the GNU style, which is the same
syntax for the inputs and a different set of flags, so they share everything below that is about
what has to be linked and differ in what is about the image. The PE line is GNU ld’s PE port and
ld.lld in its MinGW mode, which read each other’s arguments for exactly this reason.
Mach-O and the MSVC ABI are refused rather than approximated. ld64 wants a platform version
load command and a -syslibroot, lld-link wants /MACHINE: and a /DEFAULTLIB: set out of an
SDK that cannot be redistributed, and neither is a different spelling of what is below.
Unsupported says which by name, which is a better answer than a line that looks plausible and
produces nothing that runs.
Structs§
- Invocation
- What the driver knows that the line needs, beyond the target and the sysroot.
Enums§
- Item
- One input to the link, in the position the user wrote it.
- Unsupported
- A target, or a combination of a target and a mode, that has no line here.
Functions§
- argv
- The whole linker command line for this target, not counting the linker itself.
- emulation
- Which of the formats one linker can write is meant, in the name
-mknows it by. - pe_
machine - Which machine a PE linker is to write for, in the name
-mknows it by.