I came across the following statement from Bootstrappable.org when I clicked Michael’s link: “Compilers are often written in the language they are compiling. This creates a chicken-and-egg problem that leads users and distributors to rely on opaque, pre-built binaries of those compilers that they use to build newer versions of the compiler.” At first, I wasn’t sure I agreed with the premise because I had always assumed that most compilers were ultimately written in assembly language. After looking into it more, I realized the situation is more nuanced and actually touches on a fascinating aspect of compiler history. Historically, many early compilers were indeed written largely in assembly language. In the early days of computing, there was no alternative. If you wanted a compiler, assembler, or operating system, someone first had to write machine code or assembly code to make it happen. However, once a language became mature enough, compiler developers often rewrote the compiler in the language itself. This is known as a self-hosting compiler. Some modern examples include:
This raises an obvious question: How was the first compiler for a language built if no compiler for that language existed yet? Rust provides a good example. The first Rust compiler was not written in Rust. It was written primarily in OCaml by Graydon Hoare and early contributors. Once that compiler became capable enough, it was used to compile a new implementation of the Rust compiler written in Rust itself. Eventually the OCaml implementation was retired. The evolution looked roughly like this: OCaml compiler ↓ Early Rust compiler (written in OCaml) ↓ Compiles ↓ Rust compiler (written in Rust) ↓ Compiles ↓ Future Rust compilers If we keep following the chain backward, we eventually arrive at something like: Modern Rust compiler ↓ Older Rust compiler ↓ OCaml Rust compiler ↓ OCaml compiler ↓ C compiler ↓ Older C compiler ↓ Assembly-language compiler ↓ Assembler ↓ Hand-entered machine code This is the bootstrap chain that Bootstrappable.org is concerned about. The issue is not that modern compilers are untrustworthy. Rather, their point is that at some stage everyone relies on a pre-built binary that they did not personally create. Most of us accept this as a practical necessity. We trust compiler binaries provided by established projects and distributions. However, researchers interested in software supply-chain integrity ask a deeper question: “Can we reproduce the entire toolchain from source all the way back to a tiny, auditable starting point?” This is closely related to the famous “Trusting Trust” problem described by Ken Thompson. Even if source code appears clean, a malicious compiler binary could theoretically inject unwanted behavior during compilation. That is why projects such as Stage0, GNU Mes, and the broader bootstrappable-builds effort exist. Their goal is to minimize the amount of binary software that must be trusted at the beginning of the build process. As someone interested in TinyCC, I find this particularly interesting because TinyCC occupies a unique place in the compiler ecosystem. Its relatively small size makes it easier to study, understand, and potentially use as part of a bootstrap path compared to the massive codebases of GCC or LLVM. What’s especially fascinating about TinyCC is that it appears to trace its roots to Fabrice Bellard’s remarkably small self-hosting OTCC compiler. OTCC was only a few kilobytes of source code, yet it could already compile itself. Bellard then expanded that foundation into the much more capable TinyCC we know today. If I were to speculate on the likely bootstrap path, it might have looked something like: Hand-written machine code ↓ Assembler ↓ Early Unix C compiler ↓ GCC ↓ OTCC (first version) ↓ Self-hosting OTCC ↓ TinyCC ↓ Modern TinyCC In the end, I came away with two conclusions:
I’m curious how the TinyCC community views this issue and whether anyone here has explored compiler bootstrapping, trusted build chains, or participation in the bootstrappable-builds effort. More specifically, has Fabrice Bellard ever documented exactly which compiler built the first OTCC release? If so, does a reproducible bootstrap path from that original version still exist today? I suspect some long-time TinyCC developers may know the answer from old mailing-list discussions, historical source archives, or Bellard’s original development notes. Best regards, John M. On Jun 2, 2026, at 5:15 AM, Michael Ackermann via Tinycc-devel <[email protected]> wrote:
|
signature.asc
Description: Binary data
_______________________________________________ Tinycc-devel mailing list [email protected] https://lists.nongnu.org/mailman/listinfo/tinycc-devel
