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