cosmo | ||
cosmo-kuroko | ||
cosmo-muon | ||
cosmo-perl | ||
cosmo-yices | ||
notwa-util | ||
.gitignore | ||
auto-update | ||
build-all | ||
install-cosmo | ||
README.md | ||
TODO.md |
stargazing
this repository contains experiments in building third-party software against cosmopolitan libc. the provided scripts produce APEs (Actually Portable Executables) that run on Linux, Mac, Windows, FreeBSD, OpenBSD, and NetBSD. however, despite running on all platforms, not every feature is available on every platform. cosmopolitan already does a tremendous job at polyfilling missing features across platforms, but pre-existing software still takes a lot of patching before becoming fully functional.
building
on most Linux distros with podman properly installed and configured,
it should suffice to run ./build-all
in the root of the repository.
binaries are copied to the out/
directory upon success.
installing
no installation is necessary — everything in the out/
directory is self-contained.
however, if you'd like to use create
your own pseudo-release of cosmopolitan to build against,
you can run install-cosmo
to install an amalgamation to /opt/cosmopolitan/
.
this includes the amalgamation (in dist/
),
the gcc toolchain (in gcc/
),
some essential APEs (in bin/
),
and all the necessary headers.
notes
Docker
this project uses Dockerfiles to allow for mostly-reproducible builds. podman is used instead of docker, because the official docker software is commercial and obnoxious.
neither docker nor podman is required for executing the binaries. binaries are to be isolated and extracted from the resulting containers. those binaries can then be transferred across platforms, like any other APE.
in the future, it would be nice to use something like what Void Linux does for its packages, which would entirely sidestep the clunkiness of Dockerfiles and working with containers.
make no mistake, this project does not strive for reproducible builds in any way that nix does.
Host OS
this project must be built on a host running Linux. if you are not running Linux, use a VM of some sort. i personally use VirtualBox running Alpine Linux. i have not tried building with WSL2.
Code Style
this project encourages a heretical and horrifying style of code
for its shell scripts. the intent is to chain &&
s while facilitating
trivial re-ordering of lines. for instance, a RUN
command in a Dockerfile
(which just executes a line of shell) might look like this:
RUN : \
&& echo hello \
&& note() \
{ : \
&& printf '\033[1m%s\033[m: %s\n' >&2 \
noted "$*" \
;} \
# this is an inline comment! it should end with a semicolon, \
# because vim's syntax highlighting is bad. \
&& note '\\( o _ o )//' \
;
a good example of a script in this style is
the acquire
script.
gratuitous explanation
-
4-space indentation is a must, since at least three characters are needed to contain the operators on the left of each line.
-
:
is akin to thetrue
command; it's used as a no-op that only sets the most recent exit code ($?
) to0
. -
\
continues the shell command to the next line; the proceeding newline is removed and ignored. -
&&
is a short-circuiting operator that only evaluates its right-hand side when$?
is0
.&&
is preferred over a simple semicolon because most programs use a non-zero exit code to indicate that an error occurred, whereas;
will continue executing code, even in the presence of an error. note: thediff
command breaks the convention and uses both0
and1
as normal exit codes. -
||
is like&&
but only executes when$?
is not0
. important:||
has a lower precedence than&&
! make sure to wrap your||
s in braces unless you want to capture everything before it. for example, an excerpt of a shell script might look like this:
&& { test -e myfile || touch myfile ;} \
-
leftmost
&&
s and||
s are always centered within their 4-space indent. -
avoid using pipes (
|
) when possible, because only the exit code of the final command in any pipe is respected. instead, write intermediate data to/tmp
when possible. remember to mount/tmp
as atmpfs
at the start of theRUN
command! -
functions are declared (
()
) on their own line without any braces or other commands. -
{ :
is used to begin a multi-line block, similar to howRUN :
begins a shell command. sadly, the space between the brace and the colon is not optional. -
;}
is used to finish a multi-line block. this is aligned with the preceeding&&
and||
operators. thankfully, the space between;
and}
is optional. -
a final
;
is used to finish off the line-continutation. this means that every line before it can end with a\
, which simplifies editing. when podman gives you strange errors, double-check that you aren't forgetting a\
or the final semicolon. -
redirections are usually specified before a final list of arguments. this makes skimming code easier when arguments extend across many lines.
-
TODO: explain
if cmd \ ;then : \ && cmd \ ;fi
. -
TODO: explain
for cmd \ ;do : \ && cmd \ ;done
. -
TODO: explain
while cmd \ ;do : \ && cmd \ ;done
. -
TODO: explain
test
s? -
TODO: explain the two different kinds of commends.