Add MSYS as a platform.

This adds code to build GN for
the MSYS2 platform, NOT mingw,
meaning the Cygwin like POSIX layer.

Change-Id: I6e26522c465750e67ce3b26fd11c8b02726dabdb
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/9660
Reviewed-by: Brett Wilson <brettw@chromium.org>
Commit-Queue: Brett Wilson <brettw@chromium.org>
diff --git a/build/gen.py b/build/gen.py
index c4effa8..c8f0e88 100755
--- a/build/gen.py
+++ b/build/gen.py
@@ -37,6 +37,8 @@
       self._platform = 'darwin'
     elif self._platform.startswith('mingw'):
       self._platform = 'mingw'
+    elif self._platform.startswith('msys'):
+      self._platform = 'msys'
     elif self._platform.startswith('win'):
       self._platform = 'msvc'
     elif self._platform.startswith('aix'):
@@ -54,7 +56,7 @@
 
   @staticmethod
   def known_platforms():
-    return ['linux', 'darwin', 'mingw', 'msvc', 'aix', 'fuchsia', 'freebsd', 'openbsd', 'haiku', 'solaris']
+    return ['linux', 'darwin', 'mingw', 'msys', 'msvc', 'aix', 'fuchsia', 'freebsd', 'openbsd', 'haiku', 'solaris']
 
   def platform(self):
     return self._platform
@@ -65,6 +67,9 @@
   def is_mingw(self):
     return self._platform == 'mingw'
 
+  def is_msys(self):
+    return self._platform == 'msys'
+
   def is_msvc(self):
     return self._platform == 'msvc'
 
@@ -84,7 +89,7 @@
     return self._platform == 'solaris'
 
   def is_posix(self):
-    return self._platform in ['linux', 'freebsd', 'darwin', 'aix', 'openbsd', 'haiku', 'solaris']
+    return self._platform in ['linux', 'freebsd', 'darwin', 'aix', 'openbsd', 'haiku', 'solaris', 'msys']
 
 
 def main(argv):
@@ -202,6 +207,7 @@
   template_filename = os.path.join(SCRIPT_DIR, {
       'msvc': 'build_win.ninja.template',
       'mingw': 'build_linux.ninja.template',
+      'msys': 'build_linux.ninja.template',
       'darwin': 'build_mac.ninja.template',
       'linux': 'build_linux.ninja.template',
       'freebsd': 'build_linux.ninja.template',
@@ -293,6 +299,10 @@
     cxx = os.environ.get('CXX', 'g++')
     ld = os.environ.get('LD', 'g++')
     ar = os.environ.get('AR', 'ar -X64')
+  elif platform.is_msys():
+    cxx = os.environ.get('CXX', 'g++')
+    ld = os.environ.get('LD', 'g++')
+    ar = os.environ.get('AR', 'ar')
   else:
     cxx = os.environ.get('CXX', 'clang++')
     ld = cxx
@@ -361,14 +371,23 @@
         '-std=c++17'
     ])
 
-    if platform.is_linux() or platform.is_mingw():
+    if platform.is_linux() or platform.is_mingw() or platform.is_msys():
       ldflags.append('-Wl,--as-needed')
 
       if not options.no_static_libstdcpp:
         ldflags.append('-static-libstdc++')
 
-      # This is needed by libc++.
-      if not platform.is_mingw():
+      if platform.is_mingw() or platform.is_msys():
+        cflags.remove('-std=c++17')
+        cflags.extend([
+          '-Wno-deprecated-copy',
+          '-Wno-implicit-fallthrough',
+          '-Wno-redundant-move',
+          '-Wno-unused-variable',
+          '-std=gnu++17'
+        ])
+      else:
+        # This is needed by libc++.
         libs.append('-ldl')
     elif platform.is_darwin():
       min_mac_version_flag = '-mmacosx-version-min=10.9'
@@ -384,7 +403,7 @@
     if platform.is_posix() and not platform.is_haiku():
       ldflags.append('-pthread')
 
