The third field of the triplet is for the operating system identifier [1] which can be expressed as two fields in the form of `<sys>-<abi>` [2] as well as just `<sys>`, when applicable. The LLVM docs also refer to the second part of the operating system identifier as the "environment type" [3].
Examples of allowed operating system identifiers could be `freebsd`, `linux-gnu` or `linux-android`. So, while it seems like four components, the last two seem to get combined to refer to a single "operating system identifier".
I'm no expert here, so corrections welcome, I was just curious from your comment and thought I'd share what I had found.
linux-gnu (GNU/Linux) is one component of the triple (x86_64, unknown, linux-gnu). The fact that the hyphen is overloaded to separate both components of the triple and words within those components is unfortunate, but it's probably too difficult to change at this point.
I’ve compiled dozens, maybe hundreds, of cross compilers setting the targets manually and I never knew it was called a triple or the actual format underlying it. TIL
Welcome to target triples. It's usually called a "triple" since there's conventionally three components to the identifier, but in practice, there's often more (or sometimes less!). The point is to unambiguously identify a complete environment for a compiler toolchain. Unfortunately, it kind of doesn't.
Notionally, the base component of the triple is "architecture", "vendor", and "OS". So you might have something like sparc-sun-solaris--SPARC is the architecture, Sun would be the vendor, and solaris would indicate the OS running on SPARC. The OS itself might also incorporate specific version numbers, which can be helpful for the many OSes that do not guarantee ABI stability. This basic triple of identifiers format has a few issues by itself.
First, it's not sufficient to uniquely identify the necessary ABI. The most salient example is hard float (using hardware FPUs) versus soft float (using software libraries to implement floating-point)--this impacts calling conventions, so you need to distinguish which one you're using.
A second issue is with Linux, where the requisite C library is (unusually) not part of the standard operating system. So triples for Linux need to distinguish between which C library you're using as well. This means the OS field becomes linux-gnu or linux-musl among other things.
The distinguishing on C library was backported to Windows for some tooling, to distinguish between building on Windows assuming a standard Windows environment (windows-msvc) or relying on mingw's let's-pretend-Windows-is-Unix (windows-gnu).
As a result our triple is actually four units long, right? Well, the vendor field itself is kind of redundant, so it's not uncommon to omit that field altogether.
And several architectures have been around since approximately forever, resulting in a proliferation of architecture versions. Sometimes they need to be distinguished, so you have, e.g., armv7 and armv8 as different architectures, or i386 versus i686.
Since there's a lot of potential for confusion in such a flexible format, it's obviously important that there's a central committee for coordination. As such, there's an all-important mailing list where all of these issues are handled--oh wait, that's just my fantasy. No, there's no coordination, which means you'll invariably have different people and different tools coming up with their own unique ideas as to what triples to use for any given platform, and these are inconsistent.
Naturally, if you try to ask anyone to give you a list of all the target triples, even just a list of all the ones they support, the response is "sorry, that's too complicated."
So, welcome again to target triples. Be thankful it's not your job to deal with them, unless it actually is, in which case an ample supply of a strong beverage of your choice is recommended.
I haven't (badly) used Rust in over a year, but this was confusing:
x86_64-unknown-linux-gnu and other machine type identifiers are referred to as target triples.
Isn't that four components, i.e a quad? What am I missing?