This repository contains a simple Hello world!
example in the Rust
programming language, that builds with Cosmopolitan Libc. Now it also
includes example snippets scraped from Rust By Example,
and it builds around 175 example programs, including those that use Rust's
std::thread
and std::sync::Arc
.
ripgrep
builds with Cosmopolitan Libc -- check it out here.
To build this repo you need a recent version of gcc
(9 or 10 ought to be
good), a recent version of binutils
(ld.bfd
and objcopy
), and bash
due to a simple filter script.
This includes a custom compilation target for Rust, called
x86_64-unknown-linux-cosmo
, to provide a build process that uses the
Cosmopolitan Libc amalgamation and cargo
.
- Download the Cosmopolitan Libc amalgamation into the
libcosmo
folder:
cd libcosmo
wget https://justine.lol/cosmopolitan/cosmopolitan.zip
unzip cosmopolitan.zip
cd ../
For reference, I used the cosmopolitan.zip
v2.2 from November 7, 2022.
- Download the necessary host toolchain and source code for Rust:
# Download Rust
curl --proto '=https' --tlsv1.3 https://sh.rustup.rs -sSf | sh
# I was on Ubuntu 20.04, so I did this
rustup toolchain install nightly-x86_64-unknown-linux-gnu
rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu
For reference, I used rustc 1.67.1 (d5a82bbd2 2023-02-07)
.
- run
cargo build
to get the debug executable. This uses a bash script that removes unnecessary linker arguments. A recent version ofgcc
andld.bfd
is required.
cargo +nightly build -Zbuild-std=libc,panic_abort,std -Zbuild-std-features="" --target=./x86_64-unknown-linux-cosmo.json
For reference, I used the below versions of gcc
and ld.bfd
gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1)
GNU ld (GNU Binutils for Ubuntu) 2.34
- run
objcopy
on the debug binary to obtain the APE:
# objcopy is the same version as ld.bfd above
objcopy -SO binary ./target/x86_64-unknown-linux-cosmo/debug/hello.com.dbg ./hello.com
# run the APE
./hello.com
# see syscalls made by the APE
./hello.com --strace
Now we have Actually Portable Executables built with Rust!
- figure out build config to avoid using
libunwind
The std
crate relies on
backtrace
, which depends on
libunwind
in the default builds for
unix. To work around this, cosmopolitan.a
currently has stubs for the
functions that backtrace
relies on. However, it might be easier to provide a
build flag in Cargo.toml
to use the noop
module of backtrace
.
A small change needs to be submitted to the source code of backtrace
(in the
cfg_if!
here)
to allow choosing noop
when building as part of the std
crate. This
conditional compilation flag should be accessible when building the std
crate
either via Cargo.toml
or something like -Z use-std-backtrace-noop
in the
build command.