mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			777 lines
		
	
	
	
		
			21 KiB
		
	
	
	
		
			Ruby
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			777 lines
		
	
	
	
		
			21 KiB
		
	
	
	
		
			Ruby
		
	
	
		
			Executable file
		
	
	
	
	
#! /usr/local/bin/ruby
 | 
						|
# -*- mode: ruby; coding: us-ascii -*-
 | 
						|
# frozen_string_literal: false
 | 
						|
 | 
						|
# :stopdoc:
 | 
						|
$extension = nil
 | 
						|
$extstatic = nil
 | 
						|
$force_static = nil
 | 
						|
$destdir = nil
 | 
						|
$dryrun = false
 | 
						|
$nodynamic = nil
 | 
						|
$extobjs = []
 | 
						|
$extflags = ""
 | 
						|
$extlibs = nil
 | 
						|
$extpath = nil
 | 
						|
$message = nil
 | 
						|
$command_output = nil
 | 
						|
$subconfigure = false
 | 
						|
 | 
						|
$progname = $0
 | 
						|
alias $PROGRAM_NAME $0
 | 
						|
alias $0 $progname
 | 
						|
 | 
						|
$extlist = []
 | 
						|
 | 
						|
DUMMY_SIGNATURE = "***DUMMY MAKEFILE***"
 | 
						|
 | 
						|
srcdir = File.dirname(File.dirname(__FILE__))
 | 
						|
unless defined?(CROSS_COMPILING) and CROSS_COMPILING
 | 
						|
  $:.replace([File.expand_path("lib", srcdir), Dir.pwd])
 | 
						|
end
 | 
						|
$:.unshift(srcdir)
 | 
						|
require 'rbconfig'
 | 
						|
 | 
						|
$topdir = "."
 | 
						|
$top_srcdir = srcdir
 | 
						|
 | 
						|
$" << "mkmf.rb"
 | 
						|
load File.expand_path("lib/mkmf.rb", srcdir)
 | 
						|
require 'optparse/shellwords'
 | 
						|
 | 
						|
if defined?(File::NULL)
 | 
						|
  @null = File::NULL
 | 
						|
elsif !File.chardev?(@null = "/dev/null")
 | 
						|
  @null = "nul"
 | 
						|
end
 | 
						|
 | 
						|
def verbose?
 | 
						|
  $mflags.defined?("V") == "1"
 | 
						|
end
 | 
						|
 | 
						|
def system(*args)
 | 
						|
  if verbose?
 | 
						|
    if args.size == 1
 | 
						|
      puts args
 | 
						|
    else
 | 
						|
      puts Shellwords.join(args)
 | 
						|
    end
 | 
						|
  end
 | 
						|
  super
 | 
						|
end
 | 
						|
 | 
						|
def atomic_write_open(filename)
 | 
						|
  filename_new = filename + ".new.#$$"
 | 
						|
  open(filename_new, "wb") do |f|
 | 
						|
    yield f
 | 
						|
  end
 | 
						|
  if File.binread(filename_new) != (File.binread(filename) rescue nil)
 | 
						|
    File.rename(filename_new, filename)
 | 
						|
  else
 | 
						|
    File.unlink(filename_new)
 | 
						|
  end
 | 
						|
end
 | 
						|
 | 
						|
