* ext/socket/extconf.rb: check if getaddrinfo() works fine only when
  wide-getaddrinfo option is not given.  fixed: [ruby-dev:25422]

* lib/mkmf.rb ($extmk): check if under ext directory.

* lib/mkmf.rb (Logging.postpone): allow recursive operation.

* lib/mkmf.rb (try_constant): make sure if really a constant, reduce
  the number of times of compile.

* lib/mkmf.rb (have_macro, have_var, byte_order): new functions.

* lib/mkmf.rb (find_library): allow directory list with separators.

* lib/mkmf.rb (arg_config): manage provided configuration options.

* lib/mkmf.rb (dir_config): accept arrays of directory names as
  default values.


Index: ext/socket/extconf.rb
===================================================================
RCS file: /cvs/ruby/src/ruby/ext/socket/extconf.rb,v
retrieving revision 1.36
diff -U2 -p -r1.36 extconf.rb
--- ext/socket/extconf.rb	15 Oct 2003 02:25:46 -0000	1.36
+++ ext/socket/extconf.rb	9 Jan 2005 08:43:15 -0000
@@ -25,8 +25,16 @@ else
 end
 
-$ipv6 = false
+unless $mswin or $bccwin or $mingw
+  headers = %w<sys/types.h netdb.h string.h sys/socket.h netinet/in.h>
+end
+if /solaris/ =~ RUBY_PLATFORM and !try_compile("")
+  # bug of gcc 3.0 on Solaris 8 ?
+  headers << "sys/feature_tests.h"
+end
+
+ipv6 = false
 default_ipv6 = /cygwin/ !~ RUBY_PLATFORM
 if enable_config("ipv6", default_ipv6)
-  if try_link(<<EOF)
+  if checking_for("ipv6") {try_link(<<EOF)}
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -36,158 +44,65 @@ main()
 }
 EOF
-    $CFLAGS+=" -DENABLE_IPV6"
-    $ipv6 = true
+    $defs << "-DENABLE_IPV6" << "-DINET6"
+    ipv6 = true
   end
 end
 
-$ipv6type = nil
-$ipv6lib = nil
-$ipv6libdir = nil
-$ipv6trylibc = nil
-if $ipv6
-  if macro_defined?("IPV6_INRIA_VERSION", <<EOF)
-#include <netinet/in.h>
-EOF
-    $ipv6type = "inria"
-    $CFLAGS="-DINET6 "+$CFLAGS
-  elsif macro_defined?("__KAME__", <<EOF)
-#include <netinet/in.h>
-EOF
-    $ipv6type = "kame"
-    $ipv6lib="inet6"
-    $ipv6libdir="/usr/local/v6/lib"
-    $ipv6trylibc=true
-    $CFLAGS="-DINET6 "+$CFLAGS
-  elsif File.directory? "/usr/inet6"
-    $ipv6type = "linux"
-    $ipv6lib="inet6"
-    $ipv6libdir="/usr/inet6/lib"
-    $CFLAGS="-DINET6 -I/usr/inet6/include "+$CFLAGS
-  elsif macro_defined?("_TOSHIBA_INET6", <<EOF)
-#include <sys/param.h>
-EOF
-    $ipv6type = "toshiba"
-    $ipv6lib="inet6"
-    $ipv6libdir="/usr/local/v6/lib"
-    $CFLAGS="-DINET6 "+$CFLAGS
-  elsif macro_defined?("__V6D__", <<EOF)
-#include </usr/local/v6/include/sys/v6config.h>
-EOF
-    $ipv6type = "v6d"
-    $ipv6lib="v6"
-    $ipv6libdir="/usr/local/v6/lib"
-    $CFLAGS="-DINET6 -I/usr/local/v6/include "+$CFLAGS
-  elsif macro_defined?("_ZETA_MINAMI_INET6", <<EOF)
-#include <sys/param.h>
-EOF
-    $ipv6type = "zeta"
-    $ipv6lib="inet6"
-    $ipv6libdir="/usr/local/v6/lib"
-    $CFLAGS="-DINET6 "+$CFLAGS
-  else
-    $ipv6lib=with_config("ipv6-lib", nil)
-    $ipv6libdir=with_config("ipv6-libdir", nil)
-    $CFLAGS="-DINET6 "+$CFLAGS
-  end
-  
-  if $ipv6lib
-    if File.directory? $ipv6libdir and File.exist? "#{$ipv6libdir}/lib#{$ipv6lib}.a"
-      $LOCAL_LIBS = " -L#$ipv6libdir -l#$ipv6lib"
-    elsif !$ipv6trylibc
-      print <<EOS
+if ipv6
+  ipv6lib = nil
+  class << (fmt = Object.new)
+    def %(s) s || "unknown" end
+  end
+  idirs, ldirs = dir_config("inet6", %w[/usr/inet6 /usr/local/v6].find {|d| File.directory?(d)})
+  checking_for("ipv6 type", fmt) do
+    if have_macro("IPV6_INRIA_VERSION", "netinet/in.h")
+      "inria"
+    elsif have_macro("__KAME__", "netinet/in.h")
+      have_library(ipv6lib = "inet6")
+      "kame"
+    elsif have_macro("_TOSHIBA_INET6", "sys/param.h")
+      have_library(ipv6lib = "inet6") and "toshiba"
+    elsif have_macro("__V6D__", "sys/v6config.h")
+      have_library(ipv6lib = "v6") and "v6d"
+    elsif have_macro("_ZETA_MINAMI_INET6", "sys/param.h")
+      have_library(ipv6lib = "inet6") and "zeta"
+    elsif ipv6lib = with_config("ipv6-lib")
+      warn <<EOS
+--with-ipv6-lib and --with-ipv6-libdir option will be obsolete, use
+--with-inet6lib and --with-inet6-{include,lib} options instead.
+EOS
+      find_library(ipv6lib, nil, with_config("ipv6-libdir", ldirs)) and
+        ipv6lib
+    elsif have_library("inet6")
+      "inet6"
+    end
+  end or not ipv6lib or abort <<EOS
 
