Everything is a string, even lists are just semicolon-separated lists. The argument expansions rules for calling functions are literally impossible to remember. All variables are implicitly defined as empty strings. Typos silently break things. `if` is completely broken. The separation of the configure step from the build step is needlessly confusing and makes some things impossible. This is just scratching the surface.
It does have a couple of redeeming qualities: they have a pretty great versioning mechanism which allows them to make breaking changes. Though inexplicably they haven't used it to fix any fundamental flaws, only little tweaks. And most importantly it has been around for ages so loads of the many many weird C++ compilation knobs have been solved.