What the hell is a target triple?
61–70 of 139 posts
Re: What the hell is a target triple?
#62Note to author, I'm not sure the word "anachronism" is being used correctly in the intro.
It's being used correctly: something that is conspicuously old-fashioned for its environment is an anachronism. A toolchain that only supports native builds fits.
If someone said "old compilers were usually cross-compilers", that would be an ahistoric statement (somewhat).
If someone used clang in a movie set in the 90s, that would be anachronistic.
Re: What the hell is a target triple?
#63Funny thing I found when I gave up trying to find documentation and read the LLVM source code (seems to be what happened to the author too!): there are actually five components of the triple, not four. I can't remember what the fifth one is, but yeah... insane system. Thanks for writing this up! I wonder if anyone will ever come up with something more sensible.
---
But there's also , see below.Note that there are both canonical and non-canonical triples in use. Canonical triples are output by `config.guess` or `config.sub`; non-canonical triples are input to `config.sub` and used as prefixes for commands.
The field (1st) is what you're running on, and on some systems it includes a version number of sorts. Most 64-bit vs 32-bit differences go here, except if the runtime differs from what is natural (commonly "32-bit pointers even though the CPU is in 64-bit mode"), which goes in instead. Historically, "arm" and "mips" have been a mess here, but that has largely been fixed, in large part as a side-effect of Debian multiarch (whose triples only have to differ from GNU triples in that they canonicalize i[34567]86 to i386, but you should use dpkg-architecture to do the conversion for sanity).
The field (2nd) is not very useful these days. It defaults to "unknown" but as of a few years ago "pc" is used instead on x86 (this means that the canonical triple can change, but this hasn't been catastrophic since you should almost always use the non-canonical triple except when pattern-matching, and when pattern-matching you should usually ignore this field anyway).
The field (3rd) is pretty obvious when it's called that, but it's often called instead since "linux" is an oddity for regularly having a component that differs. On many systems it includes version data (again, Linux is the oddity for having a stable syscall API/ABI). One notable exception: if a GNU userland is used on BSD/Solaris system, a "k" is prepended. "none" is often used for freestanding/embedded compilation, but see .
The field (main part of the 4th) is usually absent on non-Linux systems, but mandatory for "linux". If it is absent, the dash after the kernel is usually removed, except if there are ABI components. Note that "gnu" can be both a kernel (Hurd) and a libc (glibc). Android uses "android" here, so maybe is a bit of a misnomer (it's not "bionic") - maybe ?
, if present, means you aren't doing the historical default for the platform specified by the main fields. Other than "eabi" for ARM, most of this is for "use 32-bit pointers but 64-bit registers".
can be "hf" for 32-bit ARM systems that actually support floats in hardware. I don't think I've seen anything else, though I admit the main reason I separately document this from is because of how Debian's architecture puts it elsewhere.
is the object file format, usually "aout", "coff", or "elf". It can be appended to the kernel field (but before the kernel version number), or replace it if "none", or it can go in the field.
Re: What the hell is a target triple?
#64> Go originally wanted to not have to link any system libraries, something that does not actually work It does work on Linux, the only kernel that promises a stable binary interface to user space. https://www.matheusmoreira.com/articles/linux-system-calls
Does it really tho? I've had address resolution break more than once in go programs.
https://wiki.archlinux.org/title/Domain_name_resolution
https://en.wikipedia.org/wiki/Name_Service_Switch
https://man.archlinux.org/man/getaddrinfo.3
This is user space stuff. You can trash all of this and roll your own mechanism to resolve the names however you want. Go probably did so. Linux will not complain in any way whatsoever.
Linux is the only kernel that lets you do this. Other kernels will break your software if you bypass their system libraries.
Re: What the hell is a target triple?
#65This article should be ignored, since it disregards the canonical origin of target triples (and the fact that it's linked to `configure`): https://git.savannah.gnu.org/cgit/config.git/tree/ The `testsuite/` directory contains some data files with a fairly extensive list of known targets. The vendor field should be considered fully extensible, and new combinations of know machine/kernel/libc shouldn't be considered in…
This article is a very LLVM-centric view, and it does ignore the GNU idea of a target triple, which is essentially $(uname -a)- vendor -$(uname -s), with vendor determined (so far as I can tell) entirely from uname -s, the system name undergoing some amount of butchering, and version numbers sometimes being included and sometimes not, and Linux getting a LIBC tacked on. But that doesn't mean the article should be ign…
Re: What the hell is a target triple?
#66Why does this person have such negative views of GCC and positive bias towards LLVM?
Re: What the hell is a target triple?
#67Earlier quoted context omitted.
I do not think I like this author... > A critical piece of history here is to understand the really stupid way in which GCC does cross compiling. Traditionally, each GCC binary would be built for one target triple. [...] Nobody with a brain does this ^2 You're doing GCC a great disservice by ignoring its storied and essential history. It's over 40 years old, and was created at a time where there were no free/libre co…
"This was the right way to do it forty years ago, so that's why the experience is worse" isn't a compelling reason for a user to suffer today. Also, in this specific case, this ignores the history around LLVM offering itself up to the FSF. gcc could have benefitted from this fresh start too. But purely by accident, it did not.
I vaguely recall the FSF (or maybe only Stallman) arguing against the modular nature of LLVM because a monolothic structure (like GCC's) makes it harder for anti-GPL actors (Apple!) to undermine it. Was this related?
Re: What the hell is a target triple?
#68Noticed endians listed in the table. It seems like little-endian has basically taken over the world in 2025: * https://en.wikipedia.org/wiki/Endianness#Hardware Is there anything that is used a lot that is not little? IBM's stuff? Network byte order is BE: * https://en.wikipedia.org/wiki/Endianness#Networking
IBM's Power chips can run in either little or big modes, but "used a lot" is a stretch
Re: What the hell is a target triple?
#69This article should be ignored, since it disregards the canonical origin of target triples (and the fact that it's linked to `configure`): https://git.savannah.gnu.org/cgit/config.git/tree/ The `testsuite/` directory contains some data files with a fairly extensive list of known targets. The vendor field should be considered fully extensible, and new combinations of know machine/kernel/libc shouldn't be considered in…
This article is a very LLVM-centric view, and it does ignore the GNU idea of a target triple, which is essentially $(uname -a)- vendor -$(uname -s), with vendor determined (so far as I can tell) entirely from uname -s, the system name undergoing some amount of butchering, and version numbers sometimes being included and sometimes not, and Linux getting a LIBC tacked on. But that doesn't mean the article should be ign…
Re: What the hell is a target triple?
#70Funny thing I found when I gave up trying to find documentation and read the LLVM source code (seems to be what happened to the author too!): there are actually five components of the triple, not four. I can't remember what the fifth one is, but yeah... insane system. Thanks for writing this up! I wonder if anyone will ever come up with something more sensible.
There are up to 7 components in a triple, but not all are used at once, the general format is: - - - But there's also , see below. Note that there are both canonical and non-canonical triples in use. Canonical triples are output by `config.guess` or `config.sub`; non-canonical triples are input to `config.sub` and used as prefixes for commands. The field (1st) is what you're running on, and on some systems it include…
See the code starting at line 1144 here: https://llvm.org/doxygen/Triple_8cpp_source.html
The components are arch-vendor-os-environment-objectformat.
It's absolutely full of special cases and hacks. Really at this point I think the only sane option is an explicit list of fixed strings. I think Rust does that.