Just a guy with a love for tech

Building Rust for a Pentium 2

Adam L August 22, 2023

Disclaimer

I've only ever done this using Linux on x86_64 systems.

I've never tried this for any other OS or architecture.

I take no responsibility in your attempt to replicate this even if it causes the universe to explode, trashes your system or causes your significant other to leave you.

Prerequisites

Before proceeding with the compilation process, ensure the following prerequisites are met:

For me, both the source and target systems are running Linux Kernel version 6.1.28 and the version of libc.so.6 was 2.36, which has a minimum kernel version of 3.2.0.

Packages/Tools

Read Rust's dependencies and also its build depenencies for more info

The essentials are:

On Gentoo I was able to get them via Portage: emerge --ask sys-devel/clang dev-vcs/git dev-util/cmake eselect-rust

Clone Rust source and initialise submodules

Begin by cloning the Rust repository, checking out a specific version (1.69.0 in this case), and navigating into the cloned directory:

git clone https://github.com/rust-lang/rust
cd rust
git checkout 1.69.0
git submodule update --init --recursive
git submodule update --recursive

Setup GCC compiler flags

Target the Pentium instruction set which disables MMX/SSE/SSE2.

Theoretically making it compatibile with original Pentiums (hint: it doesn't due to a bug)

export CFLAGS="-march=pentium"
export CXXFLAGS="-march=pentium"

Create a config.toml

Create a config.toml file with your favourite editor (Linux line endings) and insert the following stanza into it:

[llvm]
cflags = "-lz -fcf-protection=none" 
cxxflags = "-lz -fcf-protection=none"
ldflags = "-lz -fcf-protection=none"
targets = "X86"

Setting -fcf-protection=none should stop LLVM for inserting Intel CET instructions, while on most i686 machines these are simply ignored (NOPs), on i586 machines, they cause a SIGILL

$ cargo new hello
Illegal instruction

For full disclosure: Setting the LLVM targets parameter can significantly reduce compile time, but it will disable Rust's cross-compilation capability

Depending on the Rust version you're using, you might also need to add:

download-ci-llvm = false

Note that I didn't need this at the time of writing (2023-08-22).

However, it's worth mentioning that the foundation periodically removes LLVM artifacts.

Build

Adjust the -j flag based on your machine's CPU count (minus 1):

PKG_CONFIG_ALLOW_CROSS=1 ./x.py dist --build i686-unknown-linux-gnu --host i586-unknown-linux-gnu --target i586-unknown-linux-gnu -j 23

Have a cup of tea, or several.

This takes a while, on my Ryzen 5900X it took roughly 1hr 45m to compile.

Compile completed

Now if everything went well, you should now be able to move into the build/dist directory where you should see cargo, rustc, rust-std and rust and all the other tools:

rust-1.69.0-dev-i586-unknown-linux-gnu.tar.gz
rustc-1.69.0-dev-i586-unknown-linux-gnu.tar.gz
cargo-1.69.0-dev-i586-unknown-linux-gnu.tar.gz
... etc.

The one we're intrested in is rust-1.69.0-dev-i586-unknown-linux-gnu.tar.gz

This contains a full Rust install with all the components along with an installer script.

Copy to the target system

I use an SCP command to copy it to my target Pentium 2 machine:

scp build/dist/rust-1.69.0-dev-i586-unknown-linux-gnu.tar.gz user@xxx.xxx.xxx.xxx:~/

Where you can than unpack and install it:

tar -xf rust-1.69.0-dev-i586-unknown-linux-gnu.tar.gz
cd rust-1.69.0-dev-i586-unknown-linux-gnu
./install.sh

Once installed, I like to test by simply running Cargo:

cargo -V or cargo --help

and you should be treated to Cargo's version number.

Problems I've encountered

Back to top