Windows' POSIX support is circa 1988. What I mean, for example, is that Windows API designs tend to leverage threads and callbacks, while Unix uses readiness notification through file descriptors. There are big differences between those two paradigms, and bridging them requires a lot of bug prone boilerplate code.
That's just one example. I18N and L10N is another. The list goes on-and-on.
The best way for an application to simultaneously support Unix and Windows is to not support it for those components which heavily rely on system-specific features. That particularly applies to GUI software.
The problem is that people try to design highly detailed, portable interfaces, when instead of thinking about small details they should think big. That is, break out huge chunks of the application and develop them in parallel, but separately. Trying to write them "portably" as one cohesive whole is foolhardy.
Same logic applies to the build environment. Trying to write or find the "one build system to rule them all" is a fool's errand. You can do better than autotools or CMake by simply not trying to accomplish what those two tools ultimately fail to do. Not developing the Windows portion of a GUI application completely in Visual Studio is just asking for endless and unnecessary headaches.
Point being, if you don't mix portable and non-portable code, you don't really need a complex, "portable" build solution.