-Fatal: no #$ipv6lib library found.  cannot continue.
-You need to fetch lib#{$ipv6lib}.a from appropriate
+Fatal: no #{ipv6lib} library found.  cannot continue.
+You need to fetch lib#{ipv6lib}.a from appropriate
 ipv6 kit and compile beforehand.
 EOS
-      exit
-    end
-  end
 end
 
-  if try_link(<<EOF)
-#ifdef _WIN32
-# include <windows.h>
-# include <winsock.h>
-#else
-# include <sys/types.h>
-# include <netdb.h>
-# include <string.h>
-# include <sys/socket.h>
-# include <netinet/in.h>
-#endif
-int
-main()
-{
-   struct sockaddr_in sin;
-
-   sin.sin_len;
-   return 0;
-}
-EOF
-    $CFLAGS="-DHAVE_SIN_LEN "+$CFLAGS
+if have_struct_member("struct sockaddr_in", "sin_len", headers)
+  $defs[-1] = "-DHAVE_SIN_LEN"
 end
 
-  if try_link(<<EOF)
-#ifdef _WIN32
-# include <windows.h>
-# include <winsock.h>
-#else
-# include <sys/types.h>
-# include <netdb.h>
-# include <string.h>
-# include <sys/socket.h>
-#endif
-int
-main()
-{
-   struct sockaddr_storage ss;
-
-   ss.ss_family;
-   return 0;
-}
-EOF
-    $CFLAGS="-DHAVE_SOCKADDR_STORAGE "+$CFLAGS
-else      #   doug's fix, NOW add -Dss_family... only if required!
-$CPPFLAGS += " -Dss_family=__ss_family -Dss_len=__ss_len"
-  if try_link(<<EOF)
-#ifdef _WIN32
-# include <windows.h>
-# include <winsock.h>
-#else
-# include <sys/types.h>
-# include <netdb.h>
-# include <string.h>
-# include <sys/socket.h>
-#endif
-int
-main()
-{
-   struct sockaddr_storage ss;
-
-   ss.ss_family;
-   return 0;
-}
-EOF
-    $CFLAGS="-DHAVE_SOCKADDR_STORAGE "+$CFLAGS
-end
+#   doug's fix, NOW add -Dss_family... only if required!
+[nil, " -Dss_family=__ss_family -Dss_len=__ss_len"].each do |flags|
+  if flags
+    cppflags = $CPPFLAGS
+    $CPPFLAGS += flags
+  end
+  if have_struct_member("struct sockaddr_storage", "ss_family", headers)
+    $defs[-1] = "-DHAVE_SOCKADDR_STORAGE"
+    break
+  elsif flags
+    $CPPFLAGS = cppflags
+  end
 end
 
