> Cosmopolitan Libc makes C a build-once run-anywhere language, like Java, except it doesn't need an interpreter or virtual machine.
... and it only supports x86 (without binary translation), right? It's great to see progress like this, but it's poor form to suggest it's build-once run-anywhere in the same sense that Java is. As far as I can tell, it's not trivial to run these binaries on a RPi.
There is actually a discussion on that on this page, I'll embed part of the relevant discussion here:
> It'll be nice to know that any normal PC program we write will "just work" on Raspberry Pi and Apple ARM. All we have to do embed an ARM build of the emulator above within our x86 executables, and have them morph and re-exec appropriately, similar to how Cosmopolitan is already doing doing with qemu-x86_64, except that this wouldn't need to be installed beforehand. The tradeoff is that, if we do this, binaries will only be 10x smaller than Go's Hello World, instead of 100x smaller. The other tradeoff is the GCC Runtime Exception forbids code morphing, but I already took care of that for you, by rewriting the GNU runtimes.
Not exactly what you meant, perhaps, but in the same ball-park
This is great for x86, but for low-overhead multi-platform binaries, IBM came up with a pretty good solution decades ago with OS/400 TIMI (Technology Independent Machine Interface), which is basically Android Runtime's install-time native code generation, but suitable as a C/RPG/COBOL/CL compilation target and not mandating a garbage collector.
Given Apple has undergone 3 CPU architecture migrations by now and employs Chris Latner, I was hoping they'd move to something vaguely like a modernized version of TIMI (maybe based on LLVM bitcode) as the default XCode target for Apple Silicon. Rosetta has been good enough so far, but I can see a future where Apple starts really specializing cores (say ultra-low power cores for watches and glasses or an extreme form of big.LITTLE) to the point where it makes sense for them to have radically new instruction encodings.
> This is great for x86, but for low-overhead multi-platform binaries, IBM came up with a pretty good solution decades ago with OS/400 TIMI (Technology Independent Machine Interface), which is basically Android Runtime's install-time native code generation, but suitable as a C/RPG/COBOL/CL compilation target and not mandating a garbage collector.
To be honest, I think the dream of portability which TIMI represented is mostly dead in recent IBM i versions. More and more functionality depends on the AIX compatibility environment, PASE, which doesn't run under TIMI, it is full of standard AIX XCOFF binaries containing POWER machine code. (Interspersed with calls to IBM i-specific APIs which allow PASE binaries to access services provided by code running inside and underneath TIMI.) Given the increasing use of PASE as time goes by, porting IBM i environments to something other than POWER (if IBM were ever inclined) has become closer to being as hard as porting AIX – which is to say, as hard as any other operating system. TIMI has evolved from a genuine source of portability (which greatly aided IBM in the CISC-to-RISC transition) into being little more than a historical vestige and form of backward-compatibility.
Very nice. I hope that in the future, native code will be the distribution format about as often as we write inline assembly. Sometimes you'll really need precise control over instructions, but for 99% of code, it's not worth the cost in giving up long-term technology improvements.
In particular, x86's total store ordering memory model causes some memory fences to disappear at the machine code level. The Aarch64 relaxed memory model allows for lower cache synchronization overhead, but code with correct memory fences compiled to x86 loses this information, requiring overly conservative binary translation/higher overhead TSO mode in Aarch64 binary translators. These days, hardware acquire/release/full flavors of memory fences better match the C++ and Java memory models, but some hardware has load/store/full flavors of memory fences. Binary translation across these flavors means changing all fences to full fences, or else some static analysis that's far beyond anything I'm aware existing at this time.
Afaik bitcode remains architecture-dependent, so bitcode deployments is mostly do they can re-optimise, and a convenient component of app slicing (if they end up generating the final bundle anyway, having more visibility into what’s what is useful).
I think re-targeting bitcode for a different architecture with the same pointer size and endinness is a pretty light weight operation, but I might be wrong. I'm pretty sure it's orders of magnitude lower overhead and less complicated than dynamically recompiling native code.
I've gotta second this. Maybe it's just being a grouchy pedant, but this "just" produces a polyglot x86_64 executable with a polyglot program header that rewrites its payload into the appropriate executable format for one of 4/5 supported OSes.
It's extremely impressive, and dare I say useful for several cases, but it isn't really like java unless you squint really hard and pretend virtualization/emulators like QEMU are akin to a JVM, which is the way I understand that claim is supposed to be taken.
I mean, the analogy works, and I respect why the author believes this is more practically useful than Java, but it's like saying (IMO) that Linux binaries are a universal standard because you can just virtualize or emulate a Linux kernel on the cheap, a la Docker for the Desktop or whatever it's called.
The 2-line intro says the format will run on a impressively long list of systems. Is it really that big of a deal that it doesn't specifically mention that it is x86-only? Please.
The problem is, the landing page says it's "similar to Java" right in the first sentence and in the second sentence "same portability benefits as high-level languages like Go and Rust", and later on "excellent performance on modern desktops and servers" and "compared with glibc, you should expect Cosmopolitan to be almost as fast".
The tricky part is, those claims are all true, they're just not all true at the same time. The portability claims are true (only if you ignore performance), the performance claims are true (only if you're on x86-64).
We learned yesterday on HN that Java 1.0 was only able to run on two systems: Windows and Solaris. https://github.com/ufuu/Java-JDK10 Cosmopolitan 1.0 runs on Windows, Linux, Mac, FreeBSD, OpenBSD, NetBSD, and boots from BIOS on bare metal all in a single 12kb file. https://justine.lol/cosmopolitan/howfat.html If we consider that Java today is on version 17, then I'd ask you to imagine where Cosmopolitan v17 will be in the future.
What's with all the nitpicking? I just don't get it. What is claimed today is entirely reasonable.
The landing page says SIMILAR to Java. It doesn't say runs identically on exactly all versions of every system that Java programs will run on.
Also, this is a C binary we are talking about. Fundamentally, a C binary will not run on multiple architectures (at least not without some sort of special translation mechanism like Rosetta or qemu user-mode emulation).
"Modern desktops and servers" is still pretty much x86-64 for most of the world. Yes, I know there are ARM servers and I'm typing this on an M1 Mac and I own nearly all kinds of Raspberry Pi's (even the minor revs of some models).
> Fundamentally, a C binary will not run on multiple architectures (at least not without some sort of special translation mechanism like Rosetta or qemu user-mode emulation).
The C machine model doesn't dictate native compilation. You could (and in fact IBM OS/400 does[0]) compile C to a binary format that does run on multiple architectures.
Maybe instead of "C binary" you meant "C compiled to native binary", but that linguistic shortcut also encourages a mental shortcut that excludes several interesting design tradeoffs. In the IBM TIMI case, the equivalent of setting the execute bit on the binary triggers OS/400 to perform the native code generation and save that native code to disk, similar to some versions of Android Runtime, but without mandatory garbage collection.
... and it only supports x86 (without binary translation), right? It's great to see progress like this, but it's poor form to suggest it's build-once run-anywhere in the same sense that Java is. As far as I can tell, it's not trivial to run these binaries on a RPi.