> The end result is that if you switch your Linux build process to use cosmocc instead of cc then the programs you build, e.g. Bash and Emacs, will just work on the command prompts of totally different platforms like Windows and MacOS, and when you run your programs there, it'll feel like you're on Linux. However portability isn't the only selling point. Cosmo Libc will make your software faster and use less memory too. For example, when I build Emacs using the cosmocc toolchain, Emacs thinks it's building for Linux. Then, when I run it on Windows:
> It actually goes 2x faster than the native WIN32 port that the Emacs authors wrote on their own. Cosmo Emacs loads my dotfiles in 1.2 seconds whereas GNU Emacs on Windows loads them in 2.3 seconds.
That was the most interesting part of the article for me. I don't understand how it can be faster, given that there's syscall translation going on. Is this more of a commentary on the quality of the `libc` available on Windows? Or on the quality of the GNU Emacs Windows port?
Could be like the improvements seen when running applications using DXVK. My understanding is that sometimes these translation layers can use newer and more efficient methods than the path that a native implement for the time would use. I'm not a subject matter expert though, and could be completely off base.
IIUC there is no syscall translation, it's more like there are separate libc implementations and the correct one gets selected at program start based on the OS.
Yes, this seems fairly accurate. In fact I think Wine supports this mode where you link Wine into a "windows program" at build time to produce a "native" Linux executable. So basically the difference is that you target a POSIX API rather than Win32 and the backend implementation is selected at runtime rather than build time. But both projects have the same idea that they will implement a particular API on multiple platforms.
This is all super impressive especially for such a small team.
But we should keep in mind that this project is what POSIX should have been, this is a big patch to make things right, as they should have been more than 20 years ago.
It seems magical because of the failure of numerous other teams and people who never managed to tackle the portability issue with the right mindset and skills.
Is it the job of linux OS people to provide multi-platform executable compatibility with every other OS? That seems like a stretch considering that no OS has ever done that.
You have it backwards on two counts. First count is the point of POSIX is any OS vendor doesn’t need to worry about any other OS compatibility. Just implement POSIX interfaces. Second count is that is OP’s exact point: it never has been done before, because too many OS vendors give POSIX very little thought. This helps realize the original vision of POSIX.
> First count is the point of POSIX is any OS vendor doesn’t need to worry about any other OS compatibility. Just implement POSIX interfaces.
I must be missing something. How are you getting from "just implement POSIX interfaces" to "compile once run everywhere"?
Wouldn't the former just promise that you could compile the same source on any POSIX-compliant OSs and get a binary that runs on that OS, on that architecture?
The binary portability is, in practice, not the most difficult feature, as long as the CPU arch is the same. It is also kind of a hack and IMO a nice-to-have feature but not as vital as true portability.
POSIX was not limited to the Unix world, the goal was for it to be implemented by all OS vendors, and it was partially done.
Doesn't matter. POSIX is "write once, compile everywhere," while this is "compile once, run everywhere." It could be that POSIX is easier to write than for Cosmo bins, shifting the balance between them! I see them as just different endpoints of development.
I think this could be said about pretty much any good invention. The physical world doesn't change much, so the only barrier to invention is human. And I suspect most inventions have someone imagining it long before some other person actually builds it.
If that is so, how was is possible to develop the dependency? By definition it was not available before, so it must be a new development. So by that reasoning it is impossible to ever see something new.
Since you write "Most" there seem to be fewer 'new developments' which do not follow this pattern. So all you really say, is that rare new developments, which do not depend some other innovation, enable many followup innovations.
After all, your argument is not in conflict with the previous argument. You say, that new developments (aka implementations) have dependencies that have to be available before they can be made a reality, while the previous post just said, that long before something can be implemented, someone had imagined/dreamt about it already.
Will it allow native like bash script support on Windows? I use windows as my main OS and use cmder for CLI things but really miss proper bash script support.
Other than bash itself, does it mean it can be used to make whole set of GNU tools cross platform?
Absolutely. cosmos-3.0.1.zip contains bash, GNU coreutils, Emacs, and a whole lot more. All of which run great on the Windows console. On our github release page, there's also a cosmocc zip of a GNU/Linux style GCC compiler. Cosmo provides a refreshing way to build Windows software, because we use the System V ABI (i.e. long is actually 64-bit) when we build Windows software. So there's a much more consistent cross platform development experience.
Tried running bash by renaming it to bash.exe using both CMD and Powershell and both return "Access denied.
Even though Windows 10 already has Terminal and I was getting
[error 2147942405 (0x80070005) when launching `C:\bin\bash -l']
I downloaded Terminal Preview which still throws the same error. Is Terminal or Terminal Preview the only way to run bash? There might be a way to configure cmder to use bash in a similar way you suggested for Terminal. Don't know how yet.
Try whitelisting the folder with Windows Defender. Sometimes when I get EACCES style errors on Windows mysteriously, it's because I need to recalibrate the security on the folder. Here's an example of something I ran once which fixed it.
https://github.com/jart/cosmopolitan/releases/download/3.0.1... is 213MB file which contains "fat binaries" (single binaries that execute on a bewildering array of hardware platforms and operating systems) for dozens of programs, including zip, curl, git, wget, python, ctags and even my own Datasette Python application!
It's absolutely wild that this works.
I just tried it out (on macOS). I downloaded and extracted that zip and did this:
cd ~/Downloads/cosmos-3.0.1/bin
./python -c 'print(4 + 5)'
It refused the first time because of macOS security settings. I had to open the security panel and click "allow"... and then it worked!
Yup, this is basically it. If you check out the "Actually Portable Executable" blogpost by the same author [1] and go to the "PKZIP Executables Make Pretty Good Containers" section there's a note on the approach.
Base https://llm.datasette.io/ should work just fine, but it's basically a thin Python wrapper around the OpenAI Python library which then makes HTTP requests to their API.
The bigger challenge would be LLM with plugins. Those add all sorts of extra dependencies to help LLM run models directly - PyTorch, Transformers, llama-cpp-python etc.
I'd be surprised to see "llm install llm-gpt4all" work for example, since that pulls in compiled Python wheels and I'm not sure it would know which architecture to use.
pip install DOES work:
$ ./python -m pip install httpx
Defaulting to user installation because normal site-packages is not writeable
Collecting httpx
Downloading httpx-0.25.0-py3-none-any.whl (75 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 75.7/75.7 kB 2.7 MB/s eta 0:00:00
...
Successfully installed anyio-4.0.0 h11-0.14.0 httpcore-0.18.0 httpx-0.25.0 sniffio-1.3.0
$ ./python
Python 3.11.4 (heads/pypack1:65ac8ac, Oct 16 2023, 02:35:05) [GCC 11.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import httpx
>>> httpx
<module 'httpx' from '/Users/simon/.local/lib/python3.11/site-packages/httpx/__init__.py'>
$ ls ~/.local/lib/python3.11/site-packages
anyio
anyio-4.0.0.dist-info
h11
h11-0.14.0.dist-info
httpcore
httpcore-0.18.0.dist-info
httpx
httpx-0.25.0.dist-info
sniffio
sniffio-1.3.0.dist-info
That ~/.local/lib/python3.11/ directory didn't exist until I ran the ./python -m pip install command.
Yes, so pip works because the Python APE has OpenSSL built-in.
pip install requires modifying the APE, so I end up installing pure-Python libraries as follows:
mkdir Lib
./python -m pip download httpx
unzip ./*.whl -d ./Lib
mv python python.com # in case the next step doesn't work
zip -r ./python.com Lib
mv python.com python
Installing CPython extensions like this is an unsolved problem, but I think there might be some interesting workarounds possible.
It’s so nice seeing portability over binary size winning all around these days. Such a breath of fresh air. There might be legit cases but for some reason so many people are still hang up on ´but binary size’ for no logical reason whatsoever.
I think a lot of the "logical reason" is driven by more the ephemeral, sandboxed, execution tools. e.g. a `docker run` or `serverless` architectures, where full root filesystems are populated on demand. Less executable data size there can go a long way in reducing latency/price.
> It’s so nice seeing portability over binary size winning all around these days.
It does? I would rather argue that portability between desktop OS matters today less than twenty years ago as the niches are carved out, WSL 2 becomes actually usable and the desktop metaphor as a whole declines.
You need to upgrade to zsh 5.9, or backport the patch I sent them two years ago: https://github.com/zsh-users/zsh/commit/326d9c203b3980c0f841... If you can't upgrade zsh, then the workaround is to say `sh -c ./ape-program` or `bash -c ./ape-program` instead of `./ape-program`.
Its not immediately clear what this is. The quick description is completely off on another part of the website on another webpage. TLDR: "Cosmopolitan" makes C a build-once run-anywhere language. So here's your very easy tip of the day: Describe what your thing does on the very same webpage you announce it. Very easy to do, but not done nearly enough.
> Cosmopolitan Libc makes C a build-once run-anywhere language, like Java, except it doesn't need an interpreter or virtual machine.
While anyone familiar probably finds these comments "stupid", just some helpful advice to the author - if it matters to you, there are people discovering this for the first time who might not realize what "it" is until you tell them!
>it starts with the assumption you know what it is.
That's the gripe! It's all context! Here it is with SUNSHINE 3.0.1:
After nearly one year of development, I'm pleased to announce our version 3.0.1 release of Sunshine. The project is an entirely new day. For starters, Apple sponsored our work as part of their FLOWER program. Google also awarded me an open source peer bonus for my work on Sunshine, which is a rare honor, and it's nice to see our project listed up there among the greats, e.g. OPEN, QUIT, etc. In terms of this release, we're living up to the great expectations you've all held for this project in a number of ways. The first is we invented a new widget that lets you grow large dirt which...
An announcement on someone's project web site is not targeted at the random folks on Hacker News, or even random folks in general. They know their audience, and folks showing up from random places should do at least a little bit of work to figure out the context and surrounding pages.
If you've never read their blog or announcements before, I don't know why you would expect them to cater to you.
HN's headline policy makes it especially hard here, because the submitter can't provide context.
I'm amused by the fact that even authors of the most technically brilliant projects in recent memory also struggle with CSS, just like us mere mortals. :)
This behavior really should have been the default in mobile browsers. It's not like emulating a desktop viewport actually makes giant tables usable on a tiny mobile screen so it would have been better to prefer not breaking pages that can reflow for a mostly useless hack.
I don't know, I think pinch-to-zoom + pan is a pretty decent way of dealing with pages that have more complex layouts than basic document, but were designed using e.g. tables for layout. Given that most non-trivial pages would have been laid out that way back when mobile browsers were first coming out, it seems like a reasonable tradeoff to me.
That is to say, it's definitely a hack but I wouldn't call it useless, at least originally. These days it's a lot less useful since the number of pages that do benefit from this treatment has decreased dramatically. But at this point the die has been cast.
The trick could definitely work with rust since fundamentally it's "just" a hack on how the various scripts work on different systems. Actually getting the rust compiler to produce cosmopolitan binaries would likely be a heavy lift though.
Also it says it supports WASM (wasi?) so some applications might work out of the box with that.
My above repo contains example with the Rust standard library that build as fat executables with Cosmopolitan Libc.
I also got ripgrep to build https://github.com/ahgamut/ripgrep/tree/cosmopolitan, but it wasn't part of the cosmocc binaries because some crates that are part of the build require `#!feature(rustc_private)]` to be added to their source code. Same goes for bat and fd.
To summarize, Rust CLI tools can be built with Cosmopolitan Libc, but to build them like we can build gcc/emacs/git right now, we will need some support and Rust expertise.
Last time I looked into Rust-on-Cosmopolitan, I couldn't make it work as Cosmopolitan determined syscall numbers, signal numbers, and such at runtime, but Rust standard library assumes compile-time constants (basically the same issue that C switch-case has). How did you get around that? Have you tested these binaries on non-Linux platforms?
We have about ~700 test executables and two programs called runit/runitd which remote execute them across our entire test fleet each time we run `make test`. Currently, the fleet consists of `freebsd rhel7 xnu win10 openbsd netbsd pi silicon`. We used to have rhel5 and win7 in there too, but I've been slacking off the past few months. You can watch a video of how running all the test executables on all the systems only takes about fifteen seconds. https://justine.lol/sizetricks/#why
While I have no experience building ruby, if standard ruby gives you trouble - might be worth to try mruby - it is likely easier to build and debug the build process.
Counterintuitively, having messed around with building mruby for a project a few months ago, I found it harder to deal with. It's a lot more hardcore, with vastly fewer resources and more sharp edges, and is orders of magnitude less popular, so you find yourself hitting basic problems you would think would have been solved years ago.
I'd stay away from it unless you have a very pressing need.
It says arm64 linux support, I will have to try this on a raspberry pi. It’s kind of amazing and magical that this person pulled it off. We need a MacArther genius award for software. And this should be the first award.
Every time I see an update from Justine I get so excited. It's like watching the future of computing unfold in real time. It makes me wish we could send them back in time - all of the pieces to make this work have been in place for a long long time but nobody connected all the dots. The funniest part of this post are the instructions to integrate it with autoconf. All of that autotools nonsense wouldn't have had to exist if this had been around!
This is great and all but it’s fundamentally a toy. There are a number of tradeoffs involved here, all so that the same binary runs on multiple operating systems, which isn’t actually very useful. If your program isn’t vaguely portable to begin with, it still won’t work.
Can you elaborate? I’m not sure I follow your argument. A requirement to write portable C doesn’t seem so insurmountable to render the project a mere toy.
The suite of useful tools included in the post seems like a good counter example to the claim that this is inherently not useful for anything serious.
Fat multi-arch binaries are a thing on other platforms like darwin, where they are used extremely widely. What makes this approach so different?
I don't understand what's useful here either. It's not inherently useful to have my `ls` on Mac be the same one as chromeOS, I'm happy with whatever is on either.
If this means I can FFI link against one ONNX library instead of one for linux64, Linux ARM, macOS arm, macOS Intel, android, iOS, win x64, win ARM, I'm all for it though.
Multi-arch seems completely different than multi-platform. The former is obviously useful, the user isn't necessarily going to understand why a program which ran on their MacBook isn't runnable on their older iMac because it's ARM only. The two programs can also still use highly specific OS integrations, GPU acceleration APIs, and make assumptions about being a macOS system. The stretch to multi-platform comes at a much higher cost in limitations for a much more dubious level of gain, as badass as it is from a technical perspective. When I say "cost" e.g. on Windows I have to rename the executable to end in .exe be able to launch it, when I do simple text based programs like nano do run... but they are completely unusable. Bash runs but I can't select, copy, or paste text with the mouse. It's borderline unusable if the app does more than behind the scenes processing only.
With that in mind, "plugins" to cross platform applications instead of standalone apps could be an interesting use case though. That's something which has typically went towards per platform, interpreted/jited, or VM'd solutions - all of which have their downsides for a typical user, don't really care about the rest of the system as much, and don't need to be anything but "behind the scenes processing" in most cases.
This is true, but given that many applications are built using web tech now, this stack is sufficient to fire up a server and make an app available on localhost. I can see a lot of use cases for that, and it's something that wasn't there in UNIX before X Windows. I'd use this for my personal projects that provide a web interface, since I can build once and sync (using Syncthing) the actual binaries between my Android tablet, my Macbook, and my Intel laptop. Niche use case, but very neat!
> all so that the same binary runs on multiple operating systems, which isn’t actually very useful.
I like to mention my use case when this comes up: my log file viewer (https://lnav.org) uploads an agent to remote hosts in order to tail log files on that host[1]. While lnav itself is not built using cosmo, the agent is. So, it works on multiple OSs without having to compile and include multiple versions of the agent.
Man oh man, how come I didn't find this tool 6 months ago? I think you need more topics/tags on the github repo :-D
Extremely cool, I will definitely check out lnav when I get a chance. I've been battling with the big players for a few months now and their systems are just so overengineered and complex for my needs that it's silly.
I just need tail -f for 10-ish servers and desktops.
I haven't even read the project readme, but I presume lnav is exactly what I wanted. Excellent!
I just wrote a similar thing. A simple CLI that posts alerts and heartbeats to Alerta. I used Go mainly for the same reason. (But I also couldn't write it in C or C++ :D)
Definitely exciting. Portability of binaries is such a problem these days with all the angst around ABI compatibility in the Linux kernel and the push for containerization (e.g. lots of distros going towards Snap/AppImage). Justine's work seems like it's working towards a research idea from Alan Kay about developing a kind of "Model T" library that provides a solid core for all computing [0].
I'm also kind of jealous. Like most of us I work on big systems with millions of lines of spaghetti code. I think that building very small, reliable tools like Justine's would be much more impactful work.
This is a neat trick and clever technical work, but is it useful in practical terms?
Like, wouldn't you just download the binary that's been compiled specifically for the platform and architecture that you're using? Rather than relying on a potentially quite fragile method of cross-platform execution.
In a way it kind of reminds me of Urbit. Very clever, very cool, but also very niche and more of a hobbyist showcase project than anything else. Not that there's anything wrong with that of course.
Write once, run anywhere has been a slogan for coming up on thirty years. Except all implementations of it have acceded to reality in one or more important aspects, such as needing to install Java separately. And it's not just platform-specific compilation, it's everything that could support platform-specific compilation (if you've never tried to cross-compile from Linux to MSVC, you should), and also all sorts of platform-specific code (like console functions vs terminal sequences, or even stuff as banal as $HOME vs $USERPROFILE). Cosmopolitan still isn't perfect, because it doesn't emulate all of Linux, so you still need kernel32.dll here and there. But it is still the best of any attempts.
I agree. You sound like you're speaking from experience. If so, I'd love to hear what sort of stuff you're building with Cosmo, if you're able to share! Feel free to reach out anytime (privately or discord) and let me know what the project can be doing to better serve your needs.
For the consumer it's a simple switch(arch) statement to download the right binary.
But for the developer, it means setting up 9 different build pipelines and artifacts (and realistically, most won't bother with BSD builds and a lot still don't bother with arm64 builds).
It's not necessarily a huge hurdle or an unbearable expense with modern CI services, but it's still a massive deal that this project can make it all unnecessary for every single C/C++ developer out there. If this were a paid product, literally millions of companies would be happy to pay a small fee to save on CI costs, time and maintenance.
Does this really change if Cosmopolitan e.g. outputs 9 different artifacts instead of 1 artifact merging all 9? The advantage you're describing seems to lie mostly in "a C/C++ build system which can actually cross compile without pulling your hair out" not "a C/C++ build system which produces a binary I can take from BSD to Windows and execute unmodified".
It's because the former is much easier/better if you don't also do the latter. The harder thing gives you the easier thing as a side effect, yes, but you could just do the easier thing directly and not do the harder thing at all. Zig's "zig cc" command is an example of a system that gives you the former without doing the latter. If you ONLY care about simplifying your CI for cross-compilation builds, take a look at Zig as your C/C++ compiler frontend.
It’s a very cool toy and fun personal project, but it’s not much more even though the author really wants it to be. Your code has to be vaguely portable anyway for this to work. So why would you pay the tradeoffs for a binary that runs in multiple operating systems, which is not that useful.
I noticed a similar comment from you in the same thread. If you don't write portable software, it doesn't mean the world isn't writing portable software in C, C++, Rust, etc. To list a very few ones:
Blender, GIMP, Emacs, Vim, Pidgin, Evince, Firefox, gEdit, Inkscape, Krita, FFmpeg, Python, Perl, ... I could go on and on.
> You can write portable software… and then compile it for each platform to get the best performance and functionality.
Perhaps not what you intended, but I believe this is that exactly what Cosmopolitan is doing:
- They are writing portable software in that it can run on various architectures and operating systems
- They compile it for each platform, even if the output is a single binary
- For the best performance and functionality, they mention several examples of how Cosmopolitan outperforms the native alternatives
I'm sure there are plenty of rebuttals ("Emacs on Windows is a port", "Cygwin isn't portable", "they could make the native version of $WHATEVER more performant", "Cosmopolitan isn't always faster", etc.), all of which are well and good, but would be missing the bigger picture, which is that there are reasons for both approaches (among others!) to exist, an idea that far transcends software.
Author here. I invented a novel polyglot executable format that makes developers lives easier, and we're helping the AV industry feel comfortable with that through openness and transparency. Every time I ship a release, I make an effort to upload all the executables to Microsoft Security Intelligence to give them a heads up and let them know that I wrote them (since there's currently no vendor neutral solution for code signing). If you build APE binaries, then you should do that too: https://www.microsoft.com/en-us/wdsi/filesubmission?persona=... Every time I submit the form, Microsoft whitelists them with zero hassle. They even let you upload a single zip file containing hundreds of executables, and they'll take care of them all. It's great. Doing that ensures Windows Defender won't cause issues. The good news is most other AVs are plugged into the same database as Defender (even Google Search bases their analysis on Microsoft's security intelligence) so that form actually gets you off the radar of a lot of AVs. As for CrowdStrike, if you have contacts there, then I'd be happy to share with them information about what our team is building and shipping, as well as documentation on the APE file format, in addition to free consultation from me for any help they need supporting it on their end. My email is in the blog post.
- Additional Information (example): I'm the author of Redbean, an open source web server https://redbean.dev
It uses a polyglot executable format called APE which I designed. My
project has received positive coverage in the media:
https://www.theregister.com/2022/06/20/redbean_2_a_singlefil... Sadly
we're having trouble with AVs. Could you unflag my release
binaries? Thanks!
Administrators can create exclusions in Crowdstrike. Given the question I'm assuming you don't have admin rights and you should definitely not try to avoid company policy, that is a fantastic way to get canned
Perhaps, by the same authors, redbean, which "embeds Lua, SQLite, and MbedTLS into a fork() driven application server" ... " a great fit for when you want to build an app that's vertically integrated into a single tiny file that runs on nearly all PCs and servers". It looks like as of now, greenbean exists as well.
I second this. I'm a Java dev and so have been porting Spring Petclinic to redbean using fullmoon which is a Lua framework built on top of redbean by Paul Kulchenko (who also is the author of ZeroBrane studio - a nice lightweight Lua ide which I have been using).
So far it's been a lovely experience and Paul is super responsive. Redbean is massively faster at startup so I can build/bounce to do hot reload in real time basically where the spring app takes about 6 seconds to start up.
Generally speaking (I've not tested this kind of setup with the cosmopolitan libc) what I've done in the past with C is use something like libmicrohttpd along with some web assets linked into the executable (`xxd -i` can help you with the assets). That gives you a single (small) binary where you can use HTML/CSS/JS for the main GUI and logic.
You can then integrate additional libraries as you please, such as sqlite3 to give yourself fast, local database access over an endpoint on the embedded HTTP/S/2 (or websocket) server.
Docker actually solved this quite a while ago with tags and downloads of the correct architecture container. But this is interesting even though it won't scale well.
POSIX / SUS / the Open Group Base Specifications have issues (pun not intended, but I’ll take it), and then those issues have editions. The last one of those is from 2018[1], being a revision of (indeed) the 2008 issue. (I remember Landley being more than a little acidic about this versioning scheme.)
I still have no idea what the quote is referring to, though, and given Justine’s slightly (deliberately?) unhinged manner of writing, I’d give even odds the change is in fact from 2001 or something like that.
This looks to be the one, thank you! Doesn’t look to have gotten into the current version [the sh(1) page in the version I linked still refers to text files]. (The bug is also tagged tc3-2008, when the last corrigendum released is TC2, and the change was marked applied in 2019. So it makes sense it hasn’t found its way into a release yet.)
Trying to run Cosmos apps from the Windows Terminal opens a pop-up saying "Select an app to open '<app>'". How can I execute them?
I ended up finding a solution:
> If you want to run them on Windows, then you simply need to rename the file so that it has the .com suffix. Better yet, consider making that a symlink (a.k.a. reparse point).
What I like to do is configure Windows Terminal Preview so it launches `C:\bin\bash -l` as my command prompt. Once you're inside bash, it doesn't care about the .com or .exe suffix being there. Only CMD.EXE really cares about the suffix. So you have to simply rename the files if you want to run it there.
Just kidding, I’ve played around with some of the stuff @jart and other contributors have created and it’s mind blowing. Well done and keep up the good work.
> However portability isn't the only selling point. Cosmo Libc will make your software faster and use less memory too.
With that in mind, is there a "slim binary" mode that lets me only export the code to run the binaries on my system, so that I can reap these benefits for personal use without added "bloat" for a feature that I won't need? (where "bloat" is contextual, with the current context being "not actually planning to make use of portability")
Author here. We've got you covered. Search for `MODE=tinylinux` in the https://github.com/jart/cosmopolitan#getting-started section of the README. If you use that build mode, then hello world for x86 linux is only 8kb in size. It's very similar to what you'd expect from Musl Libc. All the Windows / BSD / Mac / BIOS stuff gets removed from the compilation.
That predefined mode is actually a friendly wrapper around a more generalized platform support system Cosmopolitan offers, which is called `-DSUPPORT_VECTOR` where you can define a bitset of specifically what platforms you want to be supported. Then dead code elimination takes care of the rest. The same concept also generally applies to microarchitecture support, where you can have as much or as little runtime dispatching as you want.
Would you consider this a competitive replacement of Busybox? Curious if you've compared, since they also take liberty in cutting out uncommon functionality.
I think you can subset supported systems, like you could only compile for x86_64 ELF systems (aka Linux and *BSD) and have the shim be much smaller; presumably a subset of one is also acceptable. I don’t know how (or if) you can do this with the new build environment, though.
As awesome as these are, they're not really portable executables if you can't set their setuid bits and expect them to run as root like with normal executables, right?
There's a program that's part of cosmos called `assimilate` which can turn any APE binary into a platform-specific binary.
jart@nightmare:~$ /opt/cosmos/bin/assimilate --help
assimilate: illegal option -- -
actually portable executable assimilate v1.6
copyright 2023 justine alexandra roberts tunney
usage: assimilate [-xapembfchv] [-o PATH] FILE...
-h show help
-v show version
-f ignore soft errors
-b don't remove freebsd from elf os/abi
-c clobber input path w/o making backup
-e convert to elf regardless of host os
-m convert to macho regardless of host os
-x convert to amd64 regardless of host cpu
-a convert to arm64 regardless of host cpu
-p convert to ppc64 regardless of host cpu
-o PATH write modified binary to different file
If you aren't using binfmt_misc then you can also pass the `--assimilate` flag to your APE binary, to turn it into a native executable, without having to use the tool. It's baked into the shell script. Just use the `less` command on any APE file and read the shell script.
Once assimilated, you're free to turn it into a setuid binary.
We also have patches in flight for the Linux Kernel as well as BSDs, to make APE native. https://justine.lol/ape.patch
Wow, that’s some combination of awesome and horrifying.
Is there an actual written spec somewhere describing how this works? What happens if the APE embeds an ELF header and something else? Or multiple ELF headers?
ISTM if this thing goes in the Linux kernel (and maybe a BSD kernel and maybe a Windows kernel, yeah right), it should at least be written down cleanly. It doesn’t necessarily need to be a PDF. (Linux can load ELF files. ELF has a spec or five that are only mostly horrible, and I’m not actually aware of a unified ELF spec that covers everything, but this isn’t really a showstopper.)
Off the top of my head, it seems like it would be nice for whatever bit of the shell-compatible header encodes an ELF header to also indicate that it’s ELF (as opposed to something else) and maybe even that it’s Linux-flavored ELF. Maybe like:
#ELF-Linux-LE
print…
#ELF-BSD-LE
print…
#ELF-U-boot-BE
print…
This isn’t intended to be a real proposal. Little- and big-endian in the same binary would be even more amusing than the average APE binary, and I don’t remember off the top of my head exactly which properties of the target can be unambiguously determined from the binary encoding of the ELF header.
(And obviously there would be some shell-flavored conditions in the middle.)
244 comments
[ 3.1 ms ] story [ 249 ms ] thread> It actually goes 2x faster than the native WIN32 port that the Emacs authors wrote on their own. Cosmo Emacs loads my dotfiles in 1.2 seconds whereas GNU Emacs on Windows loads them in 2.3 seconds.
Impressive stuff.
But we should keep in mind that this project is what POSIX should have been, this is a big patch to make things right, as they should have been more than 20 years ago.
It seems magical because of the failure of numerous other teams and people who never managed to tackle the portability issue with the right mindset and skills.
I must be missing something. How are you getting from "just implement POSIX interfaces" to "compile once run everywhere"?
Wouldn't the former just promise that you could compile the same source on any POSIX-compliant OSs and get a binary that runs on that OS, on that architecture?
POSIX was not limited to the Unix world, the goal was for it to be implemented by all OS vendors, and it was partially done.
Improvement doesn't come from passiveness. Someone, somewhere, will have to start first.
Most new development in tech, including software, have some dependencies on something that was not available before.
Since you write "Most" there seem to be fewer 'new developments' which do not follow this pattern. So all you really say, is that rare new developments, which do not depend some other innovation, enable many followup innovations.
After all, your argument is not in conflict with the previous argument. You say, that new developments (aka implementations) have dependencies that have to be available before they can be made a reality, while the previous post just said, that long before something can be implemented, someone had imagined/dreamt about it already.
Other than bash itself, does it mean it can be used to make whole set of GNU tools cross platform?
Even though Windows 10 already has Terminal and I was getting
I downloaded Terminal Preview which still throws the same error. Is Terminal or Terminal Preview the only way to run bash? There might be a way to configure cmder to use bash in a similar way you suggested for Terminal. Don't know how yet.https://github.com/jart/cosmopolitan/releases/download/3.0.1... is 213MB file which contains "fat binaries" (single binaries that execute on a bewildering array of hardware platforms and operating systems) for dozens of programs, including zip, curl, git, wget, python, ctags and even my own Datasette Python application!
It's absolutely wild that this works.
I just tried it out (on macOS). I downloaded and extracted that zip and did this:
It refused the first time because of macOS security settings. I had to open the security panel and click "allow"... and then it worked!Likewise, this worked:
That started a https://datasette.io/ server running on port 8000.Git works too:
That git binary is 6.3MB, and I believe that same exact file can be copied to a Linux or Windows machine and will work the same way.1: https://justine.lol/ape.html
Also, to add new pure-python packages, you just need to unzip them into a local folder "./Lib", and add that folder to the APE.
The bigger challenge would be LLM with plugins. Those add all sorts of extra dependencies to help LLM run models directly - PyTorch, Transformers, llama-cpp-python etc.
I'd be surprised to see "llm install llm-gpt4all" work for example, since that pulls in compiled Python wheels and I'm not sure it would know which architecture to use.
pip install DOES work:
That ~/.local/lib/python3.11/ directory didn't exist until I ran the ./python -m pip install command.Unfortunately "./python -m pip install llm" didn't quite work, I got this:
pip install requires modifying the APE, so I end up installing pure-Python libraries as follows:
Installing CPython extensions like this is an unsolved problem, but I think there might be some interesting workarounds possible.https://github.com/jart/cosmopolitan/tree/master/third_party...
and
https://github.com/trholding/llama2.c
should also allow anything to run without opening settings
According to the article, Cosmo's fat binary dash was 30% larger but ran faster and used less real memory than Alpine's x86-linux-only version.
However there is still probably a 30% overhead for storage and copying.
It does? I would rather argue that portability between desktop OS matters today less than twenty years ago as the niches are carved out, WSL 2 becomes actually usable and the desktop metaphor as a whole declines.
Kinda feels like they are super intelligent alien beings from another planet trying to save us from software bloat and fragmentation.
> POSIX even changed their rules about binary in shell scripts specifically to let us do it.
I don't know what to say.
The first sub-title headline tells you, but it isn't clear to someone new if this is "one of the features of something" or "the thing."
> Build Once Anywhere, Run Anywhere C/C++
I clicked to the home page and then to here: https://justine.lol/cosmopolitan/
Then I understood!
> Cosmopolitan Libc makes C a build-once run-anywhere language, like Java, except it doesn't need an interpreter or virtual machine.
While anyone familiar probably finds these comments "stupid", just some helpful advice to the author - if it matters to you, there are people discovering this for the first time who might not realize what "it" is until you tell them!
That's the gripe! It's all context! Here it is with SUNSHINE 3.0.1:
If you've never read their blog or announcements before, I don't know why you would expect them to cater to you.
HN's headline policy makes it especially hard here, because the submitter can't provide context.
Its odd to think someone should not expect new user interest when they've made a new thing. Announcements are for new users and old users alike.
- a compiler outputting a portable executable
- POSIX shims for multiple platforms that get statically linked to resulting binary
I'm not sure why it compares itself to Java, the closest thing would be Cygwin/MinGW.
https://i.ibb.co/v4s0Xpj/IMG-1221.png
Love your work! <3
That is to say, it's definitely a hack but I wouldn't call it useless, at least originally. These days it's a lot less useful since the number of pages that do benefit from this treatment has decreased dramatically. But at this point the die has been cast.
Also it says it supports WASM (wasi?) so some applications might work out of the box with that.
My above repo contains example with the Rust standard library that build as fat executables with Cosmopolitan Libc.
I also got ripgrep to build https://github.com/ahgamut/ripgrep/tree/cosmopolitan, but it wasn't part of the cosmocc binaries because some crates that are part of the build require `#!feature(rustc_private)]` to be added to their source code. Same goes for bat and fd.
To summarize, Rust CLI tools can be built with Cosmopolitan Libc, but to build them like we can build gcc/emacs/git right now, we will need some support and Rust expertise.
I'd stay away from it unless you have a very pressing need.
The suite of useful tools included in the post seems like a good counter example to the claim that this is inherently not useful for anything serious.
Fat multi-arch binaries are a thing on other platforms like darwin, where they are used extremely widely. What makes this approach so different?
If this means I can FFI link against one ONNX library instead of one for linux64, Linux ARM, macOS arm, macOS Intel, android, iOS, win x64, win ARM, I'm all for it though.
With that in mind, "plugins" to cross platform applications instead of standalone apps could be an interesting use case though. That's something which has typically went towards per platform, interpreted/jited, or VM'd solutions - all of which have their downsides for a typical user, don't really care about the rest of the system as much, and don't need to be anything but "behind the scenes processing" in most cases.
Sure if one wants to live in the world of UNIX before X Windows, I guess it is ok.
I like to mention my use case when this comes up: my log file viewer (https://lnav.org) uploads an agent to remote hosts in order to tail log files on that host[1]. While lnav itself is not built using cosmo, the agent is. So, it works on multiple OSs without having to compile and include multiple versions of the agent.
[1] - https://lnav.org/2021/05/03/tailing-remote-files.html
Extremely cool, I will definitely check out lnav when I get a chance. I've been battling with the big players for a few months now and their systems are just so overengineered and complex for my needs that it's silly.
I just need tail -f for 10-ish servers and desktops.
I haven't even read the project readme, but I presume lnav is exactly what I wanted. Excellent!
That even explains part of their success: nobody pays attention to toys, and once they become ubiquitous it's too late to fight them.
I'm also kind of jealous. Like most of us I work on big systems with millions of lines of spaghetti code. I think that building very small, reliable tools like Justine's would be much more impactful work.
[0] https://web.archive.org/web/20070625105727/http://www.intel-...
Like, wouldn't you just download the binary that's been compiled specifically for the platform and architecture that you're using? Rather than relying on a potentially quite fragile method of cross-platform execution.
In a way it kind of reminds me of Urbit. Very clever, very cool, but also very niche and more of a hobbyist showcase project than anything else. Not that there's anything wrong with that of course.
But for the developer, it means setting up 9 different build pipelines and artifacts (and realistically, most won't bother with BSD builds and a lot still don't bother with arm64 builds).
It's not necessarily a huge hurdle or an unbearable expense with modern CI services, but it's still a massive deal that this project can make it all unnecessary for every single C/C++ developer out there. If this were a paid product, literally millions of companies would be happy to pay a small fee to save on CI costs, time and maintenance.
EDIT: not sure what is controversial about this statement. I'm not saying it's the only solution, but it does qualify.
Blender, GIMP, Emacs, Vim, Pidgin, Evince, Firefox, gEdit, Inkscape, Krita, FFmpeg, Python, Perl, ... I could go on and on.
Perhaps not what you intended, but I believe this is that exactly what Cosmopolitan is doing: - They are writing portable software in that it can run on various architectures and operating systems - They compile it for each platform, even if the output is a single binary - For the best performance and functionality, they mention several examples of how Cosmopolitan outperforms the native alternatives
I'm sure there are plenty of rebuttals ("Emacs on Windows is a port", "Cygwin isn't portable", "they could make the native version of $WHATEVER more performant", "Cosmopolitan isn't always faster", etc.), all of which are well and good, but would be missing the bigger picture, which is that there are reasons for both approaches (among others!) to exist, an idea that far transcends software.
- Company Name: Justine Tunney
- Incorrectly detected as malware/malicious
- Detection Name: Trojan:Win32/Wacatac.B!ml
- Additional Information (example): I'm the author of Redbean, an open source web server https://redbean.dev It uses a polyglot executable format called APE which I designed. My project has received positive coverage in the media: https://www.theregister.com/2022/06/20/redbean_2_a_singlefil... Sadly we're having trouble with AVs. Could you unflag my release binaries? Thanks!
(say, Qt WebAssembly? ...something else?)
Or is there a even better route to run-anywhere Cosmopolitan apps with a GUI?
https://github.com/pkulchenko/fullmoon
So far it's been a lovely experience and Paul is super responsive. Redbean is massively faster at startup so I can build/bounce to do hot reload in real time basically where the spring app takes about 6 seconds to start up.
You can then integrate additional libraries as you please, such as sqlite3 to give yourself fast, local database access over an endpoint on the embedded HTTP/S/2 (or websocket) server.
Qt was doing their own thing for a while but scrubbed it, I think...
Something something Flutter Web?
Why not?
What does this refer to?
The latest POSIX standard was released 2007. [1]
1: https://standards.ieee.org/ieee/1003.1/7101/
I still have no idea what the quote is referring to, though, and given Justine’s slightly (deliberately?) unhinged manner of writing, I’d give even odds the change is in fact from 2001 or something like that.
[1] https://pubs.opengroup.org/onlinepubs/9699919799.2018edition...
I'm not sure whether the proposed changes have actually made it into a published edition of the specification.
https://austingroupbugs.net/view.php?id=1250
I ended up finding a solution:
> If you want to run them on Windows, then you simply need to rename the file so that it has the .com suffix. Better yet, consider making that a symlink (a.k.a. reparse point).
Just kidding, I’ve played around with some of the stuff @jart and other contributors have created and it’s mind blowing. Well done and keep up the good work.
> In the Cosmos, every program is statically linked and contains a PKZIP central directory where its /usr/share dependencies are embedded.
Sounds really neat, even the data and configuration files are linked into the executable. Can't wait to see what else you'll come up with.
With that in mind, is there a "slim binary" mode that lets me only export the code to run the binaries on my system, so that I can reap these benefits for personal use without added "bloat" for a feature that I won't need? (where "bloat" is contextual, with the current context being "not actually planning to make use of portability")
That predefined mode is actually a friendly wrapper around a more generalized platform support system Cosmopolitan offers, which is called `-DSUPPORT_VECTOR` where you can define a bitset of specifically what platforms you want to be supported. Then dead code elimination takes care of the rest. The same concept also generally applies to microarchitecture support, where you can have as much or as little runtime dispatching as you want.
Once assimilated, you're free to turn it into a setuid binary.
We also have patches in flight for the Linux Kernel as well as BSDs, to make APE native. https://justine.lol/ape.patch
Is there an actual written spec somewhere describing how this works? What happens if the APE embeds an ELF header and something else? Or multiple ELF headers?
ISTM if this thing goes in the Linux kernel (and maybe a BSD kernel and maybe a Windows kernel, yeah right), it should at least be written down cleanly. It doesn’t necessarily need to be a PDF. (Linux can load ELF files. ELF has a spec or five that are only mostly horrible, and I’m not actually aware of a unified ELF spec that covers everything, but this isn’t really a showstopper.)
Off the top of my head, it seems like it would be nice for whatever bit of the shell-compatible header encodes an ELF header to also indicate that it’s ELF (as opposed to something else) and maybe even that it’s Linux-flavored ELF. Maybe like:
#ELF-Linux-LE print…
#ELF-BSD-LE print…
#ELF-U-boot-BE print…
This isn’t intended to be a real proposal. Little- and big-endian in the same binary would be even more amusing than the average APE binary, and I don’t remember off the top of my head exactly which properties of the target can be unambiguously determined from the binary encoding of the ELF header.
(And obviously there would be some shell-flavored conditions in the middle.)