The biggest problem that those tools try to solve is the issue of portability.
Every platform, be it Linux, Windows, Mac, or whatever, has different tools available for building a given project. When you're dealing with C and C++, build processes can get fairly complex, especially for large projects. A few other languages have similar complexities.
Very often, it's hard to track all of the changes in the project and keep a build script up-to-date, so another job these tools perform is dependency resolution: One module might depend on another group of modules having been built, or it might depend on files that may have changed since the last rebuild. These build tools address that by keeping track of all of that for you.
They also manage build differences and configurations: A build switch given to your build tool can be used to select which modules are built, how, and with what libraries. Usually, the build tool itself enables making these kinds of decisions on a high level without forcing you to write all of the low-level requirements.
But not all build tools are made equal. Some of them are more appropriate for one group of languages and wholly inappropriate for another. .NET project files are just fine for .NET projects and Visual Studio, but they're totally inappropriate for building C and C++ on other platforms.
To address your other question about makefiles: there's some debate on the topic. Peter Miller is convinced it's a bad practice, but many other developers seem to disagree. Personally, I have no stake in it - I just let my build tool of choice (CMake) take care of it.