diff -Naur ruby-2.7.0-orig/configure.ac ruby-2.7.0/configure.ac
--- ruby-2.7.0-orig/configure.ac	2020-03-25 10:09:06.566141600 +0300
+++ ruby-2.7.0/configure.ac	2020-03-25 10:10:53.434170100 +0300
@@ -335,14 +335,14 @@
 ASFLAGS=$ASFLAGS
 AC_SUBST(ASFLAGS)
 
-AS_CASE(["$target_os"],[cygwin*|mingw*], [ac_cv_prog_ac_ct_OBJCOPY=":"])
+AS_CASE(["$target_os"],[cygwin*|msys*|mingw*], [ac_cv_prog_ac_ct_OBJCOPY=":"])
 
 # BSD's ports and MacPorts prefix GNU binutils with 'g'
 AC_CHECK_TOOLS(OBJDUMP, [objdump gobjdump])
 AC_CHECK_TOOLS(OBJCOPY, [objcopy gobjcopy])
 
 AS_CASE(["$target_os"],
-[cygwin*|mingw*], [
+[cygwin*|msys*|mingw*], [
     AC_CHECK_TOOL(WINDRES, windres)
     AC_CHECK_TOOL(DLLWRAP, dllwrap)
     target=`echo $target | sed "s/^$target_cpu-/-/"`
@@ -649,7 +649,7 @@
 	AC_DEFINE(RUBY_MINGW64_BROKEN_FREXP_MODF)
       ])
     ],
-    [cygwin*|darwin*|netbsd*], [
+    [cygwin*|msys*|darwin*|netbsd*], [
       # need lgamma_r(), finite()
     ])
 
@@ -947,7 +947,7 @@
 [haiku*], [
 		LIBS="$LIBS" # m lib is include in root
 		],
-[cygwin*], [	ac_cv_header_langinfo_h=yes
+[cygwin*|msys*], [	ac_cv_header_langinfo_h=yes
 		RUBY_APPEND_OPTIONS(CPPFLAGS, -D_XOPEN_SOURCE -D_GNU_SOURCE)
 		AC_CHECK_FUNCS(cygwin_conv_path)
 		AC_LIBOBJ([langinfo])
@@ -1950,7 +1950,7 @@
 	    rb_cv_getcwd_malloc=yes,
 	    rb_cv_getcwd_malloc=no,
 	    AS_CASE($target_os,
-		[linux*|darwin*|*bsd|cygwin*|mingw*|mswin*],
+		[linux*|darwin*|*bsd|cygwin*|msys*|mingw*|mswin*],
 		[rb_cv_getcwd_malloc=yes],
 		[rb_cv_getcwd_malloc=no]))])
     AS_IF([test "$rb_cv_getcwd_malloc" = no], [AC_DEFINE(NO_GETCWD_MALLOC, 1)])
@@ -2625,7 +2625,7 @@
       # mkmf.rb's have_header() to fail if the desired resource happens to be
       # installed in the /usr/local tree.
       RUBY_APPEND_OPTION(CCDLFLAGS, -fno-common)],
-    [bsdi*|cygwin*|mingw*|aix*|interix*], [ ],
+    [bsdi*|cygwin*|msys*|mingw*|aix*|interix*], [ ],
     [
       RUBY_APPEND_OPTION(CCDLFLAGS, -fPIC)])
   ], [
@@ -2729,7 +2729,7 @@
 			: ${LDSHARED='$(LD) -Bshareable -x'}
 			LDFLAGS="$LDFLAGS -L/lib -L/usr/lib -L/usr/local/lib"
 			rb_cv_dlopen=yes],
