Skip to main content

Module argv

Module argv 

Source
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 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.

PE in Microsoft’s environment has a line of its own, msvc, because lld-link and link.exe take a different command line rather than a different set of flags. Its libraries come out of a tree --fetch lays out once the person asking has accepted Microsoft’s licence, which is the one sysroot here that is not ours to produce, so the line names the tree’s directories and the libraries by name and leaves the finding to the linker.

Mach-O is refused rather than approximated. ld64 wants a platform version load command and a -syslibroot, which is not a different spelling of what is below. Unsupported says so 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 -m knows it by.
link_machine
Which machine lld-link is to write for, in the name -machine: knows it by.
pe_machine
Which machine a PE linker is to write for, in the name -m knows it by.