Earlier quoted context omitted.
Step 0 sounds so easy. Until you realize __time__ exists. Then you take that away, and you find out that some compiler heuristics might not be deterministic. Then you discover -frandom-seed - and go ballistic when you read "but it should be a different seed for each sourcefile" Then you figure out your linker likes emitting a timestamp in object files. Then you discover /Brepro (if you're lucky enough to use lld-link…
I think (well, assumed) what they meant by deterministic builds was merely hermetic builds, which are easier. True determinism is overkill for step 0.
Though in the last 6 years I've seen at least one case where truly deterministic builds mattered:
A performance bug only happens when a malloc() during init was not aligned to 32 bytes, glibc on x86_64 only guaranteed 16 bytes, but depending on what alloc / dealloc happened before it may just land on 32 bytes boundary.
The alloc / dealloc sequence before that point was pretty deterministic, however there were a few strings containing __FILE__. And gitlab runner checked-out codes to a path with random number (or an index? I don't remember) without -ffile-prefix-map or $PWD trick so its length varies.