* ext/extmk.rb: extend --extension option to specify necessary
  libraries.  [ruby-talk:117405]

* lib/mkmf.rb: err if no makefile is created from extconf.rb.


Index: ext/extmk.rb
===================================================================
RCS file: /cvs/ruby/src/ruby/ext/extmk.rb,v
retrieving revision 1.65
diff -U2 -p -d -r1.65 extmk.rb
--- ext/extmk.rb	2 Sep 2004 16:54:35 -0000	1.65
+++ ext/extmk.rb	24 Oct 2004 06:10:10 -0000
@@ -75,8 +75,10 @@ def extmake(target)
     $preload = nil
     makefile = "./Makefile"
+    ok = false
     unless $ignore
       if !(t = modified?(makefile, MTIMES)) ||
 	 %W<#{$srcdir}/makefile.rb #{$srcdir}/extconf.rb
-	    #{$srcdir}/depend #{$srcdir}/MANIFEST>.any? {|f| modified?(f, [t])}
+	    #{$srcdir}/depend #{$srcdir}/MANIFEST>.any? {|f| modified?(f, [t])} ||
+        $necessary[target] && /^all\b.*:\s*Makefile$/ =~ File.read(makefile)
       then
 	$defs = []
@@ -93,9 +95,10 @@ def extmake(target)
 	  end
 	  $extupdate = true
-	  File.exist?(makefile)
+	  ok = File.exist?(makefile)
 	rescue SystemExit
 	  # ignore
 	ensure
 	  rm_f "conftest*"
+          config = $0
 	  $0 = $PROGRAM_NAME
 	  Config::CONFIG["srcdir"] = $top_srcdir
@@ -121,11 +124,17 @@ def extmake(target)
 		     %w[$(libdir) $(topdir)]
 	end
-	true
+	ok = true
       end
     else
-      File.exist?(makefile)
-    end or open(makefile, "w") do |f|
-      f.print dummy_makefile($srcdir)
-      return true
+      ok = File.exist?(makefile)
+    end
+    unless ok
+      if $necessary[target]
+        mkmf_failed(config)
+      end
+      open(makefile, "w") do |f|
+        f.print dummy_makefile($srcdir)
+        return true
+      end
     end
     args = sysquote($mflags)
@@ -168,8 +177,21 @@ def parse_args()
 
   opts = nil
-  ARGV.options do |opts|
+  $optparser ||= OptionParser.new do |opts|
     opts.on('-n') {$dryrun = true}
     opts.on('--[no-]extension [EXTS]', Array) do |v|
-      $extension = (v == false ? [] : v)
+      if v
+        $extension = v.compact.collect {|v|
+          (m = /\A[-+]?/.match(v)) ? [m.post_match, m[0][0]] : [v, nil]
+        }
+        if $extension.empty? or
+            $extension.all? {|t, n| t != '*' and n != ?-} &&
+            $extension.any? {|t, n| n != ?+}
+          $extension << ["*", ?-]
+        end
+      elsif v == false
+        $extension = [["*", ?-]]
+      else
+        $extension = nil
+      end
     end
     opts.on('--[no-]extstatic [STATIC]', Array) do |v|
@@ -200,11 +222,12 @@ def parse_args()
       $message = v
     end
-    begin
-      opts.parse!
-    rescue OptionParser::InvalidOption => e
-      retry if /^--/ =~ e.args[0]
-      raise
-    end
-  end or abort opts.to_s
+  end
+  begin
+    $optparser.parse!(ARGV)
+  rescue OptionParser::InvalidOption => e
+    retry if /^--/ =~ e.args[0]
+    $optparser.warn(e)
+    abort opts.to_s
+  end
 
   $destdir ||= ''
@@ -311,13 +334,26 @@ for dir in ["ext", File::join($top_srcdi
 end unless $extstatic
 
+$necessary = {}
 ext_prefix = "#{$top_srcdir}/ext"
 exts = $static_ext.sort_by {|t, i| i}.collect {|t, i| t}
-exts |= $extension if $extension
 exts.delete_if {|t| !File.exist?("#{ext_prefix}/#{t}/MANIFEST")}
-exts |= Dir.glob("#{ext_prefix}/*/**/MANIFEST").collect {|d|
+exts |= Dir.glob("#{ext_prefix}/*/**/MANIFEST")
+exts.collect! {|d|
   d = File.dirname(d)
   d.slice!(0, ext_prefix.length + 1)
+  $extension.each {|pat, opt|
+    if File.fnmatch?(pat, d)
+      case opt
+      when ?+
+        $necessary[d] = true
+      when ?-
+        d = nil
+      end
+      break
+    end
+  } if $extension
   d
-} unless $extension
+}
+exts.compact!
 
 if $extout
Index: lib/mkmf.rb
===================================================================
RCS file: /cvs/ruby/src/ruby/lib/mkmf.rb,v
retrieving revision 1.197
diff -U2 -p -d -r1.197 mkmf.rb
--- lib/mkmf.rb	16 Oct 2004 01:56:44 -0000	1.197
+++ lib/mkmf.rb	24 Oct 2004 06:17:16 -0000
@@ -626,4 +626,5 @@ end
 
 def arg_config(config, default=nil)
+  $arg_config << [config, default]
   $configure_args.fetch(config.tr('_', '-'), default)
 end
@@ -672,5 +673,7 @@ def dir_config(target, idefault=nil, lde
 
   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) : []
@@ -1005,4 +1008,6 @@ site-install-rb: install-rb
     mfile.print "$(OBJS): #{vpath}ruby.h #{vpath}defines.h #{$config_h}\n"
   end
+
+  $makefile_created = true
 ensure
   mfile.close if mfile
@@ -1010,4 +1015,6 @@ end
 
 def init_mkmf(config = CONFIG)
+  $makefile_created = false
+  $arg_config = []
   $enable_shared = config['ENABLE_SHARED'] == 'yes'
   $defs = []
@@ -1041,7 +1048,23 @@ def init_mkmf(config = CONFIG)
   $extout_prefix ||= nil
 
+  $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
 
@@ -1108,2 +1131,6 @@ distclean:	clean
 realclean:	distclean
 "
+
+if not $extmk and /\A(extconf|makefile).rb\z/ =~ File.basename($0)
+  END {mkmf_failed($0)}
+end