-    if platform.is_mingw():
+    if platform.is_mingw() or platform.is_msys():
       cflags.extend(['-DUNICODE',
                      '-DNOMINMAX',
                      '-DWIN32_LEAN_AND_MEAN',
diff --git a/src/base/files/file.h b/src/base/files/file.h
index 673a638..dead6bd 100644
--- a/src/base/files/file.h
+++ b/src/base/files/file.h
@@ -23,7 +23,7 @@
 namespace base {
 
 #if defined(OS_BSD) || defined(OS_MACOSX) || defined(OS_NACL) || \
-    defined(OS_HAIKU) || defined(OS_ANDROID) && __ANDROID_API__ < 21
+    defined(OS_HAIKU) || defined(OS_MSYS) || defined(OS_ANDROID) && __ANDROID_API__ < 21
 typedef struct stat stat_wrapper_t;
 #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
 typedef struct stat64 stat_wrapper_t;
diff --git a/src/base/files/file_posix.cc b/src/base/files/file_posix.cc
index a60b22b..349cbfe 100644
--- a/src/base/files/file_posix.cc
+++ b/src/base/files/file_posix.cc
@@ -25,7 +25,7 @@
 namespace {
 
 #if defined(OS_BSD) || defined(OS_MACOSX) || defined(OS_NACL) || \
-    defined(OS_HAIKU) || defined(OS_ANDROID) && __ANDROID_API__ < 21
+    defined(OS_HAIKU) || defined(OS_MSYS) || defined(OS_ANDROID) && __ANDROID_API__ < 21
 int CallFstat(int fd, stat_wrapper_t* sb) {
   return fstat(fd, sb);
 }
diff --git a/src/base/files/file_util_posix.cc b/src/base/files/file_util_posix.cc
index 90362ff..79c9428 100644
--- a/src/base/files/file_util_posix.cc
+++ b/src/base/files/file_util_posix.cc
@@ -58,7 +58,7 @@
 namespace {
 
 #if defined(OS_BSD) || defined(OS_MACOSX) || defined(OS_NACL) || \
-    defined(OS_HAIKU) || defined(OS_ANDROID) && __ANDROID_API__ < 21
+    defined(OS_HAIKU) || defined(OS_MSYS) || defined(OS_ANDROID) && __ANDROID_API__ < 21
 int CallStat(const char* path, stat_wrapper_t* sb) {
   return stat(path, sb);
 }
diff --git a/src/gn/args.cc b/src/gn/args.cc
index bba3eca..392c0c9 100644
--- a/src/gn/args.cc
+++ b/src/gn/args.cc
@@ -302,7 +302,7 @@
 void Args::SetSystemVarsLocked(Scope* dest) const {
   // Host OS.
   const char* os = nullptr;
-#if defined(OS_WIN)
+#if defined(OS_WIN) || defined(OS_MSYS)
   os = "win";
 #elif defined(OS_MACOSX)
   os = "mac";
diff --git a/src/gn/function_write_file_unittest.cc b/src/gn/function_write_file_unittest.cc
index 7113526..5ee6123 100644
--- a/src/gn/function_write_file_unittest.cc
+++ b/src/gn/function_write_file_unittest.cc
@@ -13,7 +13,7 @@
 #include "gn/test_with_scope.h"
 #include "util/test/test.h"
 
-#if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_HAIKU)
+#if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_HAIKU) || defined(OS_MSYS)
 #include <sys/time.h>
 #endif
 
diff --git a/src/util/build_config.h b/src/util/build_config.h
index f7cc991..717b4e3 100644
--- a/src/util/build_config.h
+++ b/src/util/build_config.h
@@ -34,6 +34,8 @@
 // we really are using glibc, not uClibc pretending to be glibc
 #define LIBC_GLIBC 1
 #endif
+#elif defined(__MSYS__)
+#define OS_MSYS 1
 #elif defined(_WIN32)
 #define OS_WIN 1
 #elif defined(__Fuchsia__)
@@ -71,7 +73,8 @@
 #if defined(OS_AIX) || defined(OS_ANDROID) || defined(OS_ASMJS) ||    \
     defined(OS_FREEBSD) || defined(OS_LINUX) || defined(OS_MACOSX) || \
     defined(OS_NACL) || defined(OS_NETBSD) || defined(OS_OPENBSD) ||  \
-    defined(OS_QNX) || defined(OS_SOLARIS) || defined(OS_HAIKU)
+    defined(OS_QNX) || defined(OS_SOLARIS) || defined(OS_HAIKU) || \
+    defined(OS_MSYS)
 #define OS_POSIX 1
 #endif