def extract_makefile(makefile, keep = true)
 | 
						|
  m = File.read(makefile)
 | 
						|
  s = m[/^CLEANFILES[ \t]*=[ \t](.*)/, 1] and $cleanfiles = s.split
 | 
						|
  s = m[/^DISTCLEANFILES[ \t]*=[ \t](.*)/, 1] and $distcleanfiles = s.split
 | 
						|
  s = m[/^EXTSO[ \t]*=[ \t](.*)/, 1] and $extso = s.split
 | 
						|
  if !(target = m[/^TARGET[ \t]*=[ \t]*(\S*)/, 1])
 | 
						|
    return keep
 | 
						|
  end
 | 
						|
  installrb = {}
 | 
						|
  m.scan(/^(?:do-)?install-rb-default:.*[ \t](\S+)(?:[ \t].*)?\n\1:[ \t]*(\S+)/) {installrb[$2] = $1}
 | 
						|
  oldrb = installrb.keys.sort
 | 
						|
  newrb = install_rb(nil, "").collect {|d, *f| f}.flatten.sort
 | 
						|
  if target_prefix = m[/^target_prefix[ \t]*=[ \t]*\/(.*)/, 1]
 | 
						|
    target = "#{target_prefix}/#{target}"
 | 
						|
  end
 | 
						|
  unless oldrb == newrb
 | 
						|
    if $extout
 | 
						|
      newrb.each {|f| installrb.delete(f)}
 | 
						|
      unless installrb.empty?
 | 
						|
        config = CONFIG.dup
 | 
						|
        install_dirs(target_prefix).each {|var, val| config[var] = val}
 | 
						|
        FileUtils.rm_f(installrb.values.collect {|f| RbConfig.expand(f, config)},
 | 
						|
                       :verbose => verbose?)
 | 
						|
      end
 | 
						|
    end
 | 
						|
    return false
 | 
						|
  end
 | 
						|
  srcs = Dir[File.join($srcdir, "*.{#{SRC_EXT.join(%q{,})}}")].map {|fn| File.basename(fn)}.sort
 | 
						|
  if !srcs.empty?
 | 
						|
    old_srcs = m[/^ORIG_SRCS[ \t]*=[ \t](.*)/, 1] or return false
 | 
						|
    (old_srcs.split - srcs).empty? or return false
 | 
						|
  end
 | 
						|
  $target = target
 | 
						|
  $extconf_h = m[/^RUBY_EXTCONF_H[ \t]*=[ \t]*(\S+)/, 1]
 | 
						|
  if $static.nil?
 | 
						|
    $static ||= m[/^EXTSTATIC[ \t]*=[ \t]*(\S+)/, 1] || false
 | 
						|
    /^STATIC_LIB[ \t]*=[ \t]*\S+/ =~ m or $static = false
 | 
						|
  end
 | 
						|
  $preload = Shellwords.shellwords(m[/^preload[ \t]*=[ \t]*(.*)/, 1] || "")
 | 
						|
  if dldflags = m[/^dldflags[ \t]*=[ \t]*(.*)/, 1] and !$DLDFLAGS.include?(dldflags)
 | 
						|
    $DLDFLAGS += " " + dldflags
 | 
						|
  end
 | 
						|
  if s = m[/^LIBS[ \t]*=[ \t]*(.*)/, 1]
 | 
						|
    s.sub!(/^#{Regexp.quote($LIBRUBYARG)} */, "")
 | 
						|
    s.sub!(/ *#{Regexp.quote($LIBS)}$/, "")
 | 
						|
    $libs = s
 | 
						|
  end
 | 
						|
  $objs = (m[/^OBJS[ \t]*=[ \t](.*)/, 1] || "").split
 | 
						|
  $srcs = (m[/^SRCS[ \t]*=[ \t](.*)/, 1] || "").split
 | 
						|
  $headers = (m[/^LOCAL_HDRS[ \t]*=[ \t](.*)/, 1] || "").split
 | 
						|
  $LOCAL_LIBS = m[/^LOCAL_LIBS[ \t]*=[ \t]*(.*)/, 1] || ""
 | 
						|
  $LIBPATH = Shellwords.shellwords(m[/^libpath[ \t]*=[ \t]*(.*)/, 1] || "") - %w[$(libdir) $(topdir)]
 | 
						|
  true
 | 
						|
end
 | 
						|
 | 
						|
def extmake(target, basedir = 'ext', maybestatic = true)
 | 
						|
  FileUtils.mkpath target unless File.directory?(target)
 | 
						|
  begin
 | 
						|
    # don't build if parent library isn't build
 | 
						|
    parent = true
 | 
						|
    d = target
 | 
						|
    until (d = File.dirname(d)) == '.'
 | 
						|
      if File.exist?("#{$top_srcdir}/#{basedir}/#{d}/extconf.rb")
 | 
						|
        parent = (/^all:\s*install/ =~ IO.read("#{d}/Makefile") rescue false)
 | 
						|
        break
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    dir = Dir.pwd
 | 
						|
    FileUtils.mkpath target unless File.directory?(target)
 | 
						|
    Dir.chdir target
 | 
						|
    top_srcdir = $top_srcdir
 | 
						|
    topdir = $topdir
 | 
						|
    hdrdir = $hdrdir
 | 
						|
    prefix = "../" * (target.count("/")+1)
 | 
						|
    $top_srcdir = relative_from(top_srcdir, prefix)
 | 
						|
    $hdrdir = relative_from(hdrdir, prefix)
 | 
						|
    $topdir = prefix + $topdir
 | 
						|
    $target = target
 | 
						|
    $mdir = target
 | 
						|
    $srcdir = File.join($top_srcdir, basedir, $mdir)
 | 
						|
    $preload = nil
 | 
						|
    $objs = []
 | 
						|
    $srcs = []
 | 
						|
    $extso = []
 | 
						|
    makefile = "./Makefile"
 | 
						|
    static = $static
 | 
						|
    $static = nil if noinstall = File.fnmatch?("-*", target)
 | 
						|
    ok = parent && File.exist?(makefile)
 | 
						|
    if parent
 | 
						|
      rbconfig0 = RbConfig::CONFIG
 | 
						|
      mkconfig0 = CONFIG
 | 
						|
      rbconfig = {
 | 
						|
	"hdrdir" => $hdrdir,
 | 
						|
	"srcdir" => $srcdir,
 | 
						|
	"topdir" => $topdir,
 | 
						|
      }
 | 
						|
      mkconfig = {
 | 
						|
	"hdrdir" => ($hdrdir == top_srcdir) ? top_srcdir : "$(top_srcdir)/include",
 | 
						|
	"srcdir" => "$(top_srcdir)/#{basedir}/#{$mdir}",
 | 
						|
	"topdir" => $topdir,
 | 
						|
      }
 | 
						|
      rbconfig0.each_pair {|key, val| rbconfig[key] ||= val.dup}
 | 
						|
      mkconfig0.each_pair {|key, val| mkconfig[key] ||= val.dup}
 | 
						|
      RbConfig.module_eval {
 | 
						|
	remove_const(:CONFIG)
 | 
						|
	const_set(:CONFIG, rbconfig)
 | 
						|
	remove_const(:MAKEFILE_CONFIG)
 | 
						|
	const_set(:MAKEFILE_CONFIG, mkconfig)
 | 
						|
      }
 | 
						|
      MakeMakefile.class_eval {
 | 
						|
	remove_const(:CONFIG)
 | 
						|
	const_set(:CONFIG, mkconfig)
 | 
						|
      }
 | 
						|
      begin
 | 
						|
	$extconf_h = nil
 | 
						|
	ok &&= extract_makefile(makefile)
 | 
						|
	old_objs = $objs
 | 
						|
	old_cleanfiles = $distcleanfiles | $cleanfiles
 | 
						|
	conf = ["#{$srcdir}/makefile.rb", "#{$srcdir}/extconf.rb"].find {|f| File.exist?(f)}
 | 
						|
	if (!ok || ($extconf_h && !File.exist?($extconf_h)) ||
 | 
						|
	    !(t = modified?(makefile, MTIMES)) ||
 | 
						|
	    [conf, "#{$srcdir}/depend"].any? {|f| modified?(f, [t])})
 | 
						|
        then
 | 
						|
	  ok = false
 | 
						|
          if verbose?
 | 
						|
            print "#{conf}\n" if conf
 | 
						|
          else
 | 
						|
            print "#{$message} #{target}\n"
 | 
						|
          end
 | 
						|
          $stdout.flush
 | 
						|
          init_mkmf
 | 
						|
	  Logging::logfile 'mkmf.log'
 | 
						|
	  rm_f makefile
 | 
						|
	  if conf
 | 
						|
            Logging.open do
 | 
						|
              unless verbose?
 | 
						|
                $stderr.reopen($stdout.reopen(@null))
 | 
						|
              end
 | 
						|
              load $0 = conf
 | 
						|
            end
 | 
						|
	  else
 | 
						|
	    create_makefile(target)
 | 
						|
	  end
 | 
						|
	  $defs << "-DRUBY_EXPORT" if $static
 | 
						|
	  ok = File.exist?(makefile)
 | 
						|
	end
 | 
						|
      rescue SystemExit
 | 
						|
	# ignore
 | 
						|
      rescue => error
 | 
						|
        ok = false
 | 
						|
      ensure
 | 
						|
	rm_f "conftest*"
 | 
						|
	$0 = $PROGRAM_NAME
 | 
						|
      end
 | 
						|
    end
 | 
						|
    ok &&= File.open(makefile){|f| s = f.gets and !s[DUMMY_SIGNATURE]}
 | 
						|
    unless ok
 | 
						|
      mf = ["# #{DUMMY_SIGNATURE}\n", *dummy_makefile(CONFIG["srcdir"])].join("")
 | 
						|
      atomic_write_open(makefile) do |f|
 | 
						|
        f.print(mf)
 | 
						|
      end
 | 
						|
 | 
						|
      return true if !error and target.start_with?("-")
 | 
						|
 | 
						|
      message = nil
 | 
						|
      if error
 | 
						|
        loc = error.backtrace_locations[0]
 | 
						|
        message = "#{loc.absolute_path}:#{loc.lineno}: #{error.message}"
 | 
						|
        if Logging.log_opened?
 | 
						|
          Logging::message("#{message}\n\t#{error.backtrace.join("\n\t")}\n")
 | 
						|
        end
 | 
						|
      end
 | 
						|
 | 
						|
      return [parent, message]
 | 
						|
    end
 | 
						|
    args = $mflags
 | 
						|
    unless $destdir.to_s.empty? or $mflags.defined?("DESTDIR")
 | 
						|
      args += ["DESTDIR=" + relative_from($destdir, "../"+prefix)]
 | 
						|
    end
 | 
						|
    if $static and ok and !$objs.empty? and !noinstall
 | 
						|
      args += ["static"]
 | 
						|
      $extlist.push [(maybestatic ? $static : false), target, $target, $preload]
 | 
						|
    end
 | 
						|
    FileUtils.rm_f(old_cleanfiles - $distcleanfiles - $cleanfiles)
 | 
						|
    FileUtils.rm_f(old_objs - $objs)
 | 
						|
    if $static
 | 
						|
      $extflags ||= ""
 | 
						|
      $extlibs ||= []
 | 
						|
      $extpath ||= []
 | 
						|
      unless $mswin
 | 
						|
        $extflags = split_libs($extflags, $DLDFLAGS, $LDFLAGS).uniq.join(" ")
 | 
						|
      end
 | 
						|
      $extlibs = merge_libs($extlibs, split_libs($libs, $LOCAL_LIBS).map {|lib| lib.sub(/\A\.\//, "ext/#{target}/")})
 | 
						|
      $extpath |= $LIBPATH
 | 
						|
    end
 | 
						|
  ensure
 | 
						|
    Logging::log_close
 | 
						|
    if rbconfig0
 | 
						|
      RbConfig.module_eval {
 | 
						|
	remove_const(:CONFIG)
 | 
						|
	const_set(:CONFIG, rbconfig0)
 | 
						|
	remove_const(:MAKEFILE_CONFIG)
 | 
						|
	const_set(:MAKEFILE_CONFIG, mkconfig0)
 | 
						|
      }
 | 
						|
    end
 | 
						|
    if mkconfig0
 | 
						|
      MakeMakefile.class_eval {
 | 
						|
	remove_const(:CONFIG)
 | 
						|
	const_set(:CONFIG, mkconfig0)
 | 
						|
      }
 | 
						|
    end
 | 
						|
    $top_srcdir = top_srcdir
 | 
						|
    $topdir = topdir
 | 
						|
    $hdrdir = hdrdir
 | 
						|
    $static = static
 | 
						|
    Dir.chdir dir
 | 
						|
  end
 | 
						|
  begin
 | 
						|
    Dir.rmdir target
 | 
						|
    target = File.dirname(target)
 | 
						|
  rescue SystemCallError
 | 
						|
    break
 | 
						|
  end while true
 | 
						|
  true
 | 
						|
end
 | 
						|
 | 
						|
def parse_args()
 | 
						|
  $mflags = []
 | 
						|
  $makeflags = [] # for make command to build ruby, so quoted
 | 
						|
 | 
						|
  $optparser ||= OptionParser.new do |opts|
 | 
						|
    opts.on('-n') {$dryrun = true}
 | 
						|
    opts.on('--[no-]extension [EXTS]', Array) do |v|
 | 
						|
      $extension = (v == false ? [] : v)
 | 
						|
    end
 | 
						|
    opts.on('--[no-]extstatic [STATIC]', Array) do |v|
 | 
						|
      if ($extstatic = v) == false
 | 
						|
        $extstatic = []
 | 
						|
      elsif v
 | 
						|
        $force_static = true if $extstatic.delete("static")
 | 
						|
        $extstatic = nil if $extstatic.empty?
 | 
						|
      end
 | 
						|
    end
 | 
						|
    opts.on('--dest-dir=DIR') do |v|
 | 
						|
      $destdir = v
 | 
						|
    end
 | 
						|
    opts.on('--extout=DIR') do |v|
 | 
						|
      $extout = (v unless v.empty?)
 | 
						|
    end
 | 
						|
    opts.on('--make=MAKE') do |v|
 | 
						|
      $make = v || 'make'
 | 
						|
    end
 | 
						|
    opts.on('--make-flags=FLAGS', '--mflags', Shellwords) do |v|
 | 
						|
      v.grep(/\A([-\w]+)=(.*)/) {$configure_args["--#{$1}"] = $2}
 | 
						|
      if arg = v.first
 | 
						|
        arg.insert(0, '-') if /\A[^-][^=]*\Z/ =~ arg
 | 
						|
      end
 | 
						|
      $makeflags.concat(v.reject {|arg2| /\AMINIRUBY=/ =~ arg2}.quote)
 | 
						|
      $mflags.concat(v)
 | 
						|
    end
 | 
						|
    opts.on('--message [MESSAGE]', String) do |v|
 | 
						|
      $message = v
 | 
						|
    end
 | 
						|
    opts.on('--command-output=FILE', String) do |v|
 | 
						|
      $command_output = v
 | 
						|
    end
 | 
						|
    opts.on('--gnumake=yes|no', true) do |v|
 | 
						|
      $gnumake = v
 | 
						|
    end
 | 
						|
    opts.on('--extflags=FLAGS') do |v|
 | 
						|
      $extflags = v || ""
 | 
						|
    end
 | 
						|
  end
 | 
						|
  begin
 | 
						|
    $optparser.parse!(ARGV)
 | 
						|
  rescue OptionParser::InvalidOption => e
 | 
						|
    retry if /^--/ =~ e.args[0]
 | 
						|
    $optparser.warn(e)
 | 
						|
    abort $optparser.to_s
 | 
						|
  end
 | 
						|
  $command_output or abort "--command-output option is mandatory"
 | 
						|
 | 
						|
  $destdir ||= ''
 | 
						|
 | 
						|
  $make, *rest = Shellwords.shellwords($make)
 | 
						|
  $mflags.unshift(*rest) unless rest.empty?
 | 
						|
 | 
						|
  def $mflags.set?(flag)
 | 
						|
    grep(/\A-(?!-).*#{flag.chr}/i) { return true }
 | 
						|
    false
 | 
						|
  end
 | 
						|
  def $mflags.defined?(var)
 | 
						|
    grep(/\A#{var}=(.*)/) {return $1}
 | 
						|
    false
 | 
						|
  end
 | 
						|
 | 
						|
  if $mflags.set?(?n)
 | 
						|
    $dryrun = true
 | 
						|
  else
 | 
						|
    $mflags.unshift '-n' if $dryrun
 | 
						|
  end
 | 
						|
 | 
						|
  $continue = $mflags.set?(?k)
 | 
						|
  if $extout
 | 
						|
    $extout = '$(topdir)/'+$extout
 | 
						|
    RbConfig::CONFIG["extout"] = CONFIG["extout"] = $extout
 | 
						|
    $extout_prefix = $extout ? "$(extout)$(target_prefix)/" : ""
 | 
						|
    $mflags << "extout=#$extout" << "extout_prefix=#$extout_prefix"
 | 
						|
  end
 | 
						|
end
 | 
						|
 | 
						|
parse_args()
 | 
						|
 | 
						|
if target = ARGV.shift and /^[a-z-]+$/ =~ target
 | 
						|
  $mflags.push(target)
 | 
						|
  case target
 | 
						|
  when /^(dist|real)?(clean)$/, /^install\b/
 | 
						|
    abort "#{target} is obsolete"
 | 
						|
  when /configure/
 | 
						|
    $subconfigure = !ARGV.empty?
 | 
						|
  end
 | 
						|
end
 | 
						|
unless $message
 | 
						|
  if target
 | 
						|
    $message = target.sub(/^(\w+?)e?\b/, '\1ing').tr('-', ' ')
 | 
						|
  else
 | 
						|
    $message = "compiling"
 | 
						|
  end
 | 
						|
end
 | 
						|
 | 
						|
EXEEXT = CONFIG['EXEEXT']
 | 
						|
if CROSS_COMPILING
 | 
						|
  $ruby = $mflags.defined?("MINIRUBY") || CONFIG['MINIRUBY']
 | 
						|
elsif sep = config_string('BUILD_FILE_SEPARATOR')
 | 
						|
  $ruby = "$(topdir:/=#{sep})#{sep}miniruby" + EXEEXT
 | 
						|
else
 | 
						|
  $ruby = '$(topdir)/miniruby' + EXEEXT
 | 
						|
end
 | 
						|
$ruby = [$ruby]
 | 
						|
$ruby << "-I'$(topdir)'"
 | 
						|
unless CROSS_COMPILING
 | 
						|
  $ruby << "-I'$(top_srcdir)/lib'"
 | 
						|
  $ruby << "-I'$(extout)/$(arch)'" << "-I'$(extout)/common'" if $extout
 | 
						|
  ENV["RUBYLIB"] = "-"
 | 
						|
end
 | 
						|
topruby = $ruby
 | 
						|
$ruby = topruby.join(' ')
 | 
						|
$mflags << "ruby=#$ruby"
 | 
						|
 | 
						|
MTIMES = [__FILE__, 'rbconfig.rb', srcdir+'/lib/mkmf.rb'].collect {|f| File.mtime(f)}
 | 
						|
 | 
						|
# get static-link modules
 | 
						|
$static_ext = {}
 | 
						|
if $extstatic
 | 
						|
  $extstatic.each do |t|
 | 
						|
    target = t
 | 
						|
    target = target.downcase if File::FNM_SYSCASE.nonzero?
 | 
						|
    $static_ext[target] = $static_ext.size
 | 
						|
  end
 | 
						|
end
 | 
						|
for dir in ["ext", File::join($top_srcdir, "ext")]
 | 
						|
  setup = File::join(dir, CONFIG['setup'])
 | 
						|
  if File.file? setup
 | 
						|
    f = open(setup)
 | 
						|
    while line = f.gets()
 | 
						|
      line.chomp!
 | 
						|
      line.sub!(/#.*$/, '')
 | 
						|
      next if /^\s*$/ =~ line
 | 
						|
      target, opt = line.split(nil, 3)
 | 
						|
      if target == 'option'
 | 
						|
	case opt
 | 
						|
	when 'nodynamic'
 | 
						|
	  $nodynamic = true
 | 
						|
	end
 | 
						|
	next
 | 
						|
      end
 | 
						|
      target = target.downcase if File::FNM_SYSCASE.nonzero?
 | 
						|
      $static_ext[target] = $static_ext.size
 | 
						|
    end
 | 
						|
    MTIMES << f.mtime
 | 
						|
    $setup = setup
 | 
						|
    f.close
 | 
						|
    break
 | 
						|
  end
 | 
						|
end unless $extstatic
 | 
						|
 | 
						|
@gemname = nil
 | 
						|
if ARGV[0]
 | 
						|
  ext_prefix, exts = ARGV.shift.split('/', 2)
 | 
						|
  $extension = [exts] if exts
 | 
						|
  if ext_prefix == 'gems'
 | 
						|
    @gemname = exts
 | 
						|
  elsif exts
 | 
						|
    $static_ext.delete_if {|t, *| !File.fnmatch(t, exts)}
 | 
						|
  end
 | 
						|
end
 | 
						|
ext_prefix = "#{$top_srcdir}/#{ext_prefix || 'ext'}"
 | 
						|
exts = $static_ext.sort_by {|t, i| i}.collect {|t, i| t}
 | 
						|
default_exclude_exts =
 | 
						|
  case
 | 
						|
  when $cygwin
 | 
						|
    %w''
 | 
						|
  when $mswin, $mingw
 | 
						|
    %w'pty syslog'
 | 
						|
  else
 | 
						|
    %w'*win32*'
 | 
						|
  end
 | 
						|
mandatory_exts = {}
 | 
						|
withes, withouts = [["--with", nil], ["--without", default_exclude_exts]].collect {|w, d|
 | 
						|
  if !(w = %w[-extensions -ext].collect {|o|arg_config(w+o)}).any?
 | 
						|
    d ? proc {|c1| d.any?(&c1)} : proc {true}
 | 
						|
  elsif (w = w.grep(String)).empty?
 | 
						|
    proc {true}
 | 
						|
  else
 | 
						|
    w = w.collect {|o| o.split(/,/)}.flatten
 | 
						|
    w.collect! {|o| o == '+' ? d : o}.flatten!
 | 
						|
    proc {|c1| w.any?(&c1)}
 | 
						|
  end
 | 
						|
}
 | 
						|
cond = proc {|ext, *|
 | 
						|
  withes.call(proc {|n|
 | 
						|
                !n or (mandatory_exts[ext] = true if File.fnmatch(n, ext))
 | 
						|
              }) and
 | 
						|
    !withouts.call(proc {|n| File.fnmatch(n, ext)})
 | 
						|
}
 | 
						|
($extension || %w[*]).each do |e|
 | 
						|
  e = e.sub(/\A(?:\.\/)+/, '')
 | 
						|
  incl, excl = Dir.glob("#{ext_prefix}/#{e}/**/extconf.rb").collect {|d|
 | 
						|
    d = File.dirname(d)
 | 
						|
    d.slice!(0, ext_prefix.length + 1)
 | 
						|
    d
 | 
						|
  }.partition {|ext|
 | 
						|
    with_config(ext, &cond)
 | 
						|
  }
 | 
						|
  incl.sort!
 | 
						|
  excl.sort!.collect! {|d| d+"/"}
 | 
						|
  nil while incl.reject! {|d| excl << d+"/" if excl.any? {|x| d.start_with?(x)}}
 | 
						|
  exts |= incl
 | 
						|
  if $LIBRUBYARG_SHARED.empty? and CONFIG["EXTSTATIC"] == "static"
 | 
						|
    exts.delete_if {|d| File.fnmatch?("-*", d)}
 | 
						|
  end
 | 
						|
end
 | 
						|
ext_prefix = File.basename(ext_prefix)
 | 
						|
 | 
						|
extend Module.new {
 | 
						|
  def timestamp_file(name, target_prefix = nil)
 | 
						|
    if @gemname and name == '$(TARGET_SO_DIR)'
 | 
						|
      name = "$(arch)/gems/#{@gemname}#{target_prefix}"
 | 
						|
    end
 | 
						|
    super.sub(%r[/\.extout\.(?:-\.)?], '/.')
 | 
						|
  end
 | 
						|
 | 
						|
  def configuration(srcdir)
 | 
						|
    super << "EXTSO #{['=', $extso].join(' ')}\n"
 | 
						|
  end
 | 
						|
 | 
						|
  def create_makefile(*args, &block)
 | 
						|
    return super unless @gemname
 | 
						|
    super(*args) do |conf|
 | 
						|
      conf.find do |s|
 | 
						|
        s.sub!(/^(TARGET_SO_DIR *= *)\$\(RUBYARCHDIR\)/) {
 | 
						|
          "TARGET_GEM_DIR = $(extout)/gems/$(arch)/#{@gemname}\n"\
 | 
						|
          "#{$1}$(TARGET_GEM_DIR)$(target_prefix)"
 | 
						|
        }
 | 
						|
      end
 | 
						|
      conf.any? {|s| /^TARGET *= *\S/ =~ s} and conf << %{
 | 
						|
 | 
						|
# default target
 | 
						|
all:
 | 
						|
 | 
						|
build_complete = $(TARGET_GEM_DIR)/gem.build_complete
 | 
						|
install-so: build_complete
 | 
						|
build_complete: $(build_complete)
 | 
						|
$(build_complete): $(TARGET_SO)
 | 
						|
	$(Q) $(TOUCH) $@
 | 
						|
 | 
						|
clean-so::
 | 
						|
	-$(Q)$(RM) $(build_complete)
 | 
						|
}
 | 
						|
      conf
 | 
						|
    end
 | 
						|
  end
 | 
						|
}
 | 
						|
 | 
						|
dir = Dir.pwd
 | 
						|
FileUtils::makedirs(ext_prefix)
 | 
						|
Dir::chdir(ext_prefix)
 | 
						|
 | 
						|
hdrdir = $hdrdir
 | 
						|
$hdrdir = ($top_srcdir = relative_from(srcdir, $topdir = "..")) + "/include"
 | 
						|
extso = []
 | 
						|
fails = []
 | 
						|
exts.each do |d|
 | 
						|
  $static = $force_static ? true : $static_ext[d]
 | 
						|
 | 
						|
  if !$nodynamic or $static
 | 
						|
    result = extmake(d, ext_prefix, !@gemname) or abort
 | 
						|
    extso |= $extso
 | 
						|
    fails << [d, result] unless result == true
 | 
						|
  end
 | 
						|
end
 | 
						|
 | 
						|
$top_srcdir = srcdir
 | 
						|
$topdir = "."
 | 
						|
$hdrdir = hdrdir
 | 
						|
 | 
						|
extinit = Struct.new(:c, :o) {
 | 
						|
  def initialize(src)
 | 
						|
    super("#{src}.c", "#{src}.#{$OBJEXT}")
 | 
						|
  end
 | 
						|
}.new("extinit")
 | 
						|
 | 
						|
$extobjs ||= []
 | 
						|
$extpath ||= []
 | 
						|
$extflags ||= ""
 | 
						|
$extlibs ||= []
 | 
						|
extinits = []
 | 
						|
unless $extlist.empty?
 | 
						|
  list = $extlist.dup
 | 
						|
  built = []
 | 
						|
  while e = list.shift
 | 
						|
    static, target, feature, required = e
 | 
						|
    next unless static
 | 
						|
    if required and !(required -= built).empty?
 | 
						|
      l = list.size
 | 
						|
      if (while l > 0; break true if required.include?(list[l-=1][1]) end)
 | 
						|
        list.insert(l + 1, e)
 | 
						|
      end
 | 
						|
      next
 | 
						|
    end
 | 
						|
    base = File.basename(feature)
 | 
						|
    extinits << feature
 | 
						|
    $extobjs << format("ext/%s/%s.%s", target, base, $LIBEXT)
 | 
						|
    built << target
 | 
						|
  end
 | 
						|
 | 
						|
  $extpath.delete("$(topdir)")
 | 
						|
  $extflags = libpathflag($extpath) << " " << $extflags.strip
 | 
						|
  conf = [
 | 
						|
    ['LIBRUBY_SO_UPDATE', '$(LIBRUBY_EXTS)'],
 | 
						|
    ['SETUP', $setup],
 | 
						|
    ['EXTLIBS', $extlibs.join(' ')], ['EXTLDFLAGS', $extflags]
 | 
						|
  ].map {|n, v|
 | 
						|
    "#{n}=#{v}" if v &&= v[/\S(?:.*\S)?/]
 | 
						|
  }.compact
 | 
						|
  puts(*conf) unless $subconfigure
 | 
						|
  $stdout.flush
 | 
						|
  $mflags.concat(conf)
 | 
						|
  $makeflags.concat(conf)
 | 
						|
else
 | 
						|
  FileUtils.rm_f(extinit.to_a)
 | 
						|
end
 | 
						|
rubies = []
 | 
						|
%w[RUBY RUBYW STATIC_RUBY].each {|n|
 | 
						|
  r = n
 | 
						|
  if r = arg_config("--"+r.downcase) || config_string(r+"_INSTALL_NAME")
 | 
						|
    rubies << RbConfig.expand(r+=EXEEXT)
 | 
						|
    $mflags << "#{n}=#{r}"
 | 
						|
  end
 | 
						|
}
 | 
						|
 | 
						|
Dir.chdir ".."
 | 
						|
unless $destdir.to_s.empty?
 | 
						|
  $mflags.defined?("DESTDIR") or $mflags << "DESTDIR=#{$destdir}"
 | 
						|
end
 | 
						|
$makeflags.uniq!
 | 
						|
 | 
						|
$mflags.unshift("topdir=#$topdir")
 | 
						|
ENV.delete("RUBYOPT")
 | 
						|
exts.map! {|d| "#{ext_prefix}/#{d}/."}
 | 
						|
FileUtils.makedirs(File.dirname($command_output))
 | 
						|
begin
 | 
						|
  atomic_write_open($command_output) do |mf|
 | 
						|
    mf.puts "V = 0"
 | 
						|
    mf.puts "Q1 = $(V:1=)"
 | 
						|
    mf.puts "Q = $(Q1:0=@)"
 | 
						|
    mf.puts "ECHO1 = $(V:1=@:)"
 | 
						|
    mf.puts "ECHO = $(ECHO1:0=@echo)"
 | 
						|
    mf.puts "MFLAGS = -$(MAKEFLAGS)" if $nmake
 | 
						|
    mf.puts
 | 
						|
 | 
						|
    def mf.macro(name, values, max = 70)
 | 
						|
      print name, " ="
 | 
						|
      w = w0 = name.size + 2
 | 
						|
      h = " \\\n" + "\t" * (w / 8) + " " * (w % 8)
 | 
						|
      values.each do |s|
 | 
						|
        if s.size + w > max
 | 
						|
          print h
 | 
						|
          w = w0
 | 
						|
        end
 | 
						|
        print " ", s
 | 
						|
        w += s.size + 1
 | 
						|
      end
 | 
						|
      puts
 | 
						|
    end
 | 
						|
 | 
						|
    mf.macro "ruby", topruby
 | 
						|
    mf.macro "RUBY", ["$(ruby)"]
 | 
						|
    mf.macro "extensions", exts
 | 
						|
    mf.macro "EXTOBJS", $extlist.empty? ? ["dmyext.#{$OBJEXT}"] : ["ext/extinit.#{$OBJEXT}", *$extobjs]
 | 
						|
    mf.macro "EXTLIBS", $extlibs
 | 
						|
    mf.macro "EXTSO", extso
 | 
						|
    mf.macro "EXTLDFLAGS", $extflags.split
 | 
						|
    mf.macro "EXTINITS", extinits
 | 
						|
    submakeopts = []
 | 
						|
    if enable_config("shared", $enable_shared)
 | 
						|
      submakeopts << 'DLDOBJS="$(EXTOBJS) $(EXTENCS)"'
 | 
						|
      submakeopts << 'EXTOBJS='
 | 
						|
      submakeopts << 'EXTSOLIBS="$(EXTLIBS)"'
 | 
						|
      submakeopts << 'LIBRUBY_SO_UPDATE=$(LIBRUBY_EXTS)'
 | 
						|
    else
 | 
						|
      submakeopts << 'EXTOBJS="$(EXTOBJS) $(EXTENCS)"'
 | 
						|
      submakeopts << 'EXTLIBS="$(EXTLIBS)"'
 | 
						|
    end
 | 
						|
    submakeopts << 'EXTLDFLAGS="$(EXTLDFLAGS)"'
 | 
						|
    submakeopts << 'EXTINITS="$(EXTINITS)"'
 | 
						|
    submakeopts << 'UPDATE_LIBRARIES="$(UPDATE_LIBRARIES)"'
 | 
						|
    submakeopts << 'SHOWFLAGS='
 | 
						|
    mf.macro "SUBMAKEOPTS", submakeopts
 | 
						|
    mf.macro "NOTE_MESG", %w[$(RUBY) $(top_srcdir)/tool/lib/colorize.rb skip]
 | 
						|
    mf.macro "NOTE_NAME", %w[$(RUBY) $(top_srcdir)/tool/lib/colorize.rb fail]
 | 
						|
    mf.puts
 | 
						|
    targets = %w[all install static install-so install-rb clean distclean realclean]
 | 
						|
    targets.each do |tgt|
 | 
						|
      mf.puts "#{tgt}: $(extensions:/.=/#{tgt})"
 | 
						|
      mf.puts "#{tgt}: note" unless /clean\z/ =~ tgt
 | 
						|
    end
 | 
						|
    mf.puts
 | 
						|
    mf.puts "clean:\n\t-$(Q)$(RM) ext/extinit.#{$OBJEXT}"
 | 
						|
    mf.puts "distclean:\n\t-$(Q)$(RM) ext/extinit.c"
 | 
						|
    mf.puts
 | 
						|
    mf.puts "#{rubies.join(' ')}: $(extensions:/.=/#{$force_static ? 'static' : 'all'})"
 | 
						|
    submake = "$(Q)$(MAKE) $(MFLAGS) $(SUBMAKEOPTS)"
 | 
						|
    mf.puts "all static: #{rubies.join(' ')}\n"
 | 
						|
    $extobjs.each do |tgt|
 | 
						|
      mf.puts "#{tgt}: #{File.dirname(tgt)}/static"
 | 
						|
    end
 | 
						|
    mf.puts "#{rubies.join(' ')}: $(EXTOBJS)#{' libencs' if CONFIG['ENCSTATIC'] == 'static'}"
 | 
						|
    rubies.each do |tgt|
 | 
						|
      mf.puts "#{tgt}:\n\t#{submake} $@"
 | 
						|
    end
 | 
						|
    mf.puts "libencs:\n\t$(Q)$(MAKE) -f enc.mk V=$(V) $@"
 | 
						|
    mf.puts "ext/extinit.#{$OBJEXT}:\n\t$(Q)$(MAKE) $(MFLAGS) V=$(V) EXTINITS=\"$(EXTINITS)\" $@" if $static
 | 
						|
    mf.puts
 | 
						|
    if $gnumake == "yes"
 | 
						|
      submake = "$(MAKE) -C $(@D)"
 | 
						|
    else
 | 
						|
      submake = "cd $(@D) && "
 | 
						|
      config_string("exec") {|str| submake << str << " "}
 | 
						|
      submake << "$(MAKE)"
 | 
						|
    end
 | 
						|
    targets.each do |tgt|
 | 
						|
      exts.each do |d|
 | 
						|
        d = d[0..-2]
 | 
						|
        t = "#{d}#{tgt}"
 | 
						|
        if  /^(dist|real)?clean$/ =~ tgt
 | 
						|
          deps = exts.select {|e|e.start_with?(d)}.map {|e|"#{e[0..-2]}#{tgt}"} - [t]
 | 
						|
          pd = ' ' + deps.join(' ') unless deps.empty?
 | 
						|
        else
 | 
						|
          pext = File.dirname(d)
 | 
						|
          pd = " #{pext}/#{tgt}" if exts.include?("#{pext}/.")
 | 
						|
        end
 | 
						|
        mf.puts "#{t}:#{pd}\n\t$(Q)#{submake} $(MFLAGS) V=$(V) $(@F)"
 | 
						|
      end
 | 
						|
    end
 | 
						|
    mf.puts "\n""extso:\n"
 | 
						|
    mf.puts "\t@echo EXTSO=$(EXTSO)"
 | 
						|
 | 
						|
    mf.puts "\n""note:\n"
 | 
						|
    unless fails.empty?
 | 
						|
      abandon = false
 | 
						|
      mf.puts "note: note-body\n"
 | 
						|
      mf.puts "note-body:: note-header\n"
 | 
						|
      mf.puts "note-header:\n"
 | 
						|
      mf.puts %Q<\t@$(NOTE_MESG) "*** Following extensions are not compiled:">
 | 
						|
      mf.puts "note-body:: note-header\n"
 | 
						|
      fails.each do |ext, (parent, err)|
 | 
						|
        abandon ||= mandatory_exts[ext]
 | 
						|
        mf.puts %Q<\t@$(NOTE_NAME) "#{ext}:">
 | 
						|
        if parent
 | 
						|
          mf.puts %Q<\t@echo "\tCould not be configured. It will not be installed.">
 | 
						|
          err and err.scan(/.+/) do |ee|
 | 
						|
            mf.puts %Q<\t@echo "\t#{ee.gsub(/["`$^]/, '\\\\\\&')}">
 | 
						|
          end
 | 
						|
          mf.puts %Q<\t@echo "\tCheck #{ext_prefix}/#{ext}/mkmf.log for more details.">
 | 
						|
        else
 | 
						|
          mf.puts %Q<\t@echo "\tSkipped because its parent was not configured.">
 | 
						|
        end
 | 
						|
      end
 | 
						|
      mf.puts "note:\n"
 | 
						|
      mf.puts %Q<\t@$(NOTE_MESG) "*** Fix the problems, then remove these directories and try again if you want.">
 | 
						|
      if abandon
 | 
						|
        mf.puts "\t""@exit 1"
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
end
 | 
						|
# :startdoc:
 | 
						|
 | 
						|
#Local variables:
 | 
						|
# mode: ruby
 | 
						|
#end:
 |