> And why are these build systems necessary in the first place?
Because C/C++ compilers are fragmented. And because C/C++ is not very portable. If building for windows -> pass a bunch of -D flags to the compiler. If building for Linux, pass a different set of -D flags. Different compilers require different arguments.
> If there were some type of system where library A says it depends on library B ... and the compiler knows how to resolve this
Here's the crux of the problem. There is no organization that owns or maintains C++, unlike Rust. With Rust, there is only one compiler - rustc. With C++ there are at least 5 major ones maintained by 5 different (competing) organizations.
There's no way to do package management in C++ without massive build system rewrites. Consider:
I write a new C++ package called CoolCrypto. It depends on libssl. I wrote my package in CMake, libssl uses autotools. Barf, the package manager only speaks CMake and gives up.