2022-06-21 07:09:00 +00:00
|
|
|
# Actually Portable Executables with Cosmopolitan Libc and Rust
|
|
|
|
|
|
|
|
This repository contains a simple `Hello world!` example in the [Rust][rust]
|
|
|
|
programming language, that builds with [Cosmopolitan Libc][cosmo].
|
|
|
|
|
|
|
|
I created a [custom compilation target][custom-target] for Rust, called
|
2022-06-21 09:56:16 +00:00
|
|
|
`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][custom-embed] to create the target.
|
2022-06-21 07:09:00 +00:00
|
|
|
|
|
|
|
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][amalg-download] into the `libcosmo` folder:
|
|
|
|
|
|
|
|
```bash
|
|
|
|
cd libcosmo
|
|
|
|
wget https://justine.lol/cosmopolitan/cosmopolitan.zip
|
|
|
|
unzip cosmopolitan.zip
|
|
|
|
cd ../
|
|
|
|
```
|
|
|
|
|
2022-06-21 09:56:16 +00:00
|
|
|
2. Download the necessary *host* toolchain and source code for Rust:
|
2022-06-21 07:09:00 +00:00
|
|
|
|
|
|
|
```bash
|
2022-06-21 09:56:16 +00:00
|
|
|
# I was on Debian, so I did this
|
2022-06-21 07:09:00 +00:00
|
|
|
rustup toolchain install nightly-x86_64-unknown-linux-gnu
|
|
|
|
rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu
|
2022-06-21 09:56:16 +00:00
|
|
|
# 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
|
2022-06-21 07:09:00 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
3. 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.
|
|
|
|
|
|
|
|
```bash
|
|
|
|
cargo +nightly build -Zbuild-std=core,libc --target=./x86_64-unknown-linux-cosmo.json
|
|
|
|
```
|
|
|
|
|
|
|
|
4. run `objcopy` on the debug binary to obtain the APE:
|
|
|
|
|
|
|
|
```bash
|
|
|
|
objcopy -SO binary ./target/x86_64-unknown-linux-cosmo/debug/hello_world.com.dbg ./hello_world.com
|
|
|
|
```
|
|
|
|
|
|
|
|
## What about the `std` crate?
|
|
|
|
|
2022-06-22 03:55:13 +00:00
|
|
|
1. It needs a few stubs functions so the linker doesn't complain. I wrote them
|
|
|
|
out in `stubs.c`.
|
2022-06-21 07:09:00 +00:00
|
|
|
|
2022-06-22 03:55:13 +00:00
|
|
|
```bash
|
|
|
|
cd ./libcosmo/
|
|
|
|
# compiling a simple stub file via cosmopolitan.h
|
|
|
|
./compile-stubs.bash
|
|
|
|
```
|
2022-06-21 07:09:00 +00:00
|
|
|
|
2022-06-22 03:55:13 +00:00
|
|
|
2. The build command now changes to
|
2022-06-21 07:09:00 +00:00
|
|
|
|
|
|
|
```bash
|
|
|
|
cargo +nightly build -Zbuild-std=core,alloc,panic_abort,libc,std -Zbuild-std-features= --target=./x86_64-unknown-linux-cosmo.json
|
|
|
|
```
|
|
|
|
|
|
|
|
[rust]: https://rust-lang.org
|
|
|
|
[cosmo]: https://github.com/jart/cosmopolitan
|
|
|
|
[amalg-download]: https://justine.lol/cosmopolitan/download.html
|
|
|
|
[custom-target]: https://doc.rust-lang.org/rustc/targets/custom.html
|
|
|
|
[custom-embed]: https://docs.rust-embedded.org/embedonomicon/custom-target.html
|