Michael, Thank you for the detailed explanation. I found the current bootstrappable-builds route particularly interesting, especially the role of the patched TCC 0.9.26 as an intermediate step and the discussion surrounding keeping TinyCC HEAD bootstrappable.
One of my biggest takeaways from your reply is that compiler bootstrapping is viewed not merely as a response to the "Trusting Trust" problem, but as a practical engineering concern in its own right. I had not fully appreciated that perspective before. I am also curious about the historical side of the story. Do we know what compiler Fabrice Bellard actually used to build the original OTCC release, and whether that bootstrap path has ever been documented? I'm interested both from a historical perspective and because it seems like an important part of understanding TinyCC's origins. Thank you again for taking the time to explain the current state of the bootstrap chain. Best regards, John > On Jun 2, 2026, at 2:09 PM, Michael Ackermann via Tinycc-devel > <[email protected]> wrote: > > Other than "trusting trust" it is a principle engineering concern. > Furthermore i might point to the fact bootstrappable.org already did solve > the problem on the software side with great efforts (except for firmware/bios > and hardware related issues which were discussed occasionally), but some > patches > from janneke/tcc-0.9.26 weren't rebased onto tcc-head to simplify the whole > procedure a bit on the live-bootstrap side. And this too touches the concern > which C standard iteration tcc itself should follow, and which language > constructs could more or less easily be avoided to retain bootstrappability of > tcc. This topic had been discussed many years ago already if tinycc-devel > could > align internal implementation to bootstrapping criteria a bit, but there seems > to have been some disagreement hence the 0.9.26 fork persisted. I just do not > know yet myself, how complicated a rebase of related changes onto HEAD would > be, > and if it's considered desirable by tinycc-devel and if it is worth the > efforts. > This is a non-trivial discussion and involved different perspectives > naturally. > > Because Tinycc was and is a crucial piece to resolve the whole bootstrapping > up > until most recent c++/gcc/clang compilers. And while there was no > alternative to tcc yet for doing this, i would suggest tinycc itself > deserved a little attention to keep it's latest mob/HEAD bootstrappable too. > As a bonus the bootstrappable.org proceeding provides a decent > system-integration and nightly build CI testing option. There simply is no > need > to "trust" opaque binaries of unknown origin then, since you can easily > bootstrap i386-tcc plus libc etc. inside /chroot within a few minutes of > compilation time already. And from there you can cross/compile almost > everything > else as usual, including support for other ARCH. All this is mission > accomplished already, but needs the mentioned patched tcc-0.9.26 as an > intermediate step still to arrive at tcc-HEAD. > > The current route taken for tcc is: > M0 -> M1 -> M2 -> pnut-cc|mes-cc -> patched tcc-0.9.26 -> tcc-0.9.27|tcc-HEAD > (my tiny-bootstrap fork differs a little with a direct transition from 0.9.26 > to tcc-HEAD and pnut-cc chosen instead of mes-cc because the former is much > faster compile-time for the sake of quicker test cycles) > The c-standard and language construct limitations are intruded by the > transtion > from pnut-cc|mes-cc -> tcc. The M2 C-compiler is a capable but more limited > compiler hence cannot directly compile tcc (you might talk to stikonas and > others who can explain to you in detail which options exist and which > limitations this implies). > > For that matter there's too linux-tcc (and fiwix) kernels available, fully > bootstrapped and driven by tcc, myself is still working on a few things, > mainly > cleanup and testing (too much to mention here and i've yet had no luck > with any contracting to sustain a living either). > > Greetings > >> On 2026-06-02 09:30, John Mastronardo via Tinycc-devel wrote: >> 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: >> GCC is written primarily in C and C++. >> Clang/LLVM is written primarily in C++. >> The Go compiler is written primarily in Go. >> The Rust compiler (rustc) is written primarily in Rust. >> >> 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: >> My assumption that most compilers are written in assembly language is >> historically true for many early compilers, but not for most modern >> compilers. >> The “chicken-and-egg” problem described by Bootstrappable.org is real, >> although whether it is an important practical concern depends on one’s >> threat model and goals. >> >> 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. >> > _______________________________________________ > Tinycc-devel mailing list > [email protected] > https://lists.nongnu.org/mailman/listinfo/tinycc-devel > <signature.asc>
_______________________________________________ Tinycc-devel mailing list [email protected] https://lists.nongnu.org/mailman/listinfo/tinycc-devel
