A simple example with Rust and Cosmopolitan Libc
Go to file
2022-06-22 09:25:13 +05:30
.cargo add cargo config 2022-06-21 23:44:49 +05:30
libcosmo std crate builds with stubs 2022-06-22 09:25:13 +05:30
src std crate builds with stubs 2022-06-22 09:25:13 +05:30
.gitignore std crate builds with stubs 2022-06-22 09:25:13 +05:30
Cargo.toml get basic no_std example to build 2022-06-21 13:15:37 +05:30
gcc-linker-wrapper.bash get basic no_std example to build 2022-06-21 13:15:37 +05:30
LICENSE Initial commit 2022-06-21 11:30:18 +05:30
README.md std crate builds with stubs 2022-06-22 09:25:13 +05:30
x86_64-unknown-linux-cosmo.json std crate builds with stubs 2022-06-22 09:25:13 +05:30

Actually Portable Executables with Cosmopolitan Libc and Rust

This repository contains a simple Hello world! example in the Rust programming language, that builds with Cosmopolitan Libc.

I created 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. I followed the documentation in the Rust Embedonomicon to create the target.

An alternative method to build APEs with Rust would be to avoid cargo, just use rustc or equivalent compiler to generate .o files, and then write a shell script that does the linking with the expected flags. I have not tried this method.

Build steps

  1. Download the Cosmopolitan Libc amalgamation into the libcosmo folder:
cd libcosmo
wget https://justine.lol/cosmopolitan/cosmopolitan.zip
unzip cosmopolitan.zip
cd ../
  1. Download the necessary host toolchain and source code for Rust:
# I was on Debian, 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
# on Alpine Linux, you may need to do
rustup toolchain install nightly-x86_64-unknown-linux-musl
rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-musl
  1. run cargo build to get the debug executable. This uses a bash script that removes unnecessary linker arguments. A recent version of gcc and ld.bfd is required.
cargo +nightly build -Zbuild-std=core,libc --target=./x86_64-unknown-linux-cosmo.json
  1. run objcopy on the debug binary to obtain the APE:
objcopy -SO binary ./target/x86_64-unknown-linux-cosmo/debug/hello_world.com.dbg ./hello_world.com

What about the std crate?

  1. It needs a few stubs functions so the linker doesn't complain. I wrote them out in stubs.c.
cd ./libcosmo/
# compiling a simple stub file via cosmopolitan.h
./compile-stubs.bash
  1. The build command now changes to
cargo +nightly build -Zbuild-std=core,alloc,panic_abort,libc,std -Zbuild-std-features=  --target=./x86_64-unknown-linux-cosmo.json