-	[cygwin*|mingw*], [
+	[cygwin*|msys*|mingw*], [
 			: ${LDSHARED='$(CC) -shared'}
 			XLDFLAGS="$XLDFLAGS -Wl,--stack,0x00200000,--enable-auto-import"
 			DLDFLAGS="${DLDFLAGS} -Wl,--enable-auto-image-base,--enable-auto-import"
@@ -3084,7 +3084,7 @@
 SOLIBS='$(MAINLIBS)'
 
 AS_CASE(["$target_os"],
-  [cygwin*|mingw*|haiku*|darwin*], [
+  [cygwin*|msys*|mingw*|haiku*|darwin*], [
     : ${DLDLIBS=""}
     ],
   [
@@ -3114,7 +3114,7 @@
 	    [darwin*], [
 	        RUBY_SO_NAME='$(RUBY_BASE_NAME).$(RUBY_API_VERSION)'
 	    ],
-	    [cygwin*], [
+	    [cygwin*|msys*], [
 	        RUBY_SO_NAME='$(RUBY_BASE_NAME)$(MAJOR)$(MINOR)0'
 	    ],
 	    [mingw*], [
@@ -3479,7 +3479,7 @@
 	  CFLAGS="$CFLAGS -std"
 	])
 	],
-    [cygwin*|mingw*], [
+    [cygwin*|msys*|mingw*], [
 	LIBRUBY_DLDFLAGS="${LIBRUBY_DLDFLAGS}"' -Wl,--out-implib=$(LIBRUBY)'
 	AS_CASE(["$target_os"],
 	[cygwin*], [
@@ -3488,6 +3488,12 @@
 		LIBRUBY_DLDFLAGS="${LIBRUBY_DLDFLAGS}"' $(RUBYDEF)'
 	    ])
 	    ],
+	[msys*], [
+	    if test x"$enable_shared" = xyes; then
+		LIBRUBY_SO='msys-$(RUBY_SO_NAME)'.dll
+		LIBRUBY_DLDFLAGS="${LIBRUBY_DLDFLAGS}"' $(RUBYDEF)'
+	    fi
+	    ],
 	[mingw*], [
 	    AS_IF([test x"$enable_shared" = xyes], [
 		LIBRUBY_SO='$(RUBY_SO_NAME)'.dll
diff -Naur ruby-2.7.0-orig/cygwin/GNUmakefile.in ruby-2.7.0/cygwin/GNUmakefile.in
--- ruby-2.7.0-orig/cygwin/GNUmakefile.in	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/cygwin/GNUmakefile.in	2020-03-25 10:10:53.699731700 +0300
@@ -7,6 +7,8 @@
 
 ifeq (@target_os@,cygwin)
   DLL_BASE_NAME := $(LIBRUBY_SO:.dll=)
+else ifeq (@target_os@,msys)
+  DLL_BASE_NAME := $(LIBRUBY_SO:.dll=)
 else
   DLL_BASE_NAME := $(RUBY_SO_NAME)
   DLLWRAP += -mno-cygwin
@@ -100,6 +102,12 @@
 	$(ECHO) generating $@
 	$(Q) @DLLWRAP@ -s --def=$(RUBYDEF) -o $@
 endif
+
+ifeq (@target_os@,msys)
+msys2-$(RUBY_INSTALL_NAME)$(MAJOR)$(MINOR)0.dll: $(LIBRUBY_A) $(RUBYDEF)
+	$(ECHO) generating $@
+	$(Q) @DLLWRAP@ -s --def=$(RUBYDEF) -o $@
+endif
 
 clean-local::
 	@$(RM) $(RUBY_EXP) $(RCFILES:.rc=.res.@OBJEXT@)
diff -Naur ruby-2.7.0-orig/ext/etc/extconf.rb ruby-2.7.0/ext/etc/extconf.rb
--- ruby-2.7.0-orig/ext/etc/extconf.rb	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/ext/etc/extconf.rb	2020-03-25 10:10:57.399586800 +0300
@@ -36,7 +36,7 @@
   $defs.push("-DPW_AGE2VAL="+f)
 end
 have_struct_member('struct passwd', 'pw_class', 'pwd.h')
-have_struct_member('struct passwd', 'pw_comment', 'pwd.h') unless /cygwin/ === RUBY_PLATFORM
+have_struct_member('struct passwd', 'pw_comment', 'pwd.h') unless /cygwin|msys/ === RUBY_PLATFORM
 have_struct_member('struct passwd', 'pw_expire', 'pwd.h')
 have_struct_member('struct passwd', 'pw_passwd', 'pwd.h')
 have_struct_member('struct group', 'gr_passwd', 'grp.h')
diff -Naur ruby-2.7.0-orig/ext/extmk.rb ruby-2.7.0/ext/extmk.rb
--- ruby-2.7.0-orig/ext/extmk.rb	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/ext/extmk.rb	2020-03-25 10:10:57.540176000 +0300
@@ -473,7 +473,7 @@
 exts = $static_ext.sort_by {|t, i| i}.collect {|t, i| t}
 default_exclude_exts =
   case
-  when $cygwin
+  when $cygwin, $msys
     %w''
   when $mswin, $mingw
     %w'pty syslog'
diff -Naur ruby-2.7.0-orig/ext/readline/extconf.rb ruby-2.7.0/ext/readline/extconf.rb
--- ruby-2.7.0-orig/ext/readline/extconf.rb	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/ext/readline/extconf.rb	2020-03-25 10:10:57.836976200 +0300
@@ -30,7 +30,7 @@
 dir_config("readline")
 enable_libedit = enable_config("libedit")
 
-have_library("user32", nil) if /cygwin/ === RUBY_PLATFORM
+have_library("user32", nil) if /cygwin|msys/ === RUBY_PLATFORM
 have_library("ncurses", "tgetnum") ||
   have_library("termcap", "tgetnum") ||
   have_library("curses", "tgetnum")
diff -Naur ruby-2.7.0-orig/ext/Setup.nt ruby-2.7.0/ext/Setup.nt
--- ruby-2.7.0-orig/ext/Setup.nt	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/ext/Setup.nt	2020-03-25 10:10:57.977568900 +0300
@@ -1,4 +1,4 @@
-#option platform cygwin|mingw|mswin
+#option platform cygwin|msys|mingw|mswin
 #option nodynamic
 
 Win32API
diff -Naur ruby-2.7.0-orig/ext/socket/extconf.rb ruby-2.7.0/ext/socket/extconf.rb
--- ruby-2.7.0-orig/ext/socket/extconf.rb	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/ext/socket/extconf.rb	2020-03-25 10:10:58.133777000 +0300
@@ -254,7 +254,7 @@
     # [ruby-dev:44189]
     # http://bugs.ruby-lang.org/issues/5075
     close_fds = false
-  when /cygwin/
+  when /cygwin|msys/
     # Cygwin doesn't support fd passing.
     # http://cygwin.com/ml/cygwin/2003-09/msg01808.html
     close_fds = false
@@ -435,7 +435,7 @@
   test_func = "WSACleanup"
   have_library("iphlpapi")
   have_library("ws2_32", "WSACleanup", headers)
-when /cygwin/
+when /cygwin|msys/
   test_func = "socket(0,0,0)"
 when /haiku/
   test_func = "socket(0,0,0)"
diff -Naur ruby-2.7.0-orig/ext/win32/extconf.rb ruby-2.7.0/ext/win32/extconf.rb
--- ruby-2.7.0-orig/ext/win32/extconf.rb	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/ext/win32/extconf.rb	2020-03-25 10:10:58.274365900 +0300
@@ -1,4 +1,4 @@
 # frozen_string_literal: false
-if $mswin||$mingw||$cygwin
+if $mswin||$mingw||$cygwin||$msys
   create_makefile('win32')
 end
diff -Naur ruby-2.7.0-orig/ext/win32ole/extconf.rb ruby-2.7.0/ext/win32ole/extconf.rb
--- ruby-2.7.0-orig/ext/win32ole/extconf.rb	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/ext/win32ole/extconf.rb	2020-03-25 10:10:58.430576900 +0300
@@ -6,7 +6,7 @@
 require 'mkmf'
 
 case RUBY_PLATFORM
-when /cygwin/
+when /cygwin|msys/
   inc = nil
   lib = '/usr/lib/w32api'
 end
diff -Naur ruby-2.7.0-orig/gems/rake-13.0.1/lib/rake/application.rb ruby-2.7.0/gems/rake-13.0.1/lib/rake/application.rb
--- ruby-2.7.0-orig/gems/rake-13.0.1/lib/rake/application.rb	2019-12-25 12:51:00.000000000 +0300
+++ ruby-2.7.0/gems/rake-13.0.1/lib/rake/application.rb	2020-03-25 10:12:22.860786000 +0300
@@ -360,7 +360,7 @@
 
     def unix? # :nodoc:
       RbConfig::CONFIG["host_os"] =~
-        /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i
+        /(aix|darwin|linux|(net|free|open)bsd|cygwin|msys|solaris|irix|hpux)/i
     end
 
     def windows? # :nodoc:
diff -Naur ruby-2.7.0-orig/lib/bundler/vendor/thor/lib/thor/shell/basic.rb ruby-2.7.0/lib/bundler/vendor/thor/lib/thor/shell/basic.rb
--- ruby-2.7.0-orig/lib/bundler/vendor/thor/lib/thor/shell/basic.rb	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/lib/bundler/vendor/thor/lib/thor/shell/basic.rb	2020-03-25 10:22:17.134876300 +0300
@@ -404,7 +404,7 @@
       end
 
       def unix?
-        RUBY_PLATFORM =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i
+        RUBY_PLATFORM =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|msys|solaris|irix|hpux)/i
       end
 
       def truncate(string, width)
diff -Naur ruby-2.7.0-orig/lib/mkmf.rb ruby-2.7.0/lib/mkmf.rb
--- ruby-2.7.0-orig/lib/mkmf.rb	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/lib/mkmf.rb	2020-03-25 10:11:00.664421300 +0300
@@ -137,6 +137,7 @@
   $mswin = /mswin/ =~ RUBY_PLATFORM
   $mingw = /mingw/ =~ RUBY_PLATFORM
   $cygwin = /cygwin/ =~ RUBY_PLATFORM
+  $msys = /msys/ =~ RUBY_PLATFORM
   $netbsd = /netbsd/ =~ RUBY_PLATFORM
   $haiku = /haiku/ =~ RUBY_PLATFORM
   $solaris = /solaris/ =~ RUBY_PLATFORM
@@ -1914,6 +1915,12 @@
           IO.popen(["cygpath", "-u", path], &:read).chomp
         end
       end
+    when 'msys'
+      if CONFIG['target_os'] != 'msys'
+        def mkintpath(path)
+          IO.popen(["cygpath", "-u", path], &:read).chomp
+        end
+      end
     end
   end
   unless method_defined?(:mkintpath)
@@ -1930,7 +1937,7 @@
 SHELL = /bin/sh
 
 # V=0 quiet, V=1 verbose.  other values don't work.
-V = 0
+V = 1
 Q1 = $(V:1=)
 Q = $(Q1:0=@)
 ECHO1 = $(V:1=@ #{CONFIG['NULLCMD']})
diff -Naur ruby-2.7.0-orig/lib/resolv.rb ruby-2.7.0/lib/resolv.rb
--- ruby-2.7.0-orig/lib/resolv.rb	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/lib/resolv.rb	2020-03-25 10:12:55.616021000 +0300
@@ -166,7 +166,7 @@
   # Resolv::Hosts is a hostname resolver that uses the system hosts file.
 
   class Hosts
-    if /mswin|mingw|cygwin/ =~ RUBY_PLATFORM and
+    if /mswin|mingw|cygwin|msys/ =~ RUBY_PLATFORM and
       begin
         require 'win32/resolv'
         DefaultFileName = Win32::Resolv.get_hosts_path || IO::NULL
@@ -988,7 +988,7 @@
         if File.exist? filename
           config_hash = Config.parse_resolv_conf(filename)
         else
-          if /mswin|cygwin|mingw|bccwin/ =~ RUBY_PLATFORM
+          if /mswin|bccwin/ =~ RUBY_PLATFORM
             require 'win32/resolv'
             search, nameserver = Win32::Resolv.get_resolv_info
             config_hash = {}
diff -Naur ruby-2.7.0-orig/lib/rubygems/platform.rb ruby-2.7.0/lib/rubygems/platform.rb
--- ruby-2.7.0-orig/lib/rubygems/platform.rb	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/lib/rubygems/platform.rb	2020-03-25 10:11:01.351745800 +0300
@@ -79,6 +79,7 @@
       @os, @version = case os
                       when /aix(\d+)?/ then             [ 'aix',       $1  ]
                       when /cygwin/ then                [ 'cygwin',    nil ]
+                      when /msys/ then                  [ 'msys',      nil ]
                       when /darwin(\d+)?/ then          [ 'darwin',    $1  ]
                       when /^macruby$/ then             [ 'macruby',   nil ]
                       when /freebsd(\d+)?/ then         [ 'freebsd',   $1  ]
diff -Naur ruby-2.7.0-orig/spec/ruby/core/dir/chroot_spec.rb ruby-2.7.0/spec/ruby/core/dir/chroot_spec.rb
--- ruby-2.7.0-orig/spec/ruby/core/dir/chroot_spec.rb	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/spec/ruby/core/dir/chroot_spec.rb	2020-03-25 10:24:39.004292600 +0300
@@ -9,7 +9,7 @@
     end
   end
 
-  platform_is_not :cygwin, :android do
+  platform_is_not :cygwin, :msys, :android do
     as_user do
       describe "Dir.chroot as regular user" do
         before :all do
@@ -37,7 +37,7 @@
     end
   end
 
-  platform_is :cygwin do
+  platform_is :cygwin, :msys do
     as_user do
       describe "Dir.chroot as regular user" do
         it_behaves_like :dir_chroot_as_root, :chroot
diff -Naur ruby-2.7.0-orig/test/dbm/test_dbm.rb ruby-2.7.0/test/dbm/test_dbm.rb
--- ruby-2.7.0-orig/test/dbm/test_dbm.rb	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/test/dbm/test_dbm.rb	2020-03-25 10:11:01.492337400 +0300
@@ -15,7 +15,7 @@
     def TestDBM_RDONLY.uname_s
       require 'rbconfig'
       case RbConfig::CONFIG['target_os']
-      when 'cygwin'
+      when 'cygwin', 'msys'
 	require 'etc'
 	Etc.uname[:sysname]
       else
diff -Naur ruby-2.7.0-orig/test/fiddle/helper.rb ruby-2.7.0/test/fiddle/helper.rb
--- ruby-2.7.0-orig/test/fiddle/helper.rb	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/test/fiddle/helper.rb	2020-03-25 10:13:45.528727200 +0300
@@ -10,6 +10,9 @@
 when /cygwin/
   libc_so = "cygwin1.dll"
   libm_so = "cygwin1.dll"
+when /msys/
+  libc_so = "msys-2.0.dll"
+  libm_so = "msys-2.0.dll"
 when /android/
   libdir = '/system/lib'
   if [0].pack('L!').size == 8
diff -Naur ruby-2.7.0-orig/test/fiddle/test_handle.rb ruby-2.7.0/test/fiddle/test_handle.rb
--- ruby-2.7.0-orig/test/fiddle/test_handle.rb	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/test/fiddle/test_handle.rb	2020-03-25 10:11:01.773512800 +0300
@@ -164,7 +164,7 @@
       assert_no_memory_leak(%w[-W0 -rfiddle.so], '', '100_000.times {Fiddle::Handle.allocate}; GC.start', rss: true)
     end
 
-    if /cygwin|mingw|mswin/ =~ RUBY_PLATFORM
+    if /cygwin|msys|mingw|mswin/ =~ RUBY_PLATFORM
       def test_fallback_to_ansi
         k = Fiddle::Handle.new("kernel32.dll")
         ansi = k["GetFileAttributesA"]
diff -Naur ruby-2.7.0-orig/test/fileutils/test_fileutils.rb ruby-2.7.0/test/fileutils/test_fileutils.rb
--- ruby-2.7.0-orig/test/fileutils/test_fileutils.rb	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/test/fileutils/test_fileutils.rb	2020-03-25 10:26:29.920130500 +0300
@@ -76,7 +76,7 @@
     end
 
     @@no_broken_symlink = false
-    if /cygwin/ =~ RUBY_PLATFORM and /\bwinsymlinks:native(?:strict)?\b/ =~ ENV["CYGWIN"]
+    if /cygwin|msys/ =~ RUBY_PLATFORM and /\bwinsymlinks:native(?:strict)?\b/ =~ ENV["CYGWIN"]
       @@no_broken_symlink = true
     end
 
@@ -85,7 +85,7 @@
     end
 
     def root_in_posix?
-      if /cygwin/ =~ RUBY_PLATFORM
+      if /cygwin|msys/ =~ RUBY_PLATFORM
         # FIXME: privilege if groups include root user?
         return Process.groups.include?(0)
       end
@@ -1045,9 +1045,9 @@
     mkdir_p '/'
   end
 
-  if /mswin|mingw|cygwin/ =~ RUBY_PLATFORM
+  if /mswin|mingw|cygwin|msys/ =~ RUBY_PLATFORM
     def test_mkdir_p_root
-      if /cygwin/ =~ RUBY_PLATFORM
+      if /cygwin|msys/ =~ RUBY_PLATFORM
         tmpdir = `cygpath -ma .`.chomp
       else
         tmpdir = Dir.pwd
diff -Naur ruby-2.7.0-orig/test/gdbm/test_gdbm.rb ruby-2.7.0/test/gdbm/test_gdbm.rb
--- ruby-2.7.0-orig/test/gdbm/test_gdbm.rb	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/test/gdbm/test_gdbm.rb	2020-03-25 10:11:02.060234800 +0300
@@ -16,6 +16,9 @@
       case RbConfig::CONFIG['target_os']
       when 'cygwin'
         require 'etc'
+	Etc.uname[:sysname
+      when 'msys'
+        require 'etc'
 	Etc.uname[:sysname]
       else
         RbConfig::CONFIG['target_os']
diff -Naur ruby-2.7.0-orig/test/ruby/test_argf.rb ruby-2.7.0/test/ruby/test_argf.rb
--- ruby-2.7.0-orig/test/ruby/test_argf.rb	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/test/ruby/test_argf.rb	2020-03-25 10:11:02.185235900 +0300
@@ -54,7 +54,7 @@
   end
 
   def no_safe_rename
-    /cygwin|mswin|mingw|bccwin/ =~ RUBY_PLATFORM
+    /cygwin|msys|mswin|mingw|bccwin/ =~ RUBY_PLATFORM
   end
 
   def assert_src_expected(src, args = nil, line: caller_locations(1, 1)[0].lineno+1)
diff -Naur ruby-2.7.0-orig/test/ruby/test_dir_m17n.rb ruby-2.7.0/test/ruby/test_dir_m17n.rb
--- ruby-2.7.0-orig/test/ruby/test_dir_m17n.rb	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/test/ruby/test_dir_m17n.rb	2020-03-25 10:11:02.341414800 +0300
@@ -22,7 +22,7 @@
         assert_include(ents, filename)
       EOS
 
-      return if /cygwin/ =~ RUBY_PLATFORM
+      return if /cygwin|msys/ =~ RUBY_PLATFORM
       assert_separately(%w[-EASCII-8BIT], <<-EOS, :chdir=>dir)
         filename = #{code}.chr('UTF-8').force_encoding("ASCII-8BIT")
         opts = {:encoding => Encoding.default_external} if /mswin|mingw/ =~ RUBY_PLATFORM
@@ -59,7 +59,7 @@
   end
 
   def test_filename_extutf8_invalid
-    return if /cygwin/ =~ RUBY_PLATFORM
+    return if /cygwin|msys/ =~ RUBY_PLATFORM
     # High Sierra's APFS cannot use invalid filenames
     return if Bug::File::Fs.fsname(Dir.tmpdir) == "apfs"
     with_tmpdir {|d|
@@ -177,7 +177,7 @@
   ## others
 
   def test_filename_bytes_euc_jp
-    return if /cygwin/ =~ RUBY_PLATFORM
+    return if /cygwin|msys/ =~ RUBY_PLATFORM
     with_tmpdir {|d|
       assert_separately(%w[-EEUC-JP], <<-'EOS', :chdir=>d)
         filename = "\xA4\xA2".force_encoding("euc-jp")
@@ -194,7 +194,7 @@
   end
 
   def test_filename_euc_jp
-    return if /cygwin/ =~ RUBY_PLATFORM
+    return if /cygwin|msys/ =~ RUBY_PLATFORM
     with_tmpdir {|d|
       assert_separately(%w[-EEUC-JP], <<-'EOS', :chdir=>d)
         filename = "\xA4\xA2".force_encoding("euc-jp")
@@ -240,7 +240,7 @@
   end
 
   def test_filename_ext_euc_jp_and_int_utf_8
-    return if /cygwin/ =~ RUBY_PLATFORM
+    return if /cygwin|msys/ =~ RUBY_PLATFORM
     with_tmpdir {|d|
       assert_separately(%w[-EEUC-JP], <<-'EOS', :chdir=>d)
         filename = "\xA4\xA2".force_encoding("euc-jp")
diff -Naur ruby-2.7.0-orig/test/ruby/test_file.rb ruby-2.7.0/test/ruby/test_file.rb
--- ruby-2.7.0-orig/test/ruby/test_file.rb	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/test/ruby/test_file.rb	2020-03-25 10:27:57.461757900 +0300
@@ -499,7 +499,7 @@
     assert_file.not_absolute_path?("~")
     assert_file.not_absolute_path?("~user")
 
-    if /cygwin|mswin|mingw/ =~ RUBY_PLATFORM
+    if /cygwin|msys|mswin|mingw/ =~ RUBY_PLATFORM
       assert_file.absolute_path?("C:\\foo\\bar")
       assert_file.absolute_path?("C:/foo/bar")
     else
diff -Naur ruby-2.7.0-orig/test/ruby/test_file_exhaustive.rb ruby-2.7.0/test/ruby/test_file_exhaustive.rb
--- ruby-2.7.0-orig/test/ruby/test_file_exhaustive.rb	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/test/ruby/test_file_exhaustive.rb	2020-03-25 10:11:02.482004000 +0300
@@ -7,7 +7,7 @@
 
 class TestFileExhaustive < Test::Unit::TestCase
   DRIVE = Dir.pwd[%r'\A(?:[a-z]:|//[^/]+/[^/]+)'i]
-  POSIX = /cygwin|mswin|bccwin|mingw|emx/ !~ RUBY_PLATFORM
+  POSIX = /cygwin|msys|mswin|bccwin|mingw|emx/ !~ RUBY_PLATFORM
   NTFS = !(/mingw|mswin|bccwin/ !~ RUBY_PLATFORM)
 
   def assert_incompatible_encoding
@@ -1480,7 +1480,7 @@
     assert_equal(true, test(?=, fn1, fn1))
     assert_equal(false, test(?>, fn1, fn1))
     assert_equal(false, test(?<, fn1, fn1))
-    unless /cygwin/ =~ RUBY_PLATFORM
+    unless /cygwin|msys/ =~ RUBY_PLATFORM
       assert_equal(false, test(?=, fn1, fn2))
       assert_equal(false, test(?>, fn1, fn2))
       assert_equal(true, test(?>, fn2, fn1))
diff -Naur ruby-2.7.0-orig/test/ruby/test_io.rb ruby-2.7.0/test/ruby/test_io.rb
--- ruby-2.7.0-orig/test/ruby/test_io.rb	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/test/ruby/test_io.rb	2020-03-25 10:11:02.888151800 +0300
@@ -1468,7 +1468,7 @@
       t.value
       assert_equal("", s)
     end
-  end if /cygwin/ !~ RUBY_PLATFORM
+  end if /cygwin|msys/ !~ RUBY_PLATFORM
 
   def test_read
     pipe(proc do |w|
@@ -1521,7 +1521,7 @@
       t.value
       assert_equal("xxx", s)
     end
-  end if /cygwin/ !~ RUBY_PLATFORM
+  end if /cygwin|msys/ !~ RUBY_PLATFORM
 
   def test_write_nonblock
     pipe(proc do |w|
@@ -3544,7 +3544,7 @@
       assert_nothing_raised(RuntimeError, bug8669) { str.clear }
       t.join
     }
-  end if /cygwin/ !~ RUBY_PLATFORM
+  end if /cygwin|msys/ !~ RUBY_PLATFORM
 
   def test_readpartial_unlocktmp_ensure
     bug8669 = '[ruby-core:56121] [Bug #8669]'
@@ -3562,7 +3562,7 @@
       assert_nothing_raised(RuntimeError, bug8669) { str.clear }
       t.join
     }
-  end if /cygwin/ !~ RUBY_PLATFORM
+  end if /cygwin|msys/ !~ RUBY_PLATFORM
 
   def test_readpartial_bad_args
     IO.pipe do |r, w|
@@ -3591,7 +3591,7 @@
       assert_nothing_raised(RuntimeError, bug8669) { str.clear }
       t.join
     }
-  end if /cygwin/ !~ RUBY_PLATFORM
+  end if /cygwin|msys/ !~ RUBY_PLATFORM
 
   def test_exception_at_close
     bug10153 = '[ruby-core:64463] [Bug #10153] exception in close at the end of block'
@@ -3632,7 +3632,7 @@
         assert_equal("foo", t1_value)
       EOS
     }
-  end if /mswin|mingw|bccwin|cygwin/ !~ RUBY_PLATFORM
+  end if /mswin|mingw|bccwin|cygwin|msys/ !~ RUBY_PLATFORM
 
   def test_open_flag
     make_tempfile do |t|
diff -Naur ruby-2.7.0-orig/test/ruby/test_path.rb ruby-2.7.0/test/ruby/test_path.rb
--- ruby-2.7.0-orig/test/ruby/test_path.rb	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/test/ruby/test_path.rb	2020-03-25 10:11:03.153740900 +0300
@@ -48,7 +48,7 @@
   end
 
   def test_dirname
-    if /(bcc|ms)win\d|mingw|cygwin|emx/ =~ RUBY_PLATFORM
+    if /(bcc|ms)win\d|mingw|cygwin|msys|emx/ =~ RUBY_PLATFORM
       # DOSISH_DRIVE_LETTER
       assert_equal('C:.', File.dirname('C:'))
       assert_equal('C:.', File.dirname('C:a'))
@@ -104,7 +104,7 @@
     assert_equal('/', File.dirname('/a/'))
     assert_equal('/a', File.dirname('/a/b'))
 
-    if /(bcc|ms|cyg)win|mingw|emx/ =~ RUBY_PLATFORM
+    if /(bcc|ms|cyg)win|msys|mingw|emx/ =~ RUBY_PLATFORM
       # DOSISH_UNC
       assert_equal('//', File.dirname('//'))
       assert_equal('//a', File.dirname('//a'))
@@ -138,7 +138,7 @@
   end
 
   def test_basename
-    if /(bcc|ms)win\d|mingw|cygwin|emx/ =~ RUBY_PLATFORM
+    if /(bcc|ms)win\d|mingw|cygwin|msys|emx/ =~ RUBY_PLATFORM
       # DOSISH_DRIVE_LETTER
       assert_equal('', File.basename('C:'))
       assert_equal('a', File.basename('C:a'))
@@ -194,7 +194,7 @@
 
     assert_equal("..", File.basename("..", ".*"))
 
-    if /(bcc|ms|cyg)win|mingw|emx/ =~ RUBY_PLATFORM
+    if /(bcc|ms|cyg)win|msys|mingw|emx/ =~ RUBY_PLATFORM
       # DOSISH_UNC
       assert_equal('/', File.basename('//'))
       assert_equal('/', File.basename('//a'))
diff -Naur ruby-2.7.0-orig/test/ruby/test_require.rb ruby-2.7.0/test/ruby/test_require.rb
--- ruby-2.7.0-orig/test/ruby/test_require.rb	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/test/ruby/test_require.rb	2020-03-25 10:11:03.294299200 +0300
@@ -77,7 +77,7 @@
   end
 
   case RUBY_PLATFORM
-  when /cygwin/, /mswin/, /mingw/, /darwin/
+  when /cygwin/, /msys/, /mswin/, /mingw/, /darwin/
     def self.ospath_encoding(path)
       Encoding::UTF_8
     end
diff -Naur ruby-2.7.0-orig/test/ruby/test_rubyoptions.rb ruby-2.7.0/test/ruby/test_rubyoptions.rb
--- ruby-2.7.0-orig/test/ruby/test_rubyoptions.rb	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/test/ruby/test_rubyoptions.rb	2020-03-25 10:11:03.669235700 +0300
@@ -907,7 +907,7 @@
         assert_e_script_encoding(s, %W[-E#{locale.name}])
       end
     end
-  when /cygwin/
+  when /cygwin|msys/
     def test_command_line_non_ascii
       assert_separately([{"LC_ALL"=>"ja_JP.SJIS"}, "-", "\u{3042}".encode("SJIS")], <<-"end;")
         bug12184 = '[ruby-dev:49519] [Bug #12184]'
diff -Naur ruby-2.7.0-orig/test/rubygems/test_gem_platform.rb ruby-2.7.0/test/rubygems/test_gem_platform.rb
--- ruby-2.7.0-orig/test/rubygems/test_gem_platform.rb	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/test/rubygems/test_gem_platform.rb	2020-03-25 10:17:17.208435300 +0300
@@ -46,6 +46,7 @@
       'universal-darwin9'      => ['universal', 'darwin',    '9'],
       'universal-macruby'      => ['universal', 'macruby',   nil],
       'i386-cygwin'            => ['x86',       'cygwin',    nil],
+      'i386-msys'              => ['x86',       'msys',      nil],
       'i686-darwin'            => ['x86',       'darwin',    nil],
       'i686-darwin8.4.1'       => ['x86',       'darwin',    '8'],
       'i386-freebsd4.11'       => ['x86',       'freebsd',   '4'],
@@ -76,6 +77,7 @@
       'i386-solaris2.8'        => ['x86',       'solaris',   '2.8'],
       'mswin32'                => ['x86',       'mswin32',   nil],
       'x86_64-linux'           => ['x86_64',    'linux',     nil],
+      'x86_64-msys'            => ['x86_64',    'msys',      nil],
       'x86_64-linux-musl'      => ['x86_64',    'linux',     'musl'],
       'x86_64-openbsd3.9'      => ['x86_64',    'openbsd',   '3.9'],
       'x86_64-openbsd4.0'      => ['x86_64',    'openbsd',   '4.0'],
diff -Naur ruby-2.7.0-orig/test/socket/test_addrinfo.rb ruby-2.7.0/test/socket/test_addrinfo.rb
--- ruby-2.7.0-orig/test/socket/test_addrinfo.rb	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/test/socket/test_addrinfo.rb	2020-03-25 10:11:04.356531400 +0300
@@ -8,7 +8,7 @@
 require "test/unit"
 
 class TestSocketAddrinfo < Test::Unit::TestCase
-  HAS_UNIXSOCKET = defined?(UNIXSocket) && /cygwin/ !~ RUBY_PLATFORM
+  HAS_UNIXSOCKET = defined?(UNIXSocket) && /cygwin|msys/ !~ RUBY_PLATFORM
 
   def tcp_unspecified_to_loopback(addrinfo)
     if addrinfo.ipv4? && addrinfo.ip_address == "0.0.0.0"
diff -Naur ruby-2.7.0-orig/test/socket/test_unix.rb ruby-2.7.0/test/socket/test_unix.rb
--- ruby-2.7.0-orig/test/socket/test_unix.rb	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/test/socket/test_unix.rb	2020-03-25 10:11:04.487651700 +0300
@@ -708,4 +708,4 @@
       assert_equal :wait_readable, serv.accept_nonblock(exception: false)
     }
   end
-end if defined?(UNIXSocket) && /cygwin/ !~ RUBY_PLATFORM
+end if defined?(UNIXSocket) && /cygwin|msys/ !~ RUBY_PLATFORM
diff -Naur ruby-2.7.0-orig/test/webrick/test_cgi.rb ruby-2.7.0/test/webrick/test_cgi.rb
--- ruby-2.7.0-orig/test/webrick/test_cgi.rb	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/test/webrick/test_cgi.rb	2020-03-25 10:11:04.612649100 +0300
@@ -26,7 +26,7 @@
         end
       },
     }
-    if RUBY_PLATFORM =~ /mswin|mingw|cygwin|bccwin32/
+    if RUBY_PLATFORM =~ /mswin|mingw|cygwin|msys|bccwin32/
       config[:CGIPathEnv] = ENV['PATH'] # runtime dll may not be in system dir.
     end
     TestWEBrick.start_httpserver(config, log_tester){|server, addr, port, log|
@@ -43,7 +43,7 @@
       http.request(req){|res| assert_equal("/path/info", res.body, log.call)}
       req = Net::HTTP::Get.new("/webrick.cgi/%3F%3F%3F?foo=bar")
       http.request(req){|res| assert_equal("/???", res.body, log.call)}
-      unless RUBY_PLATFORM =~ /mswin|mingw|cygwin|bccwin32/
+      unless RUBY_PLATFORM =~ /mswin|mingw|cygwin|msys|bccwin32/
         # Path info of res.body is passed via ENV.
         # ENV[] returns different value on Windows depending on locale.
         req = Net::HTTP::Get.new("/webrick.cgi/%A4%DB%A4%B2/%A4%DB%A4%B2")
diff -Naur ruby-2.7.0-orig/tool/config.guess ruby-2.7.0/tool/config.guess
--- ruby-2.7.0-orig/tool/config.guess	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/tool/config.guess	2020-03-25 10:11:04.753241400 +0300
@@ -899,6 +899,9 @@
     amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
 	echo x86_64-pc-cygwin
 	exit ;;
+    amd64:MSYS*:*:* | x86_64:MSYS*:*:*)
+	echo x86_64-unknown-msys
+	exit ;;
     prep*:SunOS:5.*:*)
 	echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
 	exit ;;
diff -Naur ruby-2.7.0-orig/tool/downloader.rb ruby-2.7.0/tool/downloader.rb
--- ruby-2.7.0-orig/tool/downloader.rb	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/tool/downloader.rb	2020-03-25 10:11:05.018798000 +0300
@@ -263,7 +263,7 @@
   def self.link_cache(cache, file, name, verbose = false)
     return false unless cache and cache.exist?
     return true if cache.eql?(file)
-    if /cygwin/ !~ RUBY_PLATFORM or /winsymlink:nativestrict/ =~ ENV['CYGWIN']
+    if /cygwin|msys/ !~ RUBY_PLATFORM or /winsymlink:nativestrict/ =~ ENV['CYGWIN']
       begin
         file.make_symlink(cache.relative_path_from(file.parent))
       rescue SystemCallError
diff -Naur ruby-2.7.0-orig/tool/m4/ruby_mingw32.m4 ruby-2.7.0/tool/m4/ruby_mingw32.m4
--- ruby-2.7.0-orig/tool/m4/ruby_mingw32.m4	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/tool/m4/ruby_mingw32.m4	2020-03-25 10:11:05.284360400 +0300
@@ -1,7 +1,7 @@
 # -*- Autoconf -*-
 AC_DEFUN([RUBY_MINGW32],
 [AS_CASE(["$host_os"],
-[cygwin*], [
+[cygwin*|msys*], [
 AC_CACHE_CHECK(for mingw32 environment, rb_cv_mingw32,
 [AC_TRY_CPP([
 #ifndef __MINGW32__
diff -Naur ruby-2.7.0-orig/tool/m4/ruby_setjmp_type.m4 ruby-2.7.0/tool/m4/ruby_setjmp_type.m4
--- ruby-2.7.0-orig/tool/m4/ruby_setjmp_type.m4	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/tool/m4/ruby_setjmp_type.m4	2020-03-25 10:11:05.440650300 +0300
@@ -35,7 +35,7 @@
     setjmp_prefix=_
     setjmp_suffix=
 ], [test "$ac_cv_func_sigsetjmp" = yes], [
-    AS_CASE([$target_os],[solaris*|cygwin*],[setjmp_prefix=],[setjmp_prefix=sig])
+    AS_CASE([$target_os],[solaris*|cygwin*|msys*],[setjmp_prefix=],[setjmp_prefix=sig])
     setjmp_suffix=
 ], [
     setjmp_prefix=
diff -Naur ruby-2.7.0-orig/win32/mkexports.rb ruby-2.7.0/win32/mkexports.rb
--- ruby-2.7.0-orig/win32/mkexports.rb	2019-12-25 12:50:58.000000000 +0300
+++ ruby-2.7.0/win32/mkexports.rb	2020-03-25 10:31:46.456989400 +0300
@@ -167,6 +167,30 @@
   end
 end
 
+class Exports::Msys < Exports
+  def self.nm
+    @@nm ||= RbConfig::CONFIG["NM"]
+  end
+
+  def exports(*)
+    super()
+  end
+
+  def each_line(objs, &block)
+    IO.foreach("|#{self.class.nm} --extern --defined #{objs.join(' ')}", &block)
+  end
+
+  def each_export(objs)
+    symprefix = RbConfig::CONFIG["SYMBOL_PREFIX"]
+    symprefix.strip! if symprefix
+    re = /\s(?:(T)|[[:upper:]])\s#{symprefix}((?!#{PrivateNames}).*)$/
+    objdump(objs) do |l|
+      next if /@.*@/ =~ l
+      yield $2, !$1 if re =~ l
+    end
+  end
+end
+
 class Exports::Mingw < Exports::Cygwin
   def each_export(objs)
     super