-  if try_link(<<EOF)
-#include <sys/types.h>
-#include <netdb.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-int
-main()
-{
-   struct sockaddr sa;
-
-   sa.sa_len;
-   return 0;
-}
-EOF
-    $CFLAGS="-DHAVE_SA_LEN "+$CFLAGS
+if have_struct_member("struct sockaddr", "sa_len", headers)
+  $defs[-1] = "-DHAVE_SA_LEN "
 end
 
@@ -200,11 +115,15 @@ if have_func("sendmsg") | have_func("rec
 end
 
-$getaddr_info_ok = false
-if !enable_config("wide-getaddrinfo", false) and try_run(<<EOF)
-#include <sys/types.h>
-#include <netdb.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
+getaddr_info_ok = enable_config("wide-getaddrinfo") do
+  checking_for("wide getaddrinfo") {try_run(<<EOF)}
+#{cpp_include(headers)}
+#include <stdlib.h>
+
+#ifndef EXIT_SUCCESS
+#define EXIT_SUCCESS 0
+#endif
+#ifndef EXIT_FAILURE
+#define EXIT_FAILURE 1
+#endif
 
 #ifndef AF_LOCAL
@@ -282,16 +201,15 @@ main()
   if (aitop)
     freeaddrinfo(aitop);
-  exit(0);
+  exit(EXIT_SUCCESS);
 
  bad:
   if (aitop)
     freeaddrinfo(aitop);
-  exit(1);
+  exit(EXIT_FAILURE);
 }
 EOF
-  $getaddr_info_ok = true
 end
-if $ipv6 and not $getaddr_info_ok
-      print <<EOS
+if ipv6 and not getaddr_info_ok
+  abort <<EOS
 
 Fatal: --enable-ipv6 is specified, and your OS seems to support IPv6 feature.
@@ -300,59 +218,27 @@ you cannot compile IPv6 socket classes w
 You can try --enable-wide-getaddrinfo.
 EOS
-  exit
 end
-      
+
 case with_config("lookup-order-hack", "UNSPEC")
 when "INET"
-  $CFLAGS="-DLOOKUP_ORDER_HACK_INET "+$CFLAGS
+  $defs << "-DLOOKUP_ORDER_HACK_INET"
 when "INET6"
-  $CFLAGS="-DLOOKUP_ORDER_HACK_INET6 "+$CFLAGS
+  $defs << "-DLOOKUP_ORDER_HACK_INET6"
 when "UNSPEC"
   # nothing special
 else
-  print <<EOS
+  abort <<EOS
 
 Fatal: invalid value for --with-lookup-order-hack (expected INET, INET6 or UNSPEC)
 EOS
-  exit
 end
 
 $objs = ["socket.#{$OBJEXT}"]
-    
-if $getaddr_info_ok and have_func("getaddrinfo", "netdb.h") and have_func("getnameinfo", "netdb.h")
-  have_getaddrinfo = true
-else
-  if try_link(<<EOF)
-#ifndef _WIN32
-#  include <sys/types.h>
-#  include <netdb.h>
-#  include <string.h>
-#  include <sys/socket.h>
-#  include <netinet/in.h>
-#else
-#  include <windows.h>
-#  ifdef _WIN32_WCE
-#    include <winsock.h>
-#  else
-#    include <winsock.h>
-#  endif
-#endif
-int
-main()
-{
-   struct in6_addr addr;
-   unsigned char c;
-   c = addr.s6_addr8;
-   return 0;
-}
-EOF
-    $CFLAGS="-DHAVE_ADDR8 "+$CFLAGS
-  end
-end
 
-if have_getaddrinfo
-  $CFLAGS="-DHAVE_GETADDRINFO "+$CFLAGS
-else
-  $CFLAGS="-I. "+$CFLAGS
+unless getaddr_info_ok and have_func("getnameinfo", "netdb.h") and have_func("getaddrinfo", "netdb.h")
+  if have_struct_member("struct in6_addr", "s6_addr8", headers)
+    $defs[-1] = "-DHAVE_ADDR8"
+  end
+  $CPPFLAGS="-I. "+$CPPFLAGS
   $objs += ["getaddrinfo.#{$OBJEXT}"]
   $objs += ["getnameinfo.#{$OBJEXT}"]
@@ -365,18 +251,6 @@ else
 end
 
-if !try_link(<<EOF)
-#include <sys/types.h>
-#include <netdb.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-int
-main()
-{
-   socklen_t len;
-   return 0;
-}
-EOF
-  $CFLAGS="-Dsocklen_t=int "+$CFLAGS
+unless have_type("socklen_t", headers)
+  $defs << "-Dsocklen_t=int"
 end
 
