- git clone itself in a subfolder
- git checkout and build the initial D compiler
- install it in a temporary prefix
- git checkout the first breaking commit and build it with the initial compiler
- install it over the previous compiler
- git checkout ...
and so on. In normal operation all these stages would be cached, so before I abandoned this approach, I think I was up to a hundred or so intermediate versions.
Eventually I started doing git releases, which needed a better solution. So since I have an optional C backend, I just build the compiler with the C backend, then zip up all the C files to make the release. Then to bootstrap from it, I just do (effectively) gcc *.c -o build/neat_bootstrap.
edit: Ah, here it is: https://github.com/Neat-Lang/neat/blob/v0.1.6/bootstrap.sh
Rust has a long chain too, but rustc only uses features itself, that the previous release supports. Releases are every 6 weeks.
Go had been bootstrapping from 1.4 (the last C compiler release), until the release of 1.20 this year, when the bootstrap compiler was bumped to 1.17.13 and will be bumped yearly [0]. That meant go1.4 had to be able to compile new versions, keeping the compiler from using new features in itself for 8 years. Notably, this now allows for generics to be used in the compiler.
For a job, we needed Go on FreeBSD 8, which entailed a local patch to revert pipe2 to pipe in Go, and building from source. That was my first bootstrap. Go, as Russ mentions, is easy to bootstrap, and I've done it a couple of other times.
I've tried to bootstrap Rust, from its old compiler written in OCaml, but that one is trickier. It has not been maintained like Go's bootstrap compiler and the bootstrap chain has long since been broken. Furthermore, rustc is only guaranteed to be able to be buildable with the previous release. As far as I can tell, no one has built rustboot in many years. I like doing software archaeology, so I'll probably try again with that project sometime.
mrustc takes another approach, closer to the aforementioned GNU Mes, in that it's a reimplementation of Rust, intended for bootstrapping rustc. https://github.com/thepowersgang/mrustc