diff --git a/lib/mkmf.rb b/lib/mkmf.rb
index 946885f054..e7368df182 100644
--- a/lib/mkmf.rb
+++ b/lib/mkmf.rb
@@ -483,6 +483,23 @@ def link_command(ldflags, opt="", libpath=$DEFLIBPATH|$LIBPATH)
     RbConfig::expand(TRY_LINK.dup, conf)
   end
 
+  def link_shared_command(ldflags, opt="", libpath=$DEFLIBPATH|$LIBPATH)
+    librubyarg = $extmk ? $LIBRUBYARG_SHARED : "$(LIBRUBYARG_SHARED)"
+    conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote,
+                                  'src' => "#{CONFTEST_C}",
+                                  'arch_hdrdir' => $arch_hdrdir.quote,
+                                  'top_srcdir' => $top_srcdir.quote,
+                                  'INCFLAGS' => "#$INCFLAGS",
+                                  'CPPFLAGS' => "#$CPPFLAGS",
+                                  'CFLAGS' => "#{CONFIG['CCDLFLAGS']} #$CFLAGS",
+                                  'ARCH_FLAG' => "#$ARCH_FLAG",
+                                  'DLDFLAGS' => "#$DLDFLAGS #{CONFIG['EXTDLDFLAGS']} #{ldflags}",
+                                  'LOCAL_LIBS' => "#$LOCAL_LIBS #$libs",
+                                  'LIBS' => "#{librubyarg} #{opt} #$LIBS")
+    conf['LIBPATH'] = libpathflag(libpath.map {|s| RbConfig::expand(s.dup, conf)})
+    RbConfig::expand(TRY_LINK_SHARED.dup, conf)
+  end
+
   def cc_command(opt="")
     conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote,
                                   'arch_hdrdir' => $arch_hdrdir.quote,
@@ -545,6 +562,27 @@ def try_link0(src, opt="", *opts, &b) # :nodoc:
     MakeMakefile.rm_rf(*Dir["#{CONFTEST}*"]-[exe])
   end
 
+  def try_link0_shared(src, opt="", *opts, &b) # :nodoc:
+    so = "#{CONFTEST}.#{CONFIG['DLEXT']}"
+    cmd = link_shared_command("", opt)
+    if $universal
+      require 'tmpdir'
+      Dir.mktmpdir("mkmf_", oldtmpdir = ENV["TMPDIR"]) do |tmpdir|
+        begin
+          ENV["TMPDIR"] = tmpdir
+          try_do(src, cmd, *opts, &b)
+        ensure
+          ENV["TMPDIR"] = oldtmpdir
+        end
+      end
+    else
+      try_do(src, cmd, *opts, &b)
+    end and File.file?(so) or return nil
+    so
+  ensure
+    MakeMakefile.rm_rf(*Dir["#{CONFTEST}*"]-[so])
+  end
+
   # Returns whether or not the +src+ can be compiled as a C source and linked
   # with its depending libraries successfully.  +opt+ is passed to the linker
   # as options. Note that +$CFLAGS+ and +$LDFLAGS+ are also passed to the
@@ -657,7 +695,20 @@ def with_ldflags(flags)
   end
 
   def try_ldflags(flags, opts = {})
-    try_link(MAIN_DOES_NOTHING, flags, {:werror => true}.update(opts))
+    if CROSS_COMPILING
+      try_link(MAIN_DOES_NOTHING, flags, {:werror => true}.update(opts))
+    elsif $static.nil?
+      try_run_shared(<<SRC, flags)
+#include "#{$hdrdir}/ruby.h"
+/*top*/
+void Init_conftest(void)
+{
+  rb_define_global_const("MKMF_CONFTEST", INT2FIX(42));
+}
+SRC
+    else
+      try_run(MAIN_DOES_NOTHING, flags)
+    end
   end
 
   def append_ldflags(flags, *opts)
@@ -875,6 +926,25 @@ def try_run(src, opt = "", &b)
     MakeMakefile.rm_f "#{CONFTEST}*"
   end
 
+  def try_run_shared(src, opt = "", &b) # :nodoc:
+    if CROSS_COMPILING
+      raise "cannot run test shared library extension while cross compiling"
+    end
+
+    unless $static.nil?
+      raise "cannot run test shared library extension with static link configuration"
+    end
+
+    if try_link0_shared(src, opt, &b)
+      conftest = Shellwords.escape(File.absolute_path(CONFTEST))
+      xsystem(RbConfig::expand(%{#{$ruby} -r#{conftest}.$(DLEXT) -e "exit(MKMF_CONFTEST == 42)"}))
+    else
+      nil
+    end
+  ensure
+    MakeMakefile.rm_f "#{CONFTEST}*"
+  end
+
   def install_files(mfile, ifiles, map = nil, srcprefix = nil)
     ifiles or return
     ifiles.empty? and return
@@ -2683,6 +2753,10 @@ def MAIN_DOES_NOTHING(*refs)
     "$(CC) #{OUTFLAG}#{CONFTEST}#{$EXEEXT} $(INCFLAGS) $(CPPFLAGS) " \
     "$(CFLAGS) $(src) $(LIBPATH) $(LDFLAGS) $(ARCH_FLAG) $(LOCAL_LIBS) $(LIBS)"
 
+  TRY_LINK_SHARED = config_string('TRY_LINK_SHARED') ||
+    "$(LDSHARED) #{OUTFLAG}#{CONFTEST}.#{CONFIG['DLEXT']} $(INCFLAGS) $(CPPFLAGS) " \
+    "$(CFLAGS) $(src) $(LIBPATH) $(DLDFLAGS) $(ARCH_FLAG) $(LOCAL_LIBS) $(LIBS)"
+
   ##
   # Command which will link a shared library
 