@@ -387,4 +261,5 @@ if have_func(test_func)
   have_func("hsterror")
   have_func("getipnodebyname") or have_func("gethostbyname2")
+  have_func("socketpair")
   unless have_func("gethostname")
     have_func("uname")
@@ -392,7 +267,7 @@ if have_func(test_func)
   if enable_config("socks", ENV["SOCKS_SERVER"])
     if have_library("socks5", "SOCKSinit")
-      $CFLAGS+=" -DSOCKS5 -DSOCKS"
+      $defs << "-DSOCKS5" << "-DSOCKS"
     elsif have_library("socks", "Rconnect")
-      $CFLAGS+=" -DSOCKS"
+      $defs << "-DSOCKS"
     end
   end
Index: lib/mkmf.rb
===================================================================
RCS file: /cvs/ruby/src/ruby/lib/mkmf.rb,v
retrieving revision 1.162.2.19
diff -U2 -p -r1.162.2.19 mkmf.rb
--- lib/mkmf.rb	18 Sep 2004 06:56:36 -0000	1.162.2.19
+++ lib/mkmf.rb	9 Jan 2005 08:48:14 -0000
@@ -79,9 +79,10 @@ def map_dir(dir, map = nil)
 end
 
-libdir = File.dirname(__FILE__)
-$extmk = libdir != Config::CONFIG["rubylibdir"]
+topdir = File.dirname(libdir = File.dirname(__FILE__))
+extdir = File.expand_path("ext", topdir)
+$extmk = File.expand_path($0)[0, extdir.size+1] == extdir+"/"
 if not $extmk and File.exist? Config::CONFIG["archdir"] + "/ruby.h"
   $hdrdir = $topdir = Config::CONFIG["archdir"]
-elsif File.exist? $srcdir + "/ruby.h"
+elsif File.exist?(($top_srcdir ||= topdir)  + "/ruby.h") and
   $topdir = Config::CONFIG["compile_dir"]
   $hdrdir = $srcdir
@@ -137,4 +138,5 @@ module Logging
   @orgerr = $stderr.dup
   @orgout = $stdout.dup
+  @postpone = 0
 
   def self::open
@@ -165,5 +167,5 @@ module Logging
   
   def self::postpone
-    tmplog = "mkmftmp.log"
+    tmplog = "mkmftmp#{@postpone += 1}.log"
     open do
       log, *save = @log, @logfile, @orgout, @orgerr
@@ -175,4 +177,5 @@ module Logging
       ensure
         @log, @logfile, @orgout, @orgerr = log, *save
+        @postpone -= 1
         rm_f tmplog
       end
