PUISNE: Portable UnINtruSive Executor
A tool to package an executable & its resources quickly and easily. Think MacOS Application Bundles that work anywhere, even across operating systems! They’re exceedingly simple to work with and to share.
It’s mostly intended for research teams who frequently collaborate using custom programs with code and/or data dependencies. Packaging all that into a single file allows rapid iteration & collaboration, with barely any technical overhead. You’re more likely to use it for something in ~/some/random/project
than /bin/
or ~/.local
(although the latter is indeed reasonable).
PUISNE is…
It’s basically a glorified self-extracting zip archive. That’s the key to its ease-of-use: creating one doesn’t need any specialized software; just use Info-ZIP or what-have-you. Add your application directory to an empty PUISNE & ship it off.
When the package is run, it extracts the contents, then exec
s the main executable – with all the resources already in-place & as though you had done so directly. Furthermore, caching is available to prevent re-extracting unnecessarily (see the -u
option); by default it only replaces out-of-date files.
Run an empty PUISNE for detailed usage instructions.
PUISNE needs a truly zip-compliant archiver. Info-zip is the most thoroughly tested most & works seamlessly; it’s basically the standard available & everywhere. Examples in the help text use that. NB to maintain Windows compatibility using zip
’s -g
flag is recommended. If you ever forget your package will still work in *nix, but to recover Windows functionality, re-make your package by extracting its contents and adding them to a fresh, empty PUISNE.
Since “simple” is the whole point & to avoid scaring-off the CLI disinclined, it would be nice to support GUI-based zip utilities. Admit it: you love drag-and-drop. Unfortunately, not many GUIs tested work – usually because they cut corners. Ah well.
Works-ish
This is a front-end for Info-ZIP. It’s only available for Windows, and the UI isn’t really more user friendly than the CLI. That said, it can work; make sure to set the reference directory properly with the “Set Ref” button. I haven’t found how to set the -g
switch, so ironically this won’t build Windows compatible packages. So it goes…
Yes, I actually tested this. It worked well enough but might drop Windows compatibility. Then again, if this is what you’re using, you probably only care about Windows in the first place & in that case you can just make an SFX with WinRar already…
Works to extract content but not to add
To view a package with Windows Explorer, change the file extension to .zip
. Supposedly older versions of Windows might work to modify as well as extract, but I have not confirmed this. Please let me know if you succeed.
Need to specifically open as a .zip
, otherwise it will parse as an ELF. Attempting to modify content yields an error.
Don’t work at all
These seem only able to parse the executable content, not the zip object store. Boo!
Fails altogether.
In Linux it uses a few more tricks to remain out-of-sight. After it extracts its contents to the target directory, it mounts it over or under the working environment.
Mounting over the working environment is more “app-like” – it will “hide away” any modifications to the target directory & preserve the state of the working environment. In contrast, mounting under is “notebook-like” – Not only can it modify the working environment, it “prefers” local files to its own, if any already exist at the specified path.
An example makes this clearer:
For “app-like” behavior, mount over the working environment. The package will still be able to read from the working environment, but will not write to it. This is useful, for example, to keep config or log files out of the way, on a per-app basis. To see any files written, look in the target directory. Furthermore, if there are files in the environment with paths that clash with any in the package, it will ignore those for its own.
Mounting under the working environment is more “notebook-like”. Changes will persist in the working environment. This behavior is in-line with tools like RStudio / Jupyter notebooks, which create outputs like figures in the directory containing the notebook; this means users don’t need to look in eg. a .puisne
subdirectory. Finally, if any files in the environment have the same path as those in the package, those are available; this way, users can more easily provide data on which to operate.
--
to talk to PUISNE.
X
?X
?
X
works for you, use X
! I’ve just seen a lot of times when X
was overkill, or collaborators didn’t know how to use X
, or X
held up scientific progress, or…
git
’s great for developing code, not necessarily running it. People want your program, not your code; this is just that. If you’ve ever made a package you know how much nicer it is for your users, especially considering any make
, install
, or activate
steps you might be able to circumvent.
“Invent the universe? I just want some damn pie.”Carl Sagan--
Dockerfile
with COPY my_puisne.com ...
, or mount it via -v
so you can tweak it without rebuilding, or… Bottom line: do you. But when your team is in the “running laps between the whiteboard & their keyboard” phase, do you really want to slow them down?
zip
sometimes truncates the file; we don’t want it to do that. Try again with the -g
option. hexdump
of the “empty” PUISNE binary, all those zeroes at the end are actually important. The PE header includes a section table that describes how the executable is organized (where each section begins & how large it is). If the file does not match what is contained there, Windows gets real mad. Unfortunately, zip
by default tries to see if it can squeeze in whatever it’s adding in-place & if so, it does so then drops the padding. Therefore adding something small can potentially shrink the archive file; using the “grow” flag, -g
, should avoid this regardless. This should be unnecessary for large additions, since that won’t be “shoved into a gap” & thus should be appended.
BUILD
rules in Bazel. This is just easier & more flexible.
overlayfs
, even on systems that don’t support it. I think I may have worked out a version that basically covers what I want it to. I’d like to improve Windows use, too; bonus if that means finding a compliant GUI that works. Adding support for tar archives could improve compression, I guess (Zip doesn’t compress information redundant across files). I think I have worked out a solution that should take care of those last two, but would potentially change the way packages are made.