I agree with some of the other comments here, that while this is a very impressive hack (and this is Hacker News!) the real world value seems dubious.<p>It looks like a very clever way of packaging an x86 fat binary for multiple platforms, without actually duplicating the code. To support ARM I assume it’ll need to be an <i>actual</i> fat binary, with both x86 and ARM code. At that point, unless I actually test the code myself on both architectures, how can I be confident it’s going to work properly?<p>If you’re using very simple C constructs and not doing anything fancy, it <i>should</i> work, but it’s not clear to me that this approach is preferable to e.g. a Python script. If you’re doing fancy stuff, it’s a bit more chancy as C isn’t memory-safe and has tons of undefined behavior and platform-specified weirdness.<p>Java is “run anywhere” because they’ve specified the JVM in massive detail and tried to ensure it actually works the same on all platforms. I don’t see how you can have that same confidence if you’re running machine code everywhere.<p>I guess I just don’t see the use case where this is compelling. If I write a handy Unix utility in C, I’ll just keep the source code around, and compile it as needed.<p>It might be handy if you need to move such a utility quickly from Unix to Windows, if you don’t have any dev tools set up. But I can’t think of a situation when I’ve needed that.
I am a bit worried about this:<p>> Please note that your APE binary will assimilate itself as a conventional resident of your platform after the first run, so it can be fast and efficient for subsequent executions.<p>I understand there may be no real way out, but this defeats part of the promise/purpose of PAE: assume I use a pae binary, know it's pae, and implicitly share it or copy it to a different machine. But once I have copied it from ~/bin/ it's not pae any more, it's optimized for my OS/arch!<p>Assuming the first-run optimization step is necessary, would it make sense to provide `--deoptimize` or `--paeize` flag to the same binary, so it's easy to return to the original, without recompiling it from source? Does it lose information when it optimizes? Can that information be tucked away (with an optional flag or env variable) for this step?<p>What happens if the binary is read-only?
Super exciting to see Cosmopolitan progress further! For those wondering what it is, from the website[0]:<p>> Cosmopolitan makes C a build-once run-anywhere language, similar to Java, except it doesn't require interpreters or virtual machines be installed beforehand. Cosmo provides the same portability benefits as high-level languages like Go and Rust, but it doesn't invent a new language and you won't need to configure a CI system to build separate binaries for each operating system. What Cosmopolitan focuses on is fixing C by decoupling it from platforms, so it can be pleasant to use for writing small unix programs that are easily distributed to a much broader audience.<p>[0] <a href="https://justine.lol/cosmopolitan/index.html" rel="nofollow">https://justine.lol/cosmopolitan/index.html</a>
I have been working with Bazel in my personal monorepo (~6 months now), and the fact that Justine, someone I believe knows Bazel/Blaze well, uses GNU Make, makes me re-think my decision: perhaps I should re-consider it. I have quite a few issues with Bazel, which require significant engineering hours to overcome, whereas I could just use gnu make and solve it quickly.<p>Let's see if I can get some inspiration of how things can be built from this repo?<p>`o/$(MODE)/depend`, a makefile-looking file with the full dependency tree. It is compiled using tool/build/mkdeps.c. So we have a Makefile generator (Justine, you mentioned elsewhere in this thread you didn't want to invent a build system? :)) The Makefile generator is very specific to this project: parses C files and creates that tree.<p>It is damn fast and, so far, beautifully documented (at least the build parts I looked). Hell, even documentation lines in file preambles are 72 characters wide, and justified. Crazy. Do you manually justify those?<p>You are also vendoring statically-built GCC, and the folder with executables is <10MB. LLVM C/C++ toolchain is hundreds of megs, compressed.<p>I am certainly taking inspiration of being in tight control of the compiler toolchain, and beautiful documentation. Not sure I will write my Makefile generator, since my project is also not that big.<p>Thanks. Cosmopolitan is giving me much more to look at than an αcτµαlly pδrταblε εxεcµταblε.
> Please note that your APE binary will assimilate itself as a conventional resident of your platform after the first run, so it can be fast and efficient for subsequent executions.<p>Is my understanding correct that the binary changes itself when first run on the target platform? That sounds like it will trigger a lot of red lights with many automated defensive mechanisms like anti virus.
> <a href="https://justine.lol/redbean/index.html" rel="nofollow">https://justine.lol/redbean/index.html</a><p>> All you need to do is download the redbean.com program below, change the filename to .zip, add your content in a zip editing tool, and then change the extension back to .com.<p>> That performance is thanks to zip and gzip using the same compression format, which enables kernelspace copies.<p>Oh my. Having a web server executable which is a zip archive at the same time is a lovely idea. Have there been any other attempts similar to this?
I think there are a number of messages here:<p><pre><code> * Java is slowing our tools down
* amalgamation sqlite style is showing the benefits of tightly written, standalone good old C.
* By extension: monorepos are introducing complexity, since they depend on JVM for blaze/bazel.
* x86 is pervasive in our industry
</code></pre>
People might also want to consider the cost/benefit trade-off for binary vs source compatibility. If you can code in a programming language that works across platforms, can be readily transpiled to one of the supported statically typed languages with a robust, small and fast toolchain, you have any number of packagers who can quickly make binaries for your platform of interest that makes it convenient to install.<p>You get the benefit of better static analysis vs good old C.
You have to love this comment partway through the Linux/BSD deployment instructions, which read slightly more like the Borg manual than compilation docs:<p>> Please note that your APE binary will assimilate itself as a conventional resident of your platform after the first run...
I wonder if anyone has tried using this with Zig (or Rust) yet? I think it'd be quite cool to have this as an out-of-the-box option one can just flip
Wouldn't it be nice if operating systems just collaborated on a shared executable format (that would just wrap the platform native ones) rather than having to hack around this with self-modifying code.
Nit: XNU's version numbers number in the thousands, it's Darwin that is in the teens/early twenties. Darwin 15.6 came out in 2016, not 2018.
How can this work in sandbox distributions?
For example in a snap or flatpak package where a binary is in a read only mode and with limited permissions?
I had no idea Windows NT stood for New Technology. Also, this looks really, really interesting. This is a surely a project I will watch as until now I'd not known about it.
Only major downside of all this amazing portability work I can see is that it seems to be owned by an online advertising services corporation (the author's employer).