@@ -294,36 +297,39 @@ def try_static_assert(expr, headers = ni
 #{headers}
 /*top*/
-int tmp[(#{expr}) ? 1 : -1];
+int conftest_const[(#{expr}) ? 1 : -1];
 SRC
 end
 
 def try_constant(const, headers = nil, opt = "", &b)
-  headers = cpp_include(headers)
+  includes = cpp_include(headers)
   if CROSS_COMPILING
-    unless try_compile(<<"SRC", opt, &b)
-#{COMMON_HEADERS}
-#{headers}
-/*top*/
-int tmp = #{const};
-SRC
-      return nil
-    end
-    if try_static_assert("#{const} < 0", headers, opt)
+    if try_static_assert("#{const} > 0", headers, opt)
+      # positive constant
+    elsif try_static_assert("#{const} < 0", headers, opt)
       neg = true
       const = "-(#{const})"
     elsif try_static_assert("#{const} == 0", headers, opt)
       return 0
+    else
+      # not a constant
+      return nil
     end
     upper = 1
-    until try_static_assert("#{const} < #{upper}", headers, opt)
+    until try_static_assert("#{const} <= #{upper}", headers, opt)
       lower = upper
       upper <<= 1
     end
     return nil unless lower
-    until try_static_assert("#{const} == #{upper}", headers, opt)
-      if try_static_assert("#{const} > #{(upper+lower)/2}", headers, opt)
-        lower = (upper+lower)/2
+    while upper > lower + 1
+      mid = (upper + lower) / 2
+      if try_static_assert("#{const} > #{mid}", headers, opt)
+        lower = mid
       else
-        upper = (upper+lower)/2
+        upper = mid
+      end
+    end
+    unless upper == lower
+      if try_static_assert("#{const} == #{lower}", headers, opt)
+        upper = lower
       end
     end
@@ -332,8 +338,9 @@ SRC
   else
     src = %{#{COMMON_HEADERS}
-#{headers}
+#{includes}
 #include <stdio.h>
 /*top*/
-int main() {printf("%d\\n", (int)(#{const})); return 0;}
+int conftest_const = (int)(#{const});
+int main() {printf("%d\\n", conftest_const); return 0;}
 }
     if try_link0(src, opt, &b)
@@ -362,4 +369,15 @@ SRC
 end
 
+def try_var(var, headers = nil, &b)
+  headers = cpp_include(headers)
+  try_compile(<<"SRC", &b)
+#{COMMON_HEADERS}
+#{headers}
+/*top*/
+int main() { return 0; }
+int t() { void *volatile p; p = (void *)&#{var}; return 0; }
+SRC
+end
+
 def egrep_cpp(pat, src, opt = "", &b)
   src = create_tmpsrc(src, &b)
@@ -460,5 +478,5 @@ def message(*s)
 end
 
-def checking_for(m)
+def checking_for(m, fmt = nil)
   f = caller[0][/in `(.*)'$/, 1] and f << ": " #` for vim
   m = "checking for #{m}... "
@@ -467,5 +485,5 @@ def checking_for(m)
   Logging::postpone do
     r = yield
-    a = r ? "yes\n" : "no\n"
+    a = (fmt ? fmt % r : r ? "yes" : "no") << "\n"
     "#{f}#{m}-------------------- #{a}\n"
   end
@@ -475,4 +493,12 @@ def checking_for(m)
 end
 
+def have_macro(macro, headers = nil, opt = "", &b)
+  m = "#{macro}"
+  m << " in #{headers.inspect}" if headers
+  checking_for m do
+    macro_defined?(macro, cpp_include(headers), opt, &b)
+  end
+end
+
 def have_library(lib, func = nil, header=nil, &b)
   func = "main" if !func or func.empty?
@@ -496,4 +522,5 @@ def find_library(lib, func, *paths, &b)
   func = "main" if !func or func.empty?
   lib = with_config(lib+'lib', lib)
+  paths = paths.collect {|path| path.split(File::PATH_SEPARATOR)}.flatten
   checking_for "#{func}() in #{LIBARG%lib}" do
     libpath = $LIBPATH
@@ -525,4 +552,17 @@ def have_func(func, headers = nil, &b)
 end
 
+def have_var(var, headers = nil, &b)
+  checking_for "#{var}" do
+    libs = append_library($libs, libs)
+    if try_var(var, headers, &b)
+      $libs = libs
+      $defs.push(format("-DHAVE_%s", var.upcase))
+      true
+    else
+      false
+    end
+  end
+end
+
 def have_header(header, &b)
   checking_for header do
@@ -605,22 +645,26 @@ def find_executable(bin, path = nil)
 end
 
-def arg_config(config, default=nil)
-  $configure_args.fetch(config.tr('_', '-'), default)
+def arg_config(config, *defaults, &block)
+  $arg_config << [config, *defaults]
+  defaults << nil if !block and defaults.empty?
+  $configure_args.fetch(config.tr('_', '-'), *defaults, &block)
 end
 
-def with_config(config, default=nil)
+def with_config(config, *defaults, &block)
   unless /^--with[-_]/ =~ config
     config = '--with-' + config
   end
-  arg_config(config, default)
+  arg_config(config, *defaults, &block)
 end
 
-def enable_config(config, default=nil)
+def enable_config(config, *defaults)
   if arg_config("--enable-"+config)
     true
   elsif arg_config("--disable-"+config)
     false
+  elsif block_given?
+    yield(config, *defaults)
   else
-    default
+    return *defaults
   end
 end
@@ -647,13 +691,14 @@ end
 def dir_config(target, idefault=nil, ldefault=nil)
   if dir = with_config(target + "-dir", (idefault unless ldefault))
-    defaults = dir.split(File::PATH_SEPARATOR)
+    defaults = Array === dir ? dir : dir.split(File::PATH_SEPARATOR)
     idefault = ldefault = nil
   end
 
   idir = with_config(target + "-include", idefault)
+  $arg_config.last[1] ||= "${#{target}-dir}/include"
   ldir = with_config(target + "-lib", ldefault)
+  $arg_config.last[1] ||= "${#{target}-dir}/lib"
 
-#  idirs = idir ? idir.split(File::PATH_SEPARATOR) : []
-  idirs = idir.split(File::PATH_SEPARATOR) rescue []
+  idirs = idir ? Array === idir ? idir : idir.split(File::PATH_SEPARATOR) : []
   if defaults
     idirs.concat(defaults.collect {|dir| dir + "/include"})
@@ -668,5 +713,5 @@ def dir_config(target, idefault=nil, lde
   end
 
-  ldirs = ldir ? ldir.split(File::PATH_SEPARATOR) : []
+  ldirs = ldir ? Array === ldir ? ldir : ldir.split(File::PATH_SEPARATOR) : []
   if defaults
     ldirs.concat(defaults.collect {|dir| dir + "/lib"})
@@ -801,14 +846,16 @@ def create_makefile(target, srcprefix = 
   Config::expand(srcdir = srcprefix.dup)
 
-  unless $objs then
+  if not $objs
     $objs = []
-    for f in Dir[File.join(srcdir, "*.{#{SRC_EXT.join(%q{,})}}")]
-      $objs.push(File.basename(f, ".*") << "." << $OBJEXT)
-    end
-  else
-    for i in $objs
-      i.sub!(/\.o\z/, ".#{$OBJEXT}")
+    srcs = Dir[File.join(srcdir, "*.{#{SRC_EXT.join(%q{,})}}")]
+    for f in srcs
+      obj = File.basename(f, ".*") << ".o"
     end
   end
+  elsif !(srcs = $srcs)
+    srcs = $objs.collect {|obj| obj.sub(/\.o\z/, '.c')}
+  end
+  for i in $objs
+    i.sub!(/\.o\z/, ".#{$OBJEXT}")
   $objs = $objs.join(" ")
 
@@ -847,4 +894,5 @@ target_prefix = #{target_prefix}
 LOCAL_LIBS = #{$LOCAL_LIBS}
 LIBS = #{$LIBRUBYARG} #{$libs} #{$LIBS}
+SRCS = #{srcs.collect(&File.method(:basename)).join(' ')}
 OBJS = #{$objs}
 TARGET = #{target}
@@ -882,4 +930,5 @@ static:		$(STATIC_LIB)
     mfile.print "#{dest}: #{f} #{dir}\n\t@$(INSTALL_PROG) #{f} #{dir}\n"
   end
+TARGET_SO     = #{($extout ? '$(RUBYARCHDIR)/' : '')}$(DLLIB)
   for i in [[["lib/**/*.rb", "$(RUBYLIBDIR)", "lib"]], $INSTALLFILES]
     files = install_files(mfile, i, nil, srcprefix) or next
@@ -953,4 +1002,6 @@ static:		$(STATIC_LIB)
     end
   end
+
+  $makefile_created = true
 ensure
   mfile.close if mfile
@@ -958,4 +1009,6 @@ end
 
 def init_mkmf(config = CONFIG)
+  $makefile_created = false
+  $arg_config = []
   $enable_shared = config['ENABLE_SHARED'] == 'yes'
   $defs = []
@@ -986,7 +1039,23 @@ def init_mkmf(config = CONFIG)
   $distcleanfiles = []
 
+  $arg_config.clear
   dir_config("opt")
 end
 
+FailedMassage = <<MESSAGE
+Could not create Makefile due to some reason, probably lack of
+necessary libraries and/or headers.  Check the mkmf.log file for more
+details.  You may need configuration options.
+
+Provided configuration options:
+MESSAGE
+
+def mkmf_failed(path)
+  unless $makefile_created
+    opts = $arg_config.collect {|t, n| "\t#{t}#{"=#{n}" if n}\n"}
+    abort "*** #{path} failed ***\n" + FailedMassage + opts.join
+  end
+end
+
 init_mkmf
 
@@ -1043,12 +1112,17 @@ RPATHFLAG = config_string('RPATHFLAG') |
 LIBARG = config_string('LIBARG') || '-l%s'
 
+sep = File::ALT_SEPARATOR ? ":/=#{File::ALT_SEPARATOR}" : ''
 CLEANINGS = "
 clean:
-		@$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES)
+		@-$(RM) $(CLEANLIBS#{sep}) $(CLEANOBJS#{sep}) $(CLEANFILES#{sep})
 
 distclean:	clean
-		@$(RM) Makefile extconf.h conftest.* mkmf.log
-		@$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
+		@-$(RM) Makefile extconf.h conftest.* mkmf.log
+		@-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES#{sep})
 
 realclean:	distclean
 "
+
+if not $extmk and /\A(extconf|makefile).rb\z/ =~ File.basename($0)
+  END {mkmf_failed($0)}
+end
