I would recommend against that as well.
I have a directory structure where there's a module/hello.c (stub or generic, platform independent code) and then there's module/platform/hello.c which my Makefile selects over the generic one based on the platform. Primary issue is that there's some code duplication, and it's hard to keep .h files general across platforms all the time (not possible all the time), but in general it does make life a lot easier - especially if platform number grows over time or certain are removed.
Related: http://doc.cat-v.org/henry_spencer/ifdef_considered_harmful
I always thought that was funny. You are using the most powerful (of the widely used) language available for transforming text, but must fall back to the C preprocessor.
I use CMake with Ninja, which is faster and nicer than plain old Make.
CMake completely falls apart if you're trying to do anything else than normal user space applications that link with commonly used libraries. Some years ago I tried building a bare metal project with CMake and the job got done but the experience was atrocious.
But CMake really shines in building "normal" applications and in particular cross compiling them.
You can use MingW's make but compile with cl instead of gcc and that problem is not present. You will have to check if all compiler flags are supported though. Or use a wrapper around cl which translates compiler flags, pretty sure that exists already.
My preferred approach lately is an amalgamation build
That won't scale well though. For large projects you'll really want to use something as mentioned above, or have seperate Makefiles and VS projects, or use a build file generator like CMake.
edit another thing I wanted to add: instead of using
all over the place another option is to split the implementations over source files like impl/win32.c and impl/unix.c then have the build system deal with selecting the correct one. Especially when there are more than a couple of platforms this is much cleaner and more convenient.