upvote
Like some other commenters, I do not understand why using a cached binary isn’t sufficient. Why not use the mold3 binary and build that first, and then cache it and never rebuild it again? I’m guessing it has to do with hermiticity and build provenance guarantees in your distro.

Do you have any reading material that you can share that might help me understand better? Docs for the distro, or an issue tracker I can search through?

reply
https://stagex.tools

In short, the entire distro is always built in one-shot at any given commit, and we can only rely on cached binaries from a past release if they or nothing in their supply chains changed. Given rustc depends on almost everything, mold3 would be built far too late to be useful for the most expensive build in the whole tree, which is rust.

Recursive dependencies would break our threat model, so we cannot use any rust tools to bootstrap rust. We bootstrap rust from llvm which we bootstrap from gcc which we bootstrap from tinycc which we bootstrap from M2Planet and so on back to 186 bytes of machine code.

Anyone getting a rust package from stagex must be able to build the entire tree up until that package and get the same hash, with no binary dependencies, thus removing any trust in maintainers.

reply
This is entirely self-inflicted on your part!

> Rust is not actually the right tool for all problems.

Rust is certainly the right tool for this problem, your own decisions notwithstanding.

reply
Self inflicted because we want to protect as many people as possible from supply chain attacks. That is a very real engineering problem we have to solve that extremely high risk end users of our work depend on.

Most popular Linux distros take a position of hoping and praying supply chain attacks do not target them. I am not convinced this will go well for them in the post AI world, but hey, I also hope I am wrong.

reply
What _is_ your threat model?

If you can boostrap one version of stagex (so that its mold is trustworthy), I don't see why you can't use that to build another version of stagex.

As you say, you can rely on the cached binary because nothing in the old version's supply chain would change; it is pinned, and as long as you can build that, everything is fine.

reply
The threat model is trust no single person or computer.

In order for you to not have to trust us, you must clone our repo, of only source code, and build from zero to our released binary hashes. The shorter we can make the time for that to be possible, the more people we can convince to do it and ideally sign and publish their matching hashes. The more people we convince to do it, the less risk of us as maintainers being able add a backdoor without anyone noticing.

Mold was a tool to shave hours off the time most people have to spend doing a from-scratch verification. Forcing them to build a whole tree to get to rust to et to mold3, to then use that to build the whole tree a second time, would directly work against the goal of minimizing full tree verification time.

reply
Why not use LLD for linking Rust? You already must have the LLVM for Rust to be buildable, so that do not add any dependency.
reply
We use the llvm linker, lld, to link mold at the earliest point we can, then use mold exclusively after that. We are an LLVM native distro so we build llvm right away as the system compiler used to build the whole tree instead of gcc.

LLD would work fine for the whole tree, and did previously, but is much much slower than mold which is why we switched to mold.

Having to build all dependencies of rust including python and openssl and everything else before being able to use mold erases most of the full-tree build speedups as the path to rust is already about 80% of the full tree build time.

We are a distro that mandates independently verified 100% deterministic builds from source for any given release commit of the tree, so we have to build the whole tree several times for every release.

reply
Can't you just keep using Mold2 for the initial toolchain bootstrap and then build mold3 with Rust as part of the "final" set of toolchains that are to be used to compile everything beyond that? It isn't perfect but it's congruent with how many other components in most open reproducible bootstrapping flows work; ie using GCC 4.4 or whatever just to bootstrap GCC 10. It's annoying but it only needs to be done once and then you just use it to bootstrap newer components forever. Doesn't help with compile times, though.
reply
I would agree if not for the fact rust depends on almost the entire tree, so doing what you propose would increase our full tree verification time from 6ish hours to 12ish hours erasing any wins mold was giving us in the first place.
reply
Agreed -- not my wheelhouse, but couldn't you just build rust earlier in your process using LLD, then build mold, then build everything else?

Would that meant that building rust is slower, but everything else is the same, and you don't have to maintain a fork of another complex project?

reply
Rust requires python and perl and musl and openssl and 80% of the entire wall time of building the whole tree.

Rust is the single most expensive thing to bootstrap in any given linux distro.

