So, for a long time I've been a bit frustrated with the state of portable apps on Unix-like systems. You have two options:
- AppImages (Linux-only)
- Tarballs (More portable, but clunky)
I've always dreamed of being able to create 1 binary, that can run on *BSD, Linux and Mac, without having to get separate ones. This led me to a crazy idea, that I would love to share.
The concept is simple, you have a script, that contains an archive, this archive has every binary needed for multiple platforms, and all you have to do is double click it to run it. A simple concept, but a hard problem to solve. Fortunately, after about a month of brainstorming, I think I have it figured out.
The Search for Feasibility
My first attempt was to make a PERL script, since most Unix systems have PERL pre-installed, and if not, it's trivial to acquire it. It worked by using base64 to embed a tarball into the script, and when the script was run, it would extract the tarball into /tmp and then run it. Now this worked pretty well for small programs, however, once you got to about 2gb of data, launching the application this way was slooooooow. I tried many things to speed it up, even created my own very shitty encoding program, but nothing could seem to solve the speed issue. So my eyes wandered over to using FUSE.
This is the approach AppImages take, my first thought was to use
squashfuse. However, I quickly found out it wasn't a very portable solution, and now made sense why AppImages don't work outside of linux.
squashfuse idea was a bust, my next thought was to distribute ext4 images with the script, that could be mounted as read-only use
ext2fs. Unfortunately each UNIX system seems to have it's own way of mounting ext filesystems with FUSE. NetBSD and FreeBSD use
fuse-ext2, Linux uses ext2fs, and OpenBSD flat out doesn't have a FUSE implementation of ext. Well shit, onto the next one.
Next, I looked at the FAT file-systems. First up was
exfat, however due to a bug, it can't be mounted outside of root. Urgh. And not a single system has a packaged
fat32 FUSE implementation (Not that I would use it, because then the size of files would be limited).
At this point, I was losing hope. But then, while browsing the
wip branch of
pkgsrc I found something called
fuse-zip, and it solved literally everything.
- Is it fast enough? ✓
- Can it be mounted without root? ✓
- Is it portable? ✓
- Does it not have restrictions on file size and size of archive? ✓
- Decent compression? ✓
I fiddled with it for a couple days, found it basically treats the zip file like any old file-system. It even works on OpenBSD! Feasibility has been found!
Currently, this is my plan to implement it:
- Test the real-world speed of fuse-zip. From what I could tell, it's decently fast, but this still needs further testing.
- Create a POSIX/PERL script that can not only install fuse-zip if it's needed, but also mount the zip file and then run the program. And once closed, unmount the zip file.
- Make it detect what OS you are on, and load the appropriate libraries and run the appropriate binaries.
Wish me luck!