Having done some digging, I see the same behavior you see.
I think this is not a problem for Chromium because we use LLD (the LLVM linker), which automatically deals with this problem. As you say, `-Wl,--start-group`/`-Wl,--end-group` also solves the problem.
It seems that if you just have a single chain of dependencies, things would work correctly. I.e., in your example if :crypto only depended on :core and :core on :os, the ordering is correct. However, having :crypto also depend on :os directly messes this up.
Which I agree is awfully fragile. To make the problem worse, `gn format` will automatically sort your dependencies, meaning it could break the ordering at any time unless you use `# NOSORT`.
As I said, I would've expected GN to topologically sort the dependencies, but I guess it doesn't. I'm also not sure that attempting to do so would even work reliably or would solve the problem. I'd have to do some digging to figure out (a) why things are the way they are and (b) if we can do anything useful enough about it. I've filed
https://crbug.com/gn/403663745 to track this.
-- Dirk