I prefer amd64 as it's so much easier to type and scans so much easier. x86_64 is so awkward.
Bikeshed I guess and in the abstract I can see how x86_64 is better, but pragmatism > purity and you'll take my amd64 from my cold dead hands.
As for Go, you can get the GOARCH/GOOS combinations from "go tool dist list". Can be useful at times if you want to ensure your code cross-compiles in CI.
rustc: `rustc --print target-list`
golang: `go tool dist list`
zig: `zig targets`
As the article point out, the complete lack of standardization and consistency in what constitutes a "triple" (sometimes actually a quad!) is kind of hellishly hilarious.
It is actually a quintiple at most because the first part, architecture, may contain a version for e.g. ARM. And yet it doesn't fully describe the actual target because it may require an additional OS version for e.g. macOS. Doubly silly.
But for the rest of us, I'm so glad that I can just cross compile things in Go without thinking about it. The annoying thing with setting up cross compilation in GCC is not learning the naming conventions, it is getting the correct toolchains installed and wired up correctly in your build system. Go just ships that out of the box and it is so much more pleasant.
Its also one thing that is great about zig. Using Go+zig when I need to cross compile something that includes cgo in it is so much better than trying to get GCC toolchains setup properly.
x32 support has not been removed from the Linux kernel. In fact, we‘re still maintaining Debian for x32 in Debian Ports.
I actually do have working code for the triple-to-TargetInfo instantiation portion (which is fun because there's one or two cases that juuuust aren't quite like all of the others, and I'm not sure if that's a bad copy-paste job or actually intentional). But I never got around to working out how to actually integrate the actual bodies of TargetInfo implementations--which provide things like the properties of C/C++ fundamental types or default macros--into the TableGen easily, so that patch is still merely languishing somewhere on my computer.
> Why the Windows people invented a whole other ABI instead of making things clean and simple like Apple did with Rosetta on ARM MacBooks? I have no idea, but http://www.emulators.com/docs/abc_arm64ec_explained.htm contains various excuses, none of which I am impressed by. My read is that their compiler org was just worse at life than Apple’s, which is not surprising, since Apple does compilers better than anyone else in the business.
I was already familiar with ARM64EC from reading about its development from Microsoft over the past years but had not come across the emulators.com link before - it's a stupendous (long) read and well worth the time if you are interested in lower-level shenanigans. The truth is that Microsoft's ARM64EC solution is a hundred times more brilliant and a thousand times better for backwards (and forwards) compatibility than Rosetta on macOS, which gave the user a far inferior experience than native code, executed (sometimes far) slower, prevented interop between legacy and modern code, left app devs having to do a full port to move to use newer tech (or even just have a UI that matched the rest of the system), and was always intended as a merely transitional bit of tech to last the few years it took for native x86 apps to be developed and take the place (usurp) of old ppc ones.
Microsoft's solution has none of these drawbacks (except the noted lack of AVX support), doesn't require every app to be 2x or 3x as large as a sacrifice to the fat binaries hack, offers a much more elegant solution for developers to migrate their code (piecemeal or otherwise) to a new platform where they don't know if it will be worth their time/money to invest in a full rewrite, lets users use all the apps they love, and maintains Microsoft's very much well-earned legacy for backwards compatibility.
When you run an app for Windows 2000 on Windows 11 (x86 or ARM), you don't see the old Windows 2000 aesthetic (and if you do, there's an easy way for users to opt into newer theming rather than requiring the developer to do something about it) and you aren't stuck with bugs from 30 years ago that were long since patched by the vendor many OS releases ago.
I assumed the author was talking about the x86 emulator released for the arm migration a few years ago, not the powerpc one.
It does work on Linux, the only kernel that promises a stable binary interface to user space.
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.
It's just that those executables are going to have to resolve names all by themselves. Chances are they aren't going to do it exactly like glibc does. That may or may not be a problem.
I'm curious. Why isn't getaddrinfo implemented in a similar manner to the loaders that graphics APIs use? Shouldn't that functionality be the responsibility of whatever resolver has been installed?
The only point I'm making is: Linux does not require glibc.
Users and their programs usually do require glibc but that's their choice. It's not mandated. People could theoretically rewrite the entire Linux user space in pure freestanding Rust if they wanted to.
Name Service Switch is just a solution to a problem. There's no law that says Linux systems must have that system. Programs that depend on it will break if it's not there but that's not the fault of Linux.
I assume it works with an all-targets binutils build. I haven't seen anyone building their cross-compilers in this way (at least not in recent memory).
This is one of the biggest differences between clang and GCC: clang has one binary that supports multiple targets, while a GCC build is always target-specific.
It looks like gcc 3.3 through 4.5 just forwards to an external driver; prior to that it seems like it used the same driver for different paths, and after that it is removed.
> No idea what this is, and Google won’t help me.
Seems that Kalimba is a DSP, originally by CSR and now by Qualcomm. CSR8640 is using it, for example https://www.qualcomm.com/products/internet-of-things/consume...
VE is harder to find with such short name.
I see rumors they charge for the compiler though.
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.
<machine>-<vendor>-<kernel>-<libc?><abi?><fabi?>
But there's also <obj>, 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 <machine> 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 <abi> 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 <vendor> 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 <kernel> field (3rd) is pretty obvious when it's called that, but it's often called <os> instead since "linux" is an oddity for regularly having a <libc> 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 <obj>.
The <libc> 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 <libc> is a bit of a misnomer (it's not "bionic") - maybe <userland>?
<abi>, 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".
<fabi> 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 <abi> is because of how Debian's architecture puts it elsewhere.
<obj> 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 <abi> field.
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.
The underlying problem with target triples is that architecture-vendor-system isn't sufficient to uniquely describe the relevant details for specifying a toolchain, so the necessary extra information has been somewhat haphazardly added to the format. On top of that, since the relevance of some of the information is questionable for some tasks (especially the vendor field), different projects have chosen not to care about subtle differences, so the normalization of a triple is different between different projects.
LLVM's definition is not more or less correct than gcc's here, nor are these the only definitions floating around.
Ah, I found a modern one:
i[3456789]86-w64-mingw* does not use winsup
i[3456789]86-*-mingw* with other vendors does use winsup
There are probably more; this is embedded in all sorts of random configure scripts and it is very not-greppable.The GNU Config project is the original.
Frankly being the originators of this deranged scheme is a good reason not to listen to GNU!