1#! /usr/local/bin/ruby
2# -*- mode: ruby; coding: us-ascii -*-
3
4$extension = nil
5$extstatic = nil
6$force_static = nil
7$install = nil
8$destdir = nil
9$dryrun = false
10$clean = nil
11$nodynamic = nil
12$extinit = nil
13$extobjs = []
14$extflags = ""
15$extlibs = nil
16$extpath = nil
17$ignore = nil
18$message = nil
19$command_output = nil
20$configure_only = false
21
22$progname = $0
23alias $PROGRAM_NAME $0
24alias $0 $progname
25
26$extlist = []
27$compiled = {}
28
29DUMMY_SIGNATURE = "***DUMMY MAKEFILE***"
30
31srcdir = File.dirname(File.dirname(__FILE__))
32unless defined?(CROSS_COMPILING) and CROSS_COMPILING
33  $:.replace([File.expand_path("lib", srcdir), Dir.pwd])
34end
35$:.unshift(srcdir)
36require 'rbconfig'
37
38$topdir = "."
39$top_srcdir = srcdir
40
41$" << "mkmf.rb"
42load File.expand_path("lib/mkmf.rb", srcdir)
43require 'optparse/shellwords'
44
45if defined?(File::NULL)
46  @null = File::NULL
47elsif !File.chardev?(@null = "/dev/null")
48  @null = "nul"
49end
50
51def sysquote(x)
52  @quote ||= /os2/ =~ (CROSS_COMPILING || RUBY_PLATFORM)
53  @quote ? x.quote : x
54end
55
56def verbose?
57  $mflags.defined?("V") == "1"
58end
59
60def system(*args)
61  if verbose?
62    if args.size == 1
63      puts args
64    else
65      puts Shellwords.join(args)
66    end
67  end
68  super
69end
70
71def extract_makefile(makefile, keep = true)
72  m = File.read(makefile)
73  if !(target = m[/^TARGET[ \t]*=[ \t]*(\S*)/, 1])
74    return keep
75  end
76  installrb = {}
77  m.scan(/^install-rb-default:.*[ \t](\S+)(?:[ \t].*)?\n\1:[ \t]*(\S+)/) {installrb[$2] = $1}
78  oldrb = installrb.keys.sort
79  newrb = install_rb(nil, "").collect {|d, *f| f}.flatten.sort
80  if target_prefix = m[/^target_prefix[ \t]*=[ \t]*\/(.*)/, 1]
81    target = "#{target_prefix}/#{target}"
82  end
83  unless oldrb == newrb
84    if $extout
85      newrb.each {|f| installrb.delete(f)}
86      unless installrb.empty?
87        config = CONFIG.dup
88        install_dirs(target_prefix).each {|var, val| config[var] = val}
89        FileUtils.rm_f(installrb.values.collect {|f| RbConfig.expand(f, config)},
90                       :verbose => verbose?)
91      end
92    end
93    return false
94  end
95  srcs = Dir[File.join($srcdir, "*.{#{SRC_EXT.join(%q{,})}}")].map {|fn| File.basename(fn)}.sort
96  if !srcs.empty?
97    old_srcs = m[/^ORIG_SRCS[ \t]*=[ \t](.*)/, 1] or return false
98    old_srcs.split.sort == srcs or return false
99  end
100  $target = target
101  $extconf_h = m[/^RUBY_EXTCONF_H[ \t]*=[ \t]*(\S+)/, 1]
102  if $static.nil?
103    $static ||= m[/^EXTSTATIC[ \t]*=[ \t]*(\S+)/, 1] || false
104    /^STATIC_LIB[ \t]*=[ \t]*\S+/ =~ m or $static = false
105  end
106  $preload = Shellwords.shellwords(m[/^preload[ \t]*=[ \t]*(.*)/, 1] || "")
107  $DLDFLAGS += " " + (m[/^dldflags[ \t]*=[ \t]*(.*)/, 1] || "")
108  if s = m[/^LIBS[ \t]*=[ \t]*(.*)/, 1]
109    s.sub!(/^#{Regexp.quote($LIBRUBYARG)} */, "")
110    s.sub!(/ *#{Regexp.quote($LIBS)}$/, "")
111    $libs = s
112  end
113  $objs = (m[/^OBJS[ \t]*=[ \t](.*)/, 1] || "").split
114  $srcs = (m[/^SRCS[ \t]*=[ \t](.*)/, 1] || "").split
115  $distcleanfiles = (m[/^DISTCLEANFILES[ \t]*=[ \t](.*)/, 1] || "").split
116  $LOCAL_LIBS = m[/^LOCAL_LIBS[ \t]*=[ \t]*(.*)/, 1] || ""
117  $LIBPATH = Shellwords.shellwords(m[/^libpath[ \t]*=[ \t]*(.*)/, 1] || "") - %w[$(libdir) $(topdir)]
118  true
119end
120
121def extmake(target)
122  unless $configure_only || verbose?
123    print "#{$message} #{target}\n"
124    $stdout.flush
125  end
126
127  FileUtils.mkpath target unless File.directory?(target)
128  begin
129    dir = Dir.pwd
130    FileUtils.mkpath target unless File.directory?(target)
131    Dir.chdir target
132    top_srcdir = $top_srcdir
133    topdir = $topdir
134    hdrdir = $hdrdir
135    prefix = "../" * (target.count("/")+1)
136    $top_srcdir = relative_from(top_srcdir, prefix)
137    $hdrdir = relative_from(hdrdir, prefix)
138    $topdir = prefix + $topdir
139    $target = target
140    $mdir = target
141    $srcdir = File.join($top_srcdir, "ext", $mdir)
142    $preload = nil
143    $objs = []
144    $srcs = []
145    $compiled[target] = false
146    makefile = "./Makefile"
147    ok = File.exist?(makefile)
148    unless $ignore
149      rbconfig0 = RbConfig::CONFIG
150      mkconfig0 = CONFIG
151      rbconfig = {
152	"hdrdir" => $hdrdir,
153	"srcdir" => $srcdir,
154	"topdir" => $topdir,
155      }
156      mkconfig = {
157	"hdrdir" => ($hdrdir == top_srcdir) ? top_srcdir : "$(top_srcdir)/include",
158	"srcdir" => "$(top_srcdir)/ext/#{$mdir}",
159	"topdir" => $topdir,
160      }
161      rbconfig0.each_pair {|key, val| rbconfig[key] ||= val.dup}
162      mkconfig0.each_pair {|key, val| mkconfig[key] ||= val.dup}
163      RbConfig.module_eval {
164	remove_const(:CONFIG)
165	const_set(:CONFIG, rbconfig)
166	remove_const(:MAKEFILE_CONFIG)
167	const_set(:MAKEFILE_CONFIG, mkconfig)
168      }
169      MakeMakefile.class_eval {
170	remove_const(:CONFIG)
171	const_set(:CONFIG, mkconfig)
172      }
173      begin
174	$extconf_h = nil
175	ok &&= extract_makefile(makefile)
176	old_objs = $objs
177	old_cleanfiles = $distcleanfiles
178	conf = ["#{$srcdir}/makefile.rb", "#{$srcdir}/extconf.rb"].find {|f| File.exist?(f)}
179	if (!ok || ($extconf_h && !File.exist?($extconf_h)) ||
180	    !(t = modified?(makefile, MTIMES)) ||
181	    [conf, "#{$srcdir}/depend"].any? {|f| modified?(f, [t])})
182        then
183	  ok = false
184          if $configure_only
185            if verbose?
186              print "#{conf}\n" if conf
187            else
188              print "#{$message} #{target}\n"
189            end
190            $stdout.flush
191          end
192          init_mkmf
193	  Logging::logfile 'mkmf.log'
194	  rm_f makefile
195	  if conf
196            Logging.open do
197              unless verbose?
198                $stderr.reopen($stdout.reopen(@null))
199              end
200              load $0 = conf
201            end
202	  else
203	    create_makefile(target)
204	  end
205	  $defs << "-DRUBY_EXPORT" if $static
206	  ok = File.exist?(makefile)
207	end
208      rescue SystemExit
209	# ignore
210      rescue => error
211        ok = false
212      ensure
213	rm_f "conftest*"
214	$0 = $PROGRAM_NAME
215      end
216    end
217    ok &&= File.open(makefile){|f| !f.gets[DUMMY_SIGNATURE]}
218    ok = yield(ok) if block_given?
219    unless ok
220      open(makefile, "w") do |f|
221        f.puts "# " + DUMMY_SIGNATURE
222	f.print(*dummy_makefile(CONFIG["srcdir"]))
223      end
224
225      mess = "Failed to configure #{target}. It will not be installed.\n"
226      if error
227        mess = "#{error}\n#{mess}"
228      end
229
230      Logging::message(mess) if Logging.log_opened?
231      print(mess)
232      $stdout.flush
233      return true
234    end
235    args = sysquote($mflags)
236    unless $destdir.to_s.empty? or $mflags.defined?("DESTDIR")
237      args += [sysquote("DESTDIR=" + relative_from($destdir, "../"+prefix))]
238    end
239    if $static and ok and !$objs.empty? and !File.fnmatch?("-*", target)
240      args += ["static"] unless $clean
241      $extlist.push [$static, target, $target, $preload]
242    end
243    FileUtils.rm_f(old_cleanfiles - $distcleanfiles)
244    FileUtils.rm_f(old_objs - $objs)
245    unless $configure_only or system($make, *args)
246      $ignore or $continue or return false
247    end
248    $compiled[target] = true
249    if $clean
250      FileUtils.rm_f("mkmf.log")
251      if $clean != true
252	FileUtils.rm_f([makefile, $extconf_h || "extconf.h"])
253      end
254    end
255    if $static
256      $extflags ||= ""
257      $extlibs ||= []
258      $extpath ||= []
259      unless $mswin
260        $extflags = split_libs($extflags, $DLDFLAGS, $LDFLAGS).uniq.join(" ")
261      end
262      $extlibs = merge_libs($extlibs, split_libs($libs), split_libs($LOCAL_LIBS))
263      $extpath |= $LIBPATH
264    end
265  ensure
266    Logging::log_close
267    unless $ignore
268      RbConfig.module_eval {
269	remove_const(:CONFIG)
270	const_set(:CONFIG, rbconfig0)
271	remove_const(:MAKEFILE_CONFIG)
272	const_set(:MAKEFILE_CONFIG, mkconfig0)
273      }
274      MakeMakefile.class_eval {
275	remove_const(:CONFIG)
276	const_set(:CONFIG, mkconfig0)
277      }
278    end
279    $top_srcdir = top_srcdir
280    $topdir = topdir
281    $hdrdir = hdrdir
282    Dir.chdir dir
283  end
284  begin
285    Dir.rmdir target
286    target = File.dirname(target)
287  rescue SystemCallError
288    break
289  end while true
290  true
291end
292
293def compiled?(target)
294  $compiled[target]
295end
296
297def parse_args()
298  $mflags = []
299  $makeflags = [] # for make command to build ruby, so quoted
300
301  $optparser ||= OptionParser.new do |opts|
302    opts.on('-n') {$dryrun = true}
303    opts.on('--[no-]extension [EXTS]', Array) do |v|
304      $extension = (v == false ? [] : v)
305    end
306    opts.on('--[no-]extstatic [STATIC]', Array) do |v|
307      if ($extstatic = v) == false
308        $extstatic = []
309      elsif v
310        $force_static = true if $extstatic.delete("static")
311        $extstatic = nil if $extstatic.empty?
312      end
313    end
314    opts.on('--dest-dir=DIR') do |v|
315      $destdir = v
316    end
317    opts.on('--extout=DIR') do |v|
318      $extout = (v unless v.empty?)
319    end
320    opts.on('--make=MAKE') do |v|
321      $make = v || 'make'
322    end
323    opts.on('--make-flags=FLAGS', '--mflags', Shellwords) do |v|
324      v.grep(/\A([-\w]+)=(.*)/) {$configure_args["--#{$1}"] = $2}
325      if arg = v.first
326        arg.insert(0, '-') if /\A[^-][^=]*\Z/ =~ arg
327      end
328      $makeflags.concat(v.reject {|arg2| /\AMINIRUBY=/ =~ arg2}.quote)
329      $mflags.concat(v)
330    end
331    opts.on('--message [MESSAGE]', String) do |v|
332      $message = v
333    end
334    opts.on('--command-output=FILE', String) do |v|
335      $command_output = v
336    end
337  end
338  begin
339    $optparser.parse!(ARGV)
340  rescue OptionParser::InvalidOption => e
341    retry if /^--/ =~ e.args[0]
342    $optparser.warn(e)
343    abort $optparser.to_s
344  end
345
346  $destdir ||= ''
347
348  $make, *rest = Shellwords.shellwords($make)
349  $mflags.unshift(*rest) unless rest.empty?
350
351  def $mflags.set?(flag)
352    grep(/\A-(?!-).*#{flag.chr}/i) { return true }
353    false
354  end
355  def $mflags.defined?(var)
356    grep(/\A#{var}=(.*)/) {return $1}
357    false
358  end
359
360  if $mflags.set?(?n)
361    $dryrun = true
362  else
363    $mflags.unshift '-n' if $dryrun
364  end
365
366  $continue = $mflags.set?(?k)
367  if $extout
368    $extout = '$(topdir)/'+$extout
369    RbConfig::CONFIG["extout"] = CONFIG["extout"] = $extout
370    $extout_prefix = $extout ? "$(extout)$(target_prefix)/" : ""
371    $mflags << "extout=#$extout" << "extout_prefix=#$extout_prefix"
372  end
373end
374
375parse_args()
376
377if target = ARGV.shift and /^[a-z-]+$/ =~ target
378  $mflags.push(target)
379  case target
380  when /^(dist|real)?(clean)$/
381    target = $2
382    $ignore ||= true
383    $clean = $1 ? $1[0] : true
384  when /^install\b/
385    $install = true
386    $ignore ||= true
387    $mflags.unshift("INSTALL_PROG=install -c -p -m 0755",
388                    "INSTALL_DATA=install -c -p -m 0644",
389                    "MAKEDIRS=mkdir -p") if $dryrun
390  when /configure/
391    $configure_only = true
392  end
393end
394unless $message
395  if target
396    $message = target.sub(/^(\w+?)e?\b/, '\1ing').tr('-', ' ')
397  else
398    $message = "compiling"
399  end
400end
401
402EXEEXT = CONFIG['EXEEXT']
403if CROSS_COMPILING
404  $ruby = $mflags.defined?("MINIRUBY") || CONFIG['MINIRUBY']
405elsif sep = config_string('BUILD_FILE_SEPARATOR')
406  $ruby = "$(topdir:/=#{sep})#{sep}miniruby" + EXEEXT
407else
408  $ruby = '$(topdir)/miniruby' + EXEEXT
409end
410$ruby << " -I'$(topdir)'"
411unless CROSS_COMPILING
412  $ruby << " -I'$(top_srcdir)/lib'"
413  $ruby << " -I'$(extout)/$(arch)' -I'$(extout)/common'" if $extout
414  ENV["RUBYLIB"] = "-"
415end
416$mflags << "ruby=#$ruby"
417
418MTIMES = [__FILE__, 'rbconfig.rb', srcdir+'/lib/mkmf.rb'].collect {|f| File.mtime(f)}
419
420# get static-link modules
421$static_ext = {}
422if $extstatic
423  $extstatic.each do |t|
424    target = t
425    target = target.downcase if File::FNM_SYSCASE.nonzero?
426    $static_ext[target] = $static_ext.size
427  end
428end
429for dir in ["ext", File::join($top_srcdir, "ext")]
430  setup = File::join(dir, CONFIG['setup'])
431  if File.file? setup
432    f = open(setup)
433    while line = f.gets()
434      line.chomp!
435      line.sub!(/#.*$/, '')
436      next if /^\s*$/ =~ line
437      target, opt = line.split(nil, 3)
438      if target == 'option'
439	case opt
440	when 'nodynamic'
441	  $nodynamic = true
442	end
443	next
444      end
445      target = target.downcase if File::FNM_SYSCASE.nonzero?
446      $static_ext[target] = $static_ext.size
447    end
448    MTIMES << f.mtime
449    $setup = setup
450    f.close
451    break
452  end
453end unless $extstatic
454
455ext_prefix = "#{$top_srcdir}/ext"
456exts = $static_ext.sort_by {|t, i| i}.collect {|t, i| t}
457withes, withouts = %w[--with --without].collect {|w|
458  if !(w = %w[-extensions -ext].collect {|o|arg_config(w+o)}).any?
459    nil
460  elsif (w = w.grep(String)).empty?
461    proc {true}
462  else
463    proc {|c1| w.collect {|o| o.split(/,/)}.flatten.any?(&c1)}
464  end
465}
466if withes
467  withouts ||= proc {true}
468else
469  withes = proc {false}
470  withouts ||= withes
471end
472cond = proc {|ext, *|
473  cond1 = proc {|n| File.fnmatch(n, ext)}
474  withes.call(cond1) or !withouts.call(cond1)
475}
476($extension || %w[*]).each do |e|
477  e = e.sub(/\A(?:\.\/)+/, '')
478  exts |= Dir.glob("#{ext_prefix}/#{e}/**/extconf.rb").collect {|d|
479    d = File.dirname(d)
480    d.slice!(0, ext_prefix.length + 1)
481    d
482  }.find_all {|ext|
483    with_config(ext, &cond)
484  }.sort
485end
486
487if $extout
488  extout = RbConfig.expand("#{$extout}", RbConfig::CONFIG.merge("topdir"=>$topdir))
489  unless $ignore
490    FileUtils.mkpath(extout)
491  end
492end
493
494dir = Dir.pwd
495FileUtils::makedirs('ext')
496Dir::chdir('ext')
497
498hdrdir = $hdrdir
499$hdrdir = ($top_srcdir = relative_from(srcdir, $topdir = "..")) + "/include"
500exts.each do |d|
501  $static = $force_static ? true : $static_ext[target]
502
503  if $ignore or !$nodynamic or $static
504    extmake(d) or abort
505  end
506end
507
508$top_srcdir = srcdir
509$topdir = "."
510$hdrdir = hdrdir
511
512extinit = Struct.new(:c, :o) {
513  def initialize(src)
514    super("#{src}.c", "#{src}.#{$OBJEXT}")
515  end
516}.new("extinit")
517if $ignore
518  FileUtils.rm_f(extinit.to_a) if $clean
519  Dir.chdir ".."
520  if $clean
521    Dir.rmdir('ext') rescue nil
522    if $extout
523      FileUtils.rm_rf([extout+"/common", extout+"/include/ruby", extout+"/rdoc"])
524      FileUtils.rm_rf(extout+"/"+CONFIG["arch"])
525      if $clean != true
526	FileUtils.rm_rf(extout+"/include/"+CONFIG["arch"])
527	FileUtils.rm_f($mflags.defined?("INSTALLED_LIST")||ENV["INSTALLED_LIST"]||".installed.list")
528	Dir.rmdir(extout+"/include") rescue nil
529	Dir.rmdir(extout) rescue nil
530      end
531    end
532  end
533  exit
534end
535
536$extinit ||= ""
537$extobjs ||= []
538$extpath ||= []
539$extflags ||= ""
540$extlibs ||= []
541unless $extlist.empty?
542  $extinit << "\n" unless $extinit.empty?
543  list = $extlist.dup
544  built = []
545  while e = list.shift
546    s,t,i,r,os = e
547    if r and !(r -= built).empty?
548      l = list.size
549      if (while l > 0; break true if r.include?(list[l-=1][1]) end)
550        list.insert(l + 1, e)
551      end
552      next
553    end
554    $extinit << "    init(Init_#{File.basename i}, \"#{i}.so\");\n"
555    $extobjs << format("ext/%s/%s.%s", t, File.basename(i), $LIBEXT)
556    built << t
557  end
558
559  src = %{\
560#include "ruby/ruby.h"
561
562#define init(func, name) {	\\
563    extern void func(void);	\\
564    ruby_init_ext(name, func);	\\
565}
566
567void ruby_init_ext(const char *name, void (*init)(void));
568
569void Init_ext(void)\n{\n#$extinit}
570}
571  if !modified?(extinit.c, MTIMES) || IO.read(extinit.c) != src
572    open(extinit.c, "w") {|fe| fe.print src}
573  end
574
575  if RUBY_PLATFORM =~ /beos/
576    $extflags.delete("-L/usr/local/lib")
577  end
578  $extpath.delete("$(topdir)")
579  $extflags = libpathflag($extpath) << " " << $extflags.strip
580  conf = [
581    ['LIBRUBY_SO_UPDATE', '$(LIBRUBY_EXTS)'],
582    ['SETUP', $setup],
583    ['EXTLIBS', $extlibs.join(' ')], ['EXTLDFLAGS', $extflags]
584  ].map {|n, v|
585    "#{n}=#{v}" if v and !(v = v.strip).empty?
586  }.compact
587  puts(*conf)
588  $stdout.flush
589  $mflags.concat(conf)
590  $makeflags.concat(conf)
591else
592  FileUtils.rm_f(extinit.to_a)
593end
594rubies = []
595%w[RUBY RUBYW STATIC_RUBY].each {|n|
596  r = n
597  if r = arg_config("--"+r.downcase) || config_string(r+"_INSTALL_NAME")
598    rubies << RbConfig.expand(r+=EXEEXT)
599    $mflags << "#{n}=#{r}"
600  end
601}
602
603Dir.chdir ".."
604unless $destdir.to_s.empty?
605  $mflags.defined?("DESTDIR") or $mflags << "DESTDIR=#{$destdir}"
606end
607$makeflags.uniq!
608
609if $nmake == ?b
610  unless (vars = $mflags.grep(/\A\w+=/n)).empty?
611    open(mkf = "libruby.mk", "wb") do |tmf|
612      tmf.puts("!include Makefile")
613      tmf.puts
614      tmf.puts(*vars.map {|v| v.sub(/\=/, " = ")})
615      tmf.puts("PRE_LIBRUBY_UPDATE = del #{mkf}")
616    end
617    $mflags.unshift("-f#{mkf}")
618    vars.each {|flag| flag.sub!(/\A/, "-D")}
619  end
620end
621$mflags.unshift("topdir=#$topdir")
622ENV.delete("RUBYOPT")
623if $configure_only and $command_output
624  exts.map! {|d| "ext/#{d}/."}
625  open($command_output, "wb") do |mf|
626    mf.puts "V = 0"
627    mf.puts "Q1 = $(V:1=)"
628    mf.puts "Q = $(Q1:0=@)"
629    mf.puts "ECHO1 = $(V:1=@:)"
630    mf.puts "ECHO = $(ECHO1:0=@echo)"
631    mf.puts "MFLAGS = -$(MAKEFLAGS)" if $nmake
632    mf.puts
633
634    def mf.macro(name, values, max = 70)
635      print name, " ="
636      w = w0 = name.size + 2
637      h = " \\\n" + "\t" * (w / 8) + " " * (w % 8)
638      values.each do |s|
639        if s.size + w > max
640          print h
641          w = w0
642        end
643        print " ", s
644        w += s.size + 1
645      end
646      puts
647    end
648
649    mf.macro "extensions", exts
650    mf.macro "EXTOBJS", $extlist.empty? ? ["dmyext.#{$OBJEXT}"] : ["ext/extinit.#{$OBJEXT}", *$extobjs]
651    mf.macro "EXTLIBS", $extlibs
652    mf.macro "EXTLDFLAGS", $extflags.split
653    mf.puts
654    targets = %w[all install static install-so install-rb clean distclean realclean]
655    targets.each do |tgt|
656      mf.puts "#{tgt}: $(extensions:/.=/#{tgt})"
657    end
658    mf.puts
659    mf.puts "clean:\n\t-$(Q)$(RM) ext/extinit.#{$OBJEXT}"
660    mf.puts "distclean:\n\t-$(Q)$(RM) ext/extinit.c"
661    mf.puts
662    mf.puts "#{rubies.join(' ')}: $(extensions:/.=/#{$force_static ? 'static' : 'all'})"
663    (["all static"] + rubies).each_with_index do |tgt, i|
664      mf.print "#{tgt}:\n\t$(Q)$(MAKE) "
665      mf.print "$(MFLAGS) "
666      if enable_config("shared", $enable_shared)
667        mf.print %[DLDOBJS="$(EXTOBJS) $(ENCOBJS)" EXTSOLIBS="$(EXTLIBS)" ]
668        mf.print 'LIBRUBY_SO_UPDATE=$(LIBRUBY_EXTS) '
669      else
670        mf.print %[EXTOBJS="$(EXTOBJS) $(ENCOBJS)" EXTLIBS="$(EXTLIBS)" ]
671      end
672      mf.print 'EXTLDFLAGS="$(EXTLDFLAGS)" '
673      if i == 0
674        mf.puts rubies.join(' ')
675      else
676        mf.puts '$@'
677      end
678    end
679    mf.puts
680    exec = config_string("exec") {|str| str + " "}
681    targets.each do |tgt|
682      exts.each do |d|
683        mf.puts "#{d[0..-2]}#{tgt}:\n\t$(Q)cd $(@D) && #{exec}$(MAKE) $(MFLAGS) V=$(V) $(@F)"
684      end
685    end
686  end
687elsif $command_output
688  message = "making #{rubies.join(', ')}"
689  message = "echo #{message}"
690  $mflags.concat(rubies)
691  $makeflags.concat(rubies)
692  cmd = $makeflags.map {|ss|ss.sub(/.*[$(){};\s].*/, %q['\&'])}.join(' ')
693  open($command_output, 'wb') do |ff|
694    case $command_output
695    when /\.sh\z/
696      ff.puts message, "rm -f \"$0\"; exec \"$@\" #{cmd}"
697    when /\.bat\z/
698      ["@echo off", message, "%* #{cmd}", "del %0 & exit %ERRORLEVEL%"].each do |ss|
699        ff.print ss, "\r\n"
700      end
701    else
702      ff.puts cmd
703    end
704    ff.chmod(0755)
705  end
706elsif !$configure_only
707  message = "making #{rubies.join(', ')}"
708  puts message
709  $stdout.flush
710  $mflags.concat(rubies)
711  system($make, *sysquote($mflags)) or exit($?.exitstatus)
712end
713
714#Local variables:
715# mode: ruby
716#end:
717