I've been looking for a "real" build system for quite some time, something which allows me to correctly and completely specify the relationsships between all elements of my program in a compact and easy-to-maintain sort of way. I didn't think it would be so hard, but apparently it is.
Take Visual Studio, for an example. If I build an executable in directory A and also want to copy it to B, the only way to do that (except for possibly creating a special project for the task) is to add a post-build step which copies the executable from A to B. However, there is no way to make Visual Studio guarantee that the executables actually is copied. If the copy-step fails, it will never be executed again unless the executable itself is rebuilt. Since Visual Studio does not know (or care) about what happens in a post-build step, it is impossible to know if all post-build steps in a project actually succeeded. In other words, post-build steps are useless for anything related to the actual build process.
SCons does this right. Its specification files are Python programs and you can manipulate nodes in the dependency graph exactly as you wish. Given that you've specified your dependency graph correctly, you can actually run scons and it will rerun exactly those commands necessary to bring your targets up-to-date. As a result, you really don't need a "clean" command (even if there is one).
Unfortunately, SCons has serious performance issues and does not scale well for very large systems. But sometimes I'm willing to pay a lot of performance for actually doing correct builds.
I've been using CMake at work for some time, and it has some nice features which makes it the best there is at the moment. The fact that it can generate Visual Studio project files, while still giving command-line people like me a Makefile is a big plus.