Building Rust for a Pentium 2
Adam L August 22, 2023Disclaimer
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:
- Have a working Linux setup that has a fast, modern i686 CPU with SSE2 support.
- The target system must have a Linux Kernel greater than 3.2.0 with GLIBC 2.3 or later.
- Ideally your source and target systems should have the same version of GLIBC.
- If the source machine is too new, you'll get errors like
CPU ISA level is lower than required
, segfaults or other strange errors.
- If the source machine is too new, you'll get errors like
- At least 30 GB of free disk space on the source machine (according to Rust), preferably NVMe.
- 8+ GB of RAM, the more the better.
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:
- git
- python3.7
- gcc
- curl
- pkg-config
- libiconv
- openssl
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:
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)
Create a config.toml
Create a config.toml file with your favourite editor (Linux line endings) and insert the following stanza into it:
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
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
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:
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:
Where you can than unpack and install it:
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
-
CPU ISA level is lower than required
: That probably means your GLIBC on the source machine was higher than the target. You'll need to fix that and recompile Rust. -
SIGILL
(Illegal Instruction): This might mean you forgot to run theexport
commands or the LLVM flags inconfig.toml
were not set properly and the Rust you built includes CET or SSE instructions that don't work on a Pentium 2 or lower. Make sure they're set and then recompile.