WIP: Fix (cross)compile with MinGW

Tested on debian with the floowing settings:
$ export AR=x86_64-w64-mingw32-ar
$ export LD=x86_64-w64-mingw32-g++
$ export CXX=x86_64-w64-mingw32-g++
$ ./build/gen.py --out-path=$PWD/mingw --platform=mingw --host=linux
$ ninja -C mingw

It compiles fine and most of the tests are working.
Sadly it's using some exotic functions that seems to not be implemented
in wine and some tests are failing:

bogdan@dragon:~/.wine/drive_c/gn$ wine gn_unittests.exe
000b:fixme:winediag:start_process Wine Staging 4.0-rc2 is a testing
version containing experimental patches.
000b:fixme:winediag:start_process Please mention your exact version when
filing bug reports on winehq.org.
[134/547] SourceDi002a:fixme:nls:CompareStringEx semi-stub behavior for
flag(s) 0x10
002a:fixme:file:FindFirstFileExW flags not implemented 0x00000002
002a:fixme:file:FindFirstFileExW flags not implemented 0x00000002
[3002a:fixme:file:FindFirstFileExW flags not implemented 0x00000002
002a:fixme:file:FindFirstFileExW flags not implemented 0x00000002
[414/547] FilesystemUtils.SourceDirForPath
*** FAILURE ../src/gn/filesystem_utils_unittest.cc:578: "//baR/" ==
SourceDirForPath(root, base::FilePath(u"c:/SOURCE\\Foo/baR/")).value()

002a:fixme:file:FindFirstFileExW flags not implemented 0x00000002
002a:fixme:file:FindFirstFileExW flags not implemented 0x00000002
002a:fixme:file:FindFirstFileExW flags not implemented 0x00000002
[438/547] FormatTest.001
*** FAILURE ../src/gn/command_format_unittest.cc:47:
base::ReadFileToString( base::FilePath(FILE_PATH_LITERAL("src/gn/
format_test_data/") FILE_PATH_LITERAL("001") FILE_PATH_LITERAL(".gn")),
&input)

[439/547] FormatTest.002
*** FAILURE ../src/gn/command_format_unittest.cc:48:
base::ReadFileToString( base::FilePath(FILE_PATH_LITERAL("src/gn/
format_test_data/") FILE_PATH_LITERAL("002") FILE_PATH_LITERAL(".gn")),
&input)

continue with tons of same errors, till:

[516/547] FormatTest.081
*** FAILURE ../src/gn/command_format_unittest.cc:128:
base::ReadFileToString( base::FilePath(FILE_PATH_LITERAL("src/gn/
format_test_data/") FILE_PATH_LITERAL("081") FILE_PATH_LITERAL(".gn")),
&input)

Change-Id: Ie64d7009a085221967b02b2b8b6f375c7e5b874e
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/7360
Commit-Queue: Brett Wilson <brettw@chromium.org>
Reviewed-by: Brett Wilson <brettw@chromium.org>
diff --git a/build/gen.py b/build/gen.py
index 989eb5a..0911f35 100755
--- a/build/gen.py
+++ b/build/gen.py
@@ -47,7 +47,7 @@
 
   @staticmethod
   def known_platforms():
-    return ['linux', 'darwin', 'msvc', 'aix', 'fuchsia', 'freebsd', 'openbsd', 'haiku']
+    return ['linux', 'darwin', 'mingw', 'msvc', 'aix', 'fuchsia', 'freebsd', 'openbsd', 'haiku']
 
   def platform(self):
     return self._platform
@@ -178,6 +178,7 @@
 
   template_filename = os.path.join(SCRIPT_DIR, {
       'msvc': 'build_win.ninja.template',
+      'mingw': 'build_linux.ninja.template',
       'darwin': 'build_mac.ninja.template',
       'linux': 'build_linux.ninja.template',
       'freebsd': 'build_linux.ninja.template',
@@ -334,14 +335,15 @@
         '-std=c++17'
     ])
 
-    if platform.is_linux():
+    if platform.is_linux() or platform.is_mingw():
       ldflags.append('-Wl,--as-needed')
 
       if not options.no_static_libstdcpp:
         ldflags.append('-static-libstdc++')
 
       # This is needed by libc++.
-      libs.append('-ldl')
+      if not platform.is_mingw():
+        libs.append('-ldl')
     elif platform.is_darwin():
       min_mac_version_flag = '-mmacosx-version-min=10.9'
       cflags.append(min_mac_version_flag)
@@ -356,6 +358,17 @@
     if platform.is_posix() and not platform.is_haiku():
       ldflags.append('-pthread')
 
+    if platform.is_mingw():
+      cflags.extend(['-DUNICODE',
+                     '-DNOMINMAX',
+                     '-DWIN32_LEAN_AND_MEAN',
+                     '-DWINVER=0x0A00',
+                     '-D_CRT_SECURE_NO_DEPRECATE',
+                     '-D_SCL_SECURE_NO_DEPRECATE',
+                     '-D_UNICODE',
+                     '-D_WIN32_WINNT=0x0A00',
+                     '-D_HAS_EXCEPTIONS=0'
+      ])
   elif platform.is_msvc():
     if not options.debug:
       cflags.extend(['/O2', '/DNDEBUG', '/Zc:inline'])
@@ -680,19 +693,35 @@
         'src/base/win/scoped_process_information.cc',
     ])
 
-    libs.extend([
-        'advapi32.lib',
-        'dbghelp.lib',
-        'kernel32.lib',
-        'ole32.lib',
-        'shell32.lib',
-        'user32.lib',
-        'userenv.lib',
-        'version.lib',
-        'winmm.lib',
-        'ws2_32.lib',
-        'Shlwapi.lib',
-    ])
+    if platform.is_msvc():
+      libs.extend([
+          'advapi32.lib',
+          'dbghelp.lib',
+          'kernel32.lib',
+          'ole32.lib',
+          'shell32.lib',
+          'user32.lib',
+          'userenv.lib',
+          'version.lib',
+          'winmm.lib',
+          'ws2_32.lib',
+          'Shlwapi.lib',
+      ])
+    else:
+      libs.extend([
+          '-ladvapi32',
+          '-ldbghelp',
+          '-lkernel32',
+          '-lole32',
+          '-lshell32',
+          '-luser32',
+          '-luserenv',
+          '-lversion',
+          '-lwinmm',
+          '-lws2_32',
+          '-lshlwapi',
+      ])
+
 
   # we just build static libraries that GN needs
   executables['gn']['libs'].extend(static_libraries.keys())
diff --git a/src/base/files/file_util_win.cc b/src/base/files/file_util_win.cc
index fe5c225..a18715e 100644
--- a/src/base/files/file_util_win.cc
+++ b/src/base/files/file_util_win.cc
@@ -4,16 +4,19 @@
 
 #include "base/files/file_util.h"
 
+// windows.h includes winsock.h which isn't compatible with winsock2.h. To use winsock2.h
+// you have to include it first.
+#include <winsock2.h>
 #include <windows.h>
 
 #include <io.h>
 #include <psapi.h>
+#include <share.h>
 #include <shellapi.h>
 #include <shlobj.h>
 #include <stddef.h>
 #include <stdint.h>
 #include <time.h>
-#include <winsock2.h>
 
 #include <algorithm>
 #include <iterator>
@@ -36,7 +39,7 @@
 // "Community Additions" comment on MSDN here:
 // http://msdn.microsoft.com/en-us/library/windows/desktop/aa387694.aspx
 #define SystemFunction036 NTAPI SystemFunction036
-#include <NTSecAPI.h>
+#include <ntsecapi.h>
 #undef SystemFunction036
 
 namespace base {
diff --git a/src/base/files/file_win.cc b/src/base/files/file_win.cc
index 2a65548..e9c90e3 100644
--- a/src/base/files/file_win.cc
+++ b/src/base/files/file_win.cc
@@ -246,7 +246,9 @@
       return FILE_ERROR_NO_MEMORY;
     case ERROR_HANDLE_DISK_FULL:
     case ERROR_DISK_FULL:
+#ifndef __MINGW32__
     case ERROR_DISK_RESOURCES_EXHAUSTED:
+#endif
       return FILE_ERROR_NO_SPACE;
     case ERROR_USER_MAPPED_FILE:
       return FILE_ERROR_INVALID_OPERATION;
diff --git a/src/base/win/windows_types.h b/src/base/win/windows_types.h
index d076c44..880586e 100644
--- a/src/base/win/windows_types.h
+++ b/src/base/win/windows_types.h
@@ -9,6 +9,7 @@
 #define BASE_WIN_WINDOWS_TYPES_H
 
 // Needed for function prototypes.
+#include <inttypes.h>
 #include <concurrencysal.h>
 #include <sal.h>
 #include <specstrings.h>
diff --git a/src/util/worker_pool.cc b/src/util/worker_pool.cc
index 38ab480..9f6a47b 100644
--- a/src/util/worker_pool.cc
+++ b/src/util/worker_pool.cc
@@ -32,7 +32,7 @@
   if (num_groups_ <= 1)
     return;
 
-  const HANDLE thread_handle = thread->native_handle();
+  const HANDLE thread_handle = HANDLE(thread->native_handle());
   ::GetThreadGroupAffinity(thread_handle, &group_affinity_);
   group_affinity_.Group = group_;
   const bool success =