* Drive everything with Cargo using `build.rs`. This sort of works but it's pretty horrible.
* Give up and just have your main build system run `cargo build`. This is what I normally do but again it's not ideal because it doesn't really integrate properly with your main build system.
* Give up on Cargo entirely. This is what Bazel does, and it's probably the most robust solution but it's still not ideal because most of the Rust ecosystem expects you to use Cargo (e.g. rust-analyzer).
I don't think any other languages have really solved this problem either but it is still an annoying problem.
As you say, this is not a problem with an ideal solution to draw upon. (languages are unavoidably different). From that perspective, I don't see any of these approaches as problems.
If your project is mostly Rust with a little something else sprinkled in, use build.rs ("horrible" is an exaggeration IMO, it's merely not ideal, again, because there exists no ideal).
If your project is mostly something-else with a little Rust sprinkled in, invoke `cargo build` from your build system, and again this is a perfectly adequate solution to a problem with no ideal solutions.
If your project is extra-special, invoke rustc directly, and that's a deliberately supported use case. Hell, I use rustc directly sometimes just because I can.
The bottom line is, Rust provides a best-in-class opinionated build system that is overwhelmingly used by the Rust ecosystem, with best-effort escape hatches for integrating into other projects. To say that Rust cannot "stand the idea that you might want to mix languages", as alleged by the person I originally replied to, is factually incorrect.