It is the thing you need mold the most for to speed things up.

reply
Hopefully, someone can do some work on decreasing the requirements needed to build rust itself and ease bootstrapping.
reply
I sure hope so. Go is the gold standard to copy here, which is not surprising given the involvement of Ken Thompson who authored Reflections on Trusting Trust.

Unfortunately Rust does not even do full source bootstrapped deterministic builds themselves. Their release strategy is entirely the honor system, where everyone trusts their pinky swear that a single computer or person will never be compromised and allow for the injection of malware into the binaries everyone downloads from rustup.

The only reason we have even the crazy long bootstrap path we have today at all is the hard work of mutabah, an individual independent hacker that does it as a hobby.

The rust team seemingly considers memory safety as the only security problem that matters, and supply chain attacks out of scope.

reply
Because mold is faster. Linking is a significant bottleneck when building large projects.
reply
But we're just talking for bootstrapping Rust here.
reply
The complaint is about bootstrapping, where speed is of little relevance.
reply
It is of extreme relevance for us as we have to re-bootstrap every time we change any dependency of rust, and rust depends on almost everything that is expensive to build in a toolchain tree.
reply
Use the mold binary from the last rebuild and only rebuild again if the new one is different?
reply
I have been thinking about Rust bootstrapping recently. Couldn't a Rust compiler without borrow checker be put together relatively easily?

Assuming the source code contains no issues (which can be checked later once the Rust compiler is built), one could leave that piece behind, and take the shortest path from .rs to executed code (C transpilation, or even an interpreter).

reply
It seems like you would benefit from having reproducible and hermetic builds with a good caching layer so you don't do the same work again and again.

Then you can just use the latest built version to build mold and the next version of rust.

reply
Our tree is entirely reproducible and hermetic. In fact we are the only distro that does this 100%.

The problem is changing any dependency of rust, even python or perl or musl or openssl or the llvm stack or any dependencies of the llvm stack have the potential of resulting in a different hash for rust.

Any time a dependency is changed all decedents must be rebuilt. Which we must do very frequently. That is where mold saved us a ton of time.

reply
That's why you build a stage2 compiler at least with stage0 being the latest prebuilt.

Your stage1 will be based on whatever version is your stage0, but your stage2 should end up identical to any other build with any other stage0. So you don't have to rebuild the full chain all the time.

And then preferably you build a stage3 with FDO, you can easily get 20% more speed with a good corpus of tests.

Do you have at least a distributed cache with I guess sccache to save time for each rebuild?

reply
If we added rust to our stage3, it would add 6 hours of wall time with the fastest 192 core CPU on the market to the time it takes people to reproduce and validate stage3. Add a couple days for someone with just a 16 core consumer CPU.

Our goal is to allow people to reproduce the entire tree from source in the shortest time possible, so no one has to trust us, thus encouraging as many people to do it as possible, thus preventing us from having the means to inject supply chain attacks without anyone noticing.

It is literally a goal for new users to be able to run a server that bootstraps itself, and then bootstraps and signs all future releases, with remote attestation proofs. The shorter that initial build window is the better, which is why things like fast linkers written in early-bootstrappable-languages are so important.

reply
deleted
reply
If the need is well justified, maybe there is great chance to ask adding #[no_mangle] and extern C support? Since release is very fresh. If that is causing the problem. Or is some dependency the issue?
reply
The need here is bootstrapping. If mold is written in Rust you cannot even compile it.
reply
Even Rust is written with Rust. But yeah, if you want to bootstrap absolutely from the beginning, I see the issue.
reply
We regularly and redundantly full source bootstrap our entire tree from 186 bytes of machine code due to a supply chain security policy that forbids trusting any single human or computer.
reply

  > 186 bytes of machine code
This is better (smaller) than Forth!
reply
Could you not either bootstrap rust with lld or bootstrap rust with mold2?
reply
Bootstrapping rust with mold2 is going to be the likely play. My complaint is that now we must maintain mold2 forever now as mold3 rust edition is now incompatible with most of our tree which is made up of dependencies of rust.
reply
How much work is involved with mantaining a linker in deep maintenance mode?
reply
Hopefully not much. I am just lamenting it is an extra dependency and chore we must carry and think about forever, and will have no official upstream support.
reply
Have you considered using Eurydice?
reply
I am not finding any linkers by that name.
reply
It's a rust to C transpiler, I was thinking it could let you use a C version of the mold linker without maintaining one yourself.
reply
Interesting idea! Will look into this.
reply
how's bootstrapping rust story nowadays?
reply
You could use https://github.com/thepowersgang/mrustc to get relatively modern Rust compiler (1.90 currently apparently, but every now and then that is updated). Then build newer rustc from there to reach the current 1.99.

But I don't get why some people are obsessed with bootstrapping. Yes it is good to be able to do it, but it isn't something you need to do regularly.

Especially since rust had a much better cross compilation story than C or C++ (not as good as go or zig though), so you don't need to bootstrap on a new architecture, just cross compile to it. Furthermore, new architectures for hosting a compiler (as opposed to just a target, like microcontrollers) is a rare event. Just something that happens every few years.

reply
> But I don't get why some people are obsessed with bootstrapping.

It only matters if you have supply chain attacks in your threat model. Given they are up 400x since 2019, they should probably be in almost every threat model. Most distros operate on the honor system and that is not going to survive the post AI world.

reply
That's why you have signed packages that everyone can rebuild and verify from the very early stages of bootstrapping to speed up the process and get back to a synchronization point that is reasonable.

Distros that are not fully hermetic and don't have reproducible packages (and there are many layers of reproducibility) will certainly have issues, but that's not a huge problem as long as you have a documented path to getting back to the current state. It doesn't need to be the fastest path, just a verifiable chain of trust.

reply
We do sign our packages, but the threat model is to minimize the time it takes for users to not have to trust us.

It is critical to encourage many independent verifications that it be as fast as possible that someone can go from a clone of our tree of pure source code to the exact release hashes we publish.

Adding any binaries to that means someone that distrusts us must now go build those past releases as well, and if they rely on binaries, they must build those past past releases as well. This approach would make verification time go up dramatically every release.

reply
I'm a bit confused why a decision to decrease the maintenance burden of Mold by switching languages makes Rust the wrong tool here? Fearless concurrency sounds like a huge benefit for what they're doing, given the resources they have.
reply
It's simply an ordering problem. When building the entire world from scratch, usually the C and C++ toolchains are built near the very first, and Rust toolchains built somewhat later. Anything written in Rust must come after the Rust toolchain is built. You need a linker as part of your C++ toolchain, so it must be written in a language ready to go at that point. If it is written in C, you are done. If it is written in Rust you have to wait. So a Rust-based linker can no longer be used from that very, very early C bootstrap.

It's not a big deal for normal users, where you have Rust ready to go. Kind of a bummer in this case, but this is a specialized one.

reply
Can't you just use a statically linked mold binary for the initial bootstrap, just like you use some kind of pre-existing, basic C compiler?
reply
You could. But now you are trusting an entirely new toolchain that can build the Rust-based linker, even if it is statically linked. This toolchain is much larger than a comparatively small and much more easily understood C bootstrap toolchain.

This effectively triples or quadruples (maybe even more) the amount of code you need to trust for the cold bootstrap.

reply
Why do you keep saying C? Mold was C++ with some dependencies like TBB or zstd.
reply
Too many years at Google where the two terms are most often used interchangeably; which is imprecise, but most of the time it doesn't matter. Forgive me for being imprecise here.

The fact remains that rust adds yet another toolchain to the boot process that needs trust and verification.

reply
deleted
reply
Maybe that's about to flip. Maybe Rust will be built first, followed by C.
reply
Sorry to break it to everyone but Rust depends on python which depends on perl and openssl and the majority of any lean full source bootstrapped toolchain tree.

Unless the gcc rust engine is mature any time soon (lol), we have no path to use rust until very late game in a distro build.

The earliest we can bootstrap a go compiler is about 10 minutes. It builds directly from tinycc. Add 6 hours for our fastest compile of the shortest path to rust, with 192 cores.

I am a rust fan too, but it is the worst language to bootstrap, which is why for systems programming I still must often revert to C to have a small and reviewable and fast to build dependency surface.

reply
deleted
reply
Rust requires LLVM (or GCC) which requires C++, not just C.
reply
LLVM is the default yes, there is also an experimental cranelift backend, which is all Rust. Not sure if it is good enough to build the compiler itself using it.

(There is also a GCC backend called codegen_gcc that is pretty far along. And a separate reimplementation of both the frontend and backend using gcc and C++, called gccrs, which is not nearly as far along.)

reply
I'm pretty sure it does not support enough features to build the compiler (e.g. inline asm is not supported at all), and it will also be very, very slow to unusable.
reply
Maybe it should be rewritten in Rust then
reply
One of the explicit goals for Mold 3.0 is to promote its use as the default linker in Linux distributions, and bootstrapping complexity is certainly worthy of consideration in that realm.

> We will then conduct extensive compatibility testing and work closely with Linux distribution developers to make it practical for them to adopt mold as /usr/bin/ld. Making this happen is one of our highest priorities for mold 3.x.

reply
We are one of only two distros that uses mold as the default system linker. Unfortunately that will be stuck at mold2 until the full tree is built, but we can swap to mold3 for end user consumers of the tree. Sucks that we have to maintain and use both now.
reply
[flagged]
reply
I do understand what you are trying to say, but I think that this fails to be kind to Irvick and the other maintainers of the stage0 project who are actually being quite underfunded (someone like OAI should fund them in the name of security!)

So asking them to pay money is well.. not quite the solution.

What can happen as it often happens, is this, Mold creator created the project, Stage0 found it useful, Mold ports itself to rust, Stage0 now founds it not useful, Stage0 can comment on the new update and be slightly disappointed and comment how they would've preferred to not rust in this particular case for them.

Yes this doesn't prevent mold from changing to rust or anything as it was shown but I guess we can allow the ability for Irvick to drop a comment I guess without saying that's your responsibility while they are just being maintainers of the open source and an underfunded/mostly volunteer one of work at that.

Also, @Irvick, stage0 is extremely cool, I hope that a lot more companies sponsor the work that stage0 contributors are doing. I think that it can help the supply-chain issues that the industry is facing at, and is honestly just a really cool idea and I love reading your comments and thank you!

reply
To be clear we maintain stagex, which is a distro built on stage0 as the foundation.

Otherwise thank you for for the kind words.

reply
Yes pardon me for the slight confusion but I meant stagex (though to be honest I am impressed by stage0 and how minimalist it is as well) and how stagex compromises of all of these stages to finally build a whole distro

Also your welcome and have a nice day!

reply
>Rust is not actually the right tool for all problems.

"my problems (that are not mold's) are not solved by mold. How dare mold make those decisions?"

Maybe you should rewrite more of your linux distribution in rust so it's available earlier in the build process and get back to it being the default linker.

reply
They were solved by mold. And then mold decided to un-solve them.
reply
The mold developers are not responsible for what people want to do with their software.
reply
No, they were never one of mold's goals. You don't get to assign solutions to people _and then blame them_. Hyrum's Law being a load bearing part of your infrastructure isn't Mold's problem.
reply
I can't really agree with that. If you ship your linker with a disclaimer saying 'don't use this for early stage stuff, one day we might decide to rewrite the whole codebase in a language that won't be available early enough' then you'd have a point. But if you didn't that is precisely the kind of use case where mold shines, and so inevitably it will be adopted. Your downstream should be precious. At a minimum you should communicate such intentions, do so timely and hear what others have to say, even if afterwards you decide to push on.
reply
Pretty much every piece of open source software ships with a legal document saying that the software is provided as-is without any warranty or guarantee of functionality (i.e. https://github.com/rui314/mold/blob/main/LICENSE ). Unless I had a support agreement with the maintainers that superseded that document, I would not expect any special treatment from upstream. Personally, whenever I add a new dependency, I do it with the knowledge that I may have to either replace it or take on maintenance myself in the future.
reply
Sure. But the ability to do this kind of rugpull is new and so you will get responses like these and that's perfectly logical regardless of the legalities. I'm not saying you can't. But I am saying that if you ignore your users - even if what you ship is free and open - you are still going to be subject to backlash if you change course very rapidly. You could also simply create a new project and support the old one during some transition period. Principle of least surprise and all that.
reply
Are you seriously arguing that every open source project needs to anticipate every single way any of their users might use their software in the future, and also any future change they might want to make to the software, and write up a doc of disclaimers and caveats?

This is ridiculous. The amount of entitlement I'm reading here is gross. This is how you burn out maintainers and drive them away from open source.

> Your downstream should be precious.

No. Every open source maintainer is free to decide for themselves how much or how little they are willing to bend over backward for the sake of serving all possible user needs. If you don't like that, then feel free to build whatever you need yourself, from scratch.

reply
Strawman detected.
reply
I actually made a Linux distribution that relies on this being your latest comment, since you didn't say this wouldn't always be your latest comment. If you post any newer ones, it will break.

Edit: darn, it broke

reply
>Your downstream should be precious

Is my downstream paying me for the maintenance ?

If not, downstream may maintain mold2 themselves forever because their _extremely specific_ use case is neither a promise nor a valuable thing for mold to maintain. Debian understood this a while ago and isn't whining when they have to maintain their own fork. Maintainers maintain.

If enough downstreamers are unhappy about choices, they are also welcome to fork, until the base project is abandoned. Or they realize their usecases are extremely narrow.

(In addition, it's an extremely hypocritical and purist demand, because I am pretty certain that their distribution has, at some point, an arbitrary executable to make a compiler from. So they're probably okay with blobs, just not that one in particular.)

reply
> Your downstream should be precious.

Yeah, for stuff we wanna rely on, this should ideally be the default. I'd go one step further and say no breaking changes past 1.0.0 at all. Instead people should favor creating entirely new projects (forks or not) and jump over to those, leaving the old one behind, if they want to do massive changes to something.

Of course, no one would be forced to do this, but it feels like if more did this, long-term supporting stuff that depends on those things would be a lot easier, if things could just be instead of changing under our feet all the time. Thank god for Nix and NixOS, even with their warts.

reply
What's that benefit of a new project and abandoning an old one when you can just as easily continue using the old version?
reply
What? Why would mold be particularly valuable for early stage compilation, to the point that you’d explicitly cater to that user base?
reply
Luckily Mr Clanker can do most of the work for you at least (I myself have already had Claude/Codex rewrite a couple of Rust projects in C, worked great)
reply
And repeat that work every time you sync with upstream?
reply
Why do you need to bootstrap a toolchain to bootstrap a distro?

I know this is common but it seems like either an aesthetic decision, or glibc cruft.

reply
There are classes of virus that are hard to detect. One is a compiler virus that passes itself from compiler to compiler. You only get rid of the vector by bootstrapping from 0.
reply
No, you can do bootstrapping and save binaries for reuse with hash verification. Android did that for its Rust toolchain: https://cs.android.com/android/platform/superproject/main/+/...

Bootstrapping at every build does not save you from the threat you think it does.

reply
We only re-bootstrap the layers which had dependencies change under them. Early parts of the tree rarely change so we often do not have to rebuild these across releases, but very late tree things like rust depend on almost everything and something in the rust dependency graph changes almost every release.

Using binaries from past releases is a strict downgrade in terms of verification speed, as it means a new independent reproducible build verifier must now build both trees, doubling the release verification time, and erasing any wins mold3 could otherwise offer.

Google can rely on lots of centralized internal provenance tooling to prove cached binaries are not tampered with to other Googlers but when the goal is proving end to end full source bootstrapped build integrity to any interested user from the public in the least time possible, the requirements are significantly higher.

reply
Sure but that's a compiler bootstrapping problem. It doesn't answer the question: why do you need to bootstrap the toolchain to build the distro? You can reuse a trusted toolchain that's been safely bootstrapped .
reply
Because no other trusted toolchains exist under a threat model that trusts no single person or computer. We -are- the trusted toolchain.
reply