A consultant's three-and-a-half-hour attempt to compile Rust on DragonFly BSD turns into a meditation on dependency weight, circular toolchains, and what it actually means for a language to stand on its own.
Konstantin Schaefer's account of building Rust 1.81 from source on DragonFly BSD reads, on its surface, like a familiar genre of engineering complaint. The numbers are unkind: a 699 MB compressed tarball that expands to 1.9 GB, twenty million lines of Rust source surrounded by another thirty million lines of LLVM and C++, and a compile that consumes three hours and thirty minutes on hardware that finishes the entire OCaml toolchain in under four minutes. But the deeper argument running underneath the rant is not really about file sizes or fan noise. It is about what a programming language owes to the systems and the people that depend on it, and whether convenience at the surface is quietly purchased with fragility at the root.
The thesis hiding inside the rant
The author is careful to separate two things that critics of Rust routinely conflate. The language itself, with its ownership model and its compile-time guarantees, he calls beautiful. His objection is aimed at the official implementation and, more precisely, at its bootstrapping process. A bootstrap is the answer to a deceptively simple question: if the Rust compiler is written in Rust, what compiles the first Rust compiler? For most of Rust's life the answer has been another, slightly older Rust compiler, downloaded as a binary, which was itself produced by an even older binary, and so on back through roughly a hundred intermediate versions until you reach a long-retired compiler that was once written in OCaml.
That regress is the heart of the matter. Rust today cannot, in any practical sense, be built from source alone. You must first obtain a binary compiler from somewhere, and that somewhere is, for most developers, a server in the United States. The author frames this not as a security panic but as a structural observation: a tool that millions now treat as foundational has no path to existence that does not pass through a pre-built artifact someone else produced.

The evidence, measured against a fair yardstick
What makes the piece persuasive rather than merely grumpy is the choice of comparison. OCaml is not invoked as a superior language but as a control variable. It is comparably sophisticated, shipping a bytecode interpreter and native code generators for five architectures, yet it bootstraps from a C compiler and a 3.4 MB bytecode binary checked into its own repository. The entire process is documented, reproducible, and finishes before you have refilled your coffee. Half a million lines of total source produce a working toolchain; Rust's fifty million produce one only after you have already supplied a working toolchain.
The author walks through the indignities in sequence. The README points to an INSTALL.md that was never included in the tarball. Running cloc over the tree takes ten minutes and still hits timeouts, surfacing the genuinely surprising inventory of what lives inside a modern compiler distribution: Pest grammars, SnakeMake workflows, and ten lines of Brainfuck. Each detail is a small joke, but together they sketch a real picture of accumulated mass that no single person fully surveys anymore.

How the rest of the field solved the same problem
The most useful section is the survey of alternatives, because it demonstrates that the circular-bootstrap trap is a choice rather than a law of nature. Zig compiles its self-hosted compiler down to WebAssembly and from there emits a single 1.3-million-line C file, zig1.c, that any C compiler can build. OCaml commits a portable bytecode bootstrap binary. Go keeps version requirements loose, lets 1.24 and 1.25 build from a 1.22 compiler, and preserved a C-written Go 1.4 as an escape hatch back to a non-Go starting point. Erlang ships precompiled bytecode for its own compiler, and Elixir sidesteps the recursion entirely by writing its compiler in Erlang rather than Elixir. Python, Ruby, and Lua are implemented in C and never face the question at all.
The common thread is that each of these projects treats the existence of a clean starting point as a design requirement, not an afterthought. Rust's official implementation made the opposite trade, optimizing for the experience of the developer who runs rustup and never thinks about the chain beneath it. For the overwhelming majority of users that trade is invisible and harmless. The cost lands on the margins: on the maintainer porting Rust to DragonFly BSD, on the distribution that wants a fully source-auditable toolchain, on anyone for whom downloading a binary from a foreign server is a meaningful concern.
The implications worth taking seriously
The broader claim, stated near the close, is the one that lingers. If you are building fundamental tools upon which other and more complex things will be built, the foundation should not be a thousand times more complex than what rests on it. There is a quiet inversion here that deserves attention. The rewrite-it-in-Rust movement has reached the most basic strata of the software stack: text editors, replacements for the core Unix utilities, the uv package installer for Python, the engine behind Tailwind CSS, even a new JIT for Ruby. Each of these inherits, transitively, the entire bootstrap dependency of the Rust compiler. A memory-safe cat now sits atop fifty million lines of source and a binary you cannot regenerate without another copy of itself.
Whether that inversion matters depends entirely on context, and the author is honest about this. For large enterprise applications, for proprietary or safety-critical embedded products, the bootstrap chain is a non-issue and Rust's guarantees are worth a great deal. The warning he attaches there is a different one, about supply-chain exposure through the crate ecosystem and the danger of a blind cargo update across hundreds of transitive dependencies. The two concerns rhyme: both are about how much you can actually account for in the foundation you are standing on.
The counter-perspective
It is fair to push back on the framing. Bootstrap purity is a value, but it is not the only value, and the projects that achieve it have often paid for it in other ways. Zig's zig1.c is impressive precisely because it is unreadable, a generated artifact that nobody audits line by line either. OCaml's checked-in bytecode binary is a trusted blob in its own right, smaller and more transparent than Rust's situation but not categorically different from it. The GCC front-end for Rust, gccrs, which the author hopes will eventually provide an independent second implementation buildable from the C toolchain, is real and advancing, which suggests the community already recognizes the gap and is closing it. And the version-lockstep complaint, that Rust n+1 demands exactly Rust n, reflects a deliberate engineering discipline that keeps the compiler simple at the cost of bootstrap ergonomics.
There is also a reasonable argument that the build time and source size are LLVM's bill, not Rust's. Strip away the ten million lines of LLVM and the picture changes considerably, which is part of why the prospect of a lighter, GCC-based or Cranelift-based path is so appealing to the people who care about this.
Still, none of these rejoinders dissolve the central observation. A language can be excellent in every respect a programmer touches daily and still rest on a foundation that almost no one can rebuild from first principles. That gap between the experience of using a tool and the difficulty of reconstituting it from nothing is the real subject here, and it is a question every maturing technology eventually has to answer. Rust has reached the point of ubiquity where the answer stops being academic, and the choice of whether to use it for a given task, as the author argues, deserves the same care that the language itself brings to memory.

Comments
Please log in or register to join the discussion