diff options
Diffstat (limited to 'ext/extmk.rb')
| -rwxr-xr-x | ext/extmk.rb | 490 |
1 files changed, 259 insertions, 231 deletions
diff --git a/ext/extmk.rb b/ext/extmk.rb index 04d374ece6..f5244f72c8 100755 --- a/ext/extmk.rb +++ b/ext/extmk.rb @@ -2,24 +2,27 @@ # -*- mode: ruby; coding: us-ascii -*- # frozen_string_literal: false +module Gem + # Used by Gem::Platform.local + def self.target_rbconfig + RbConfig::CONFIG + end +end + # :stopdoc: $extension = nil $extstatic = nil $force_static = nil -$install = nil $destdir = nil $dryrun = false -$clean = nil $nodynamic = nil -$extinit = nil $extobjs = [] $extflags = "" $extlibs = nil $extpath = nil -$ignore = nil $message = nil $command_output = nil -$configure_only = false +$subconfigure = false $progname = $0 alias $PROGRAM_NAME $0 @@ -31,23 +34,23 @@ 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]) + $:.replace([Dir.pwd, File.expand_path("lib", srcdir)]) end -$:.unshift(srcdir) require 'rbconfig' +# only needs Gem::Platform +require 'rubygems/platform' + $topdir = "." $top_srcdir = srcdir +$extmk = true +inplace = File.identical?($top_srcdir, $topdir) $" << "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 +@null = File::NULL def verbose? $mflags.defined?("V") == "1" @@ -66,12 +69,17 @@ end def atomic_write_open(filename) filename_new = filename + ".new.#$$" - open(filename_new, "wb") do |f| + clean = false + File.open(filename_new, "wbx") do |f| + clean = true yield f end if File.binread(filename_new) != (File.binread(filename) rescue nil) File.rename(filename_new, filename) - else + clean = false + end +ensure + if clean File.unlink(filename_new) end end @@ -103,10 +111,10 @@ def extract_makefile(makefile, keep = true) end return false end - srcs = Dir[File.join($srcdir, "*.{#{SRC_EXT.join(%q{,})}}")].map {|fn| File.basename(fn)}.sort + srcs = Dir[*SRC_EXT.map {|e| "*.#{e}"}, base: $srcdir].map {|fn| File.basename(fn)}.sort if !srcs.empty? old_srcs = m[/^ORIG_SRCS[ \t]*=[ \t](.*)/, 1] or return false - old_srcs.split.sort == srcs or return false + (old_srcs.split - srcs).empty? or return false end $target = target $extconf_h = m[/^RUBY_EXTCONF_H[ \t]*=[ \t]*(\S+)/, 1] @@ -131,12 +139,7 @@ def extract_makefile(makefile, keep = true) true end -def extmake(target, basedir = (maybestatic = 'ext')) - unless $configure_only || verbose? - print "#{$message} #{target}\n" - $stdout.flush - 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 @@ -144,7 +147,7 @@ def extmake(target, basedir = (maybestatic = 'ext')) 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) + parent = (/^all:\s*install/ =~ File.read("#{d}/Makefile") rescue false) break end end @@ -155,7 +158,7 @@ def extmake(target, basedir = (maybestatic = 'ext')) top_srcdir = $top_srcdir topdir = $topdir hdrdir = $hdrdir - prefix = "../" * (target.count("/")+1) + prefix = "../" * (basedir.count("/")+target.count("/")+1) $top_srcdir = relative_from(top_srcdir, prefix) $hdrdir = relative_from(hdrdir, prefix) $topdir = prefix + $topdir @@ -163,14 +166,12 @@ def extmake(target, basedir = (maybestatic = 'ext')) $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 && !$ignore + if parent rbconfig0 = RbConfig::CONFIG mkconfig0 = CONFIG rbconfig = { @@ -198,7 +199,7 @@ def extmake(target, basedir = (maybestatic = 'ext')) begin $extconf_h = nil ok &&= extract_makefile(makefile) - old_objs = $objs + 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)) || @@ -206,14 +207,12 @@ def extmake(target, basedir = (maybestatic = 'ext')) [conf, "#{$srcdir}/depend"].any? {|f| modified?(f, [t])}) then ok = false - if $configure_only - if verbose? - print "#{conf}\n" if conf - else - print "#{$message} #{target}\n" - end - $stdout.flush + if verbose? + print "#{conf}\n" if conf + else + print "#{$message} #{target}\n" end + $stdout.flush init_mkmf Logging::logfile 'mkmf.log' rm_f makefile @@ -233,7 +232,6 @@ def extmake(target, basedir = (maybestatic = 'ext')) rescue SystemExit # ignore rescue => error - lineno = error.backtrace_locations[0].lineno ok = false ensure rm_f "conftest*" @@ -249,38 +247,29 @@ def extmake(target, basedir = (maybestatic = 'ext')) return true if !error and target.start_with?("-") - if parent - message = "Failed to configure #{target}. It will not be installed." - else - message = "Skipped to configure #{target}. Its parent is not configured." - end - if Logging.log_opened? - Logging::message(error.to_s) if error - Logging::message(message) + 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 - message = error.message if error - return parent ? [conf, lineno||0, message] : true + return [parent, message] end args = $mflags unless $destdir.to_s.empty? or $mflags.defined?("DESTDIR") args += ["DESTDIR=" + relative_from($destdir, "../"+prefix)] end + $objs ||= [] + $srcs ||= [] if $static and ok and !$objs.empty? and !noinstall - args += ["static"] unless $clean + args += ["static"] $extlist.push [(maybestatic ? $static : false), target, $target, $preload] end FileUtils.rm_f(old_cleanfiles - $distcleanfiles - $cleanfiles) FileUtils.rm_f(old_objs - $objs) - unless $configure_only or system($make, *args) - $ignore or $continue or return false - end - if $clean - FileUtils.rm_f("mkmf.log") - if $clean != true - FileUtils.rm_f([makefile, $extconf_h || "extconf.h"]) - end - end if $static $extflags ||= "" $extlibs ||= [] @@ -376,6 +365,7 @@ def parse_args() $optparser.warn(e) abort $optparser.to_s end + $command_output or abort "--command-output option is mandatory" $destdir ||= '' @@ -411,18 +401,10 @@ parse_args() if target = ARGV.shift and /^[a-z-]+$/ =~ target $mflags.push(target) case target - when /^(dist|real)?(clean)$/ - target = $2 - $ignore ||= true - $clean = $1 ? $1[0] : true - when /^install\b/ - $install = true - $ignore ||= true - $mflags.unshift("INSTALL_PROG=install -c -p -m 0755", - "INSTALL_DATA=install -c -p -m 0644", - "MAKEDIRS=mkdir -p") if $dryrun + when /^(dist|real)?(clean)$/, /^install\b/ + abort "#{target} is obsolete" when /configure/ - $configure_only = true + $subconfigure = !ARGV.empty? end end unless $message @@ -438,16 +420,22 @@ if CROSS_COMPILING $ruby = $mflags.defined?("MINIRUBY") || CONFIG['MINIRUBY'] elsif sep = config_string('BUILD_FILE_SEPARATOR') $ruby = "$(topdir:/=#{sep})#{sep}miniruby" + EXEEXT -else +elsif CONFIG['EXTSTATIC'] $ruby = '$(topdir)/miniruby' + EXEEXT +else + $ruby = '$(topdir)/ruby' + EXEEXT end -$ruby << " -I'$(topdir)'" +$ruby = [$ruby] +$ruby << "-I'$(topdir)'" unless CROSS_COMPILING - $ruby << " -I'$(top_srcdir)/lib'" - $ruby << " -I'$(extout)/$(arch)' -I'$(extout)/common'" if $extout + $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" +$builtruby = '$(topdir)/miniruby' + EXEEXT # Must be an executable path MTIMES = [__FILE__, 'rbconfig.rb', srcdir+'/lib/mkmf.rb'].collect {|f| File.mtime(f)} @@ -462,9 +450,8 @@ if $extstatic 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() + if (f = File.stat(setup) and f.file? rescue next) + File.foreach(setup) do |line| line.chomp! line.sub!(/#.*$/, '') next if /^\s*$/ =~ line @@ -481,13 +468,24 @@ for dir in ["ext", File::join($top_srcdir, "ext")] end MTIMES << f.mtime $setup = setup - f.close break end end unless $extstatic -ext_prefix = "#{$top_srcdir}/ext" -exts = $static_ext.sort_by {|t, i| i}.collect {|t, i| t} +@gemname = nil +if exts = ARGV.shift + ext_prefix = exts[%r[\A(?>\.bundle/)?[^/]+(?:/(?=(.+)?)|\z)]] + exts = $1 + $extension = [exts] if exts + if ext_prefix.start_with?('.') + @gemname = exts + exts = [] + else + exts &&= $static_ext.select {|t, *| File.fnmatch(t, exts)} + end +end +ext_prefix ||= 'ext' +exts = (exts || $static_ext).sort_by {|t, i| i}.collect {|t, i| t} default_exclude_exts = case when $cygwin @@ -497,122 +495,170 @@ default_exclude_exts = 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} + 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! if d - proc {|c1| w.any?(&c1)} + w.collect! {|o| o == '+' ? d : o}.flatten! + proc {|&c1| w.any?(&c1)} end } cond = proc {|ext, *| - cond1 = proc {|n| File.fnmatch(n, ext)} - withes.call(cond1) and !withouts.call(cond1) + withes.call {|n| !n or (mandatory_exts[ext] = true if File.fnmatch(n, ext))} and + !withouts.call {|n| File.fnmatch(n, ext)} } ($extension || %w[*]).each do |e| e = e.sub(/\A(?:\.\/)+/, '') - exts |= Dir.glob("#{ext_prefix}/#{e}/**/extconf.rb").collect {|d| - d = File.dirname(d) - d.slice!(0, ext_prefix.length + 1) - d - }.find_all {|ext| + incl, excl = Dir.glob("#{e}/**/extconf.rb", base: "#$top_srcdir/#{ext_prefix}").collect {|d| + File.dirname(d) + }.partition {|ext| + if @gemname + ext = ext[%r[\A[^/]+]] # extract gem name + Dir.glob("*.gemspec", base: "#$top_srcdir/#{ext_prefix}/#{ext}") do |g| + break ext = g if ext.start_with?("#{g.chomp!(".gemspec")}-") + end + end with_config(ext, &cond) - }.sort + } + 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.chomp!("/") -if $extout - extout = RbConfig.expand("#{$extout}", RbConfig::CONFIG.merge("topdir"=>$topdir)) - unless $ignore - FileUtils.mkpath("#{extout}/gems") - end -end - -FileUtils.makedirs('gems') -ext_prefix = "#$top_srcdir/gems" -gems = Dir.glob(File.join(ext_prefix, ($extension || ''), '**/extconf.rb')).collect {|d| - d = File.dirname(d) - d.slice!(0, ext_prefix.length + 1) - d -}.find_all {|ext| - with_config(ext, &cond) -}.sort - +@ext_prefix = ext_prefix +@inplace = inplace extend Module.new { + def timestamp_file(name, target_prefix = nil) - super.sub(%r[/\.extout\.(?:-\.)?], '/.') + if @gemname and name == '$(TARGET_SO_DIR)' + gem = true + name = "$(gem_platform)/$(ruby_version)/gems/#{@gemname}#{target_prefix}" + end + path = super.sub(%r[/\.extout\.(?:-\.)?], '/.') + if gem + nil while path.sub!(%r[/\.(gem_platform|ruby_version)\.-(?=\.)], '/$(\1)/') + end + path end def configuration(srcdir) super << "EXTSO #{['=', $extso].join(' ')}\n" end -} - -dir = Dir.pwd -FileUtils::makedirs('ext') -Dir::chdir('ext') - -hdrdir = $hdrdir -$hdrdir = ($top_srcdir = relative_from(srcdir, $topdir = "..")) + "/include" -extso = [] -fails = [] -exts.each do |d| - $static = $force_static ? true : $static_ext[d] - - if $ignore or !$nodynamic or $static - result = extmake(d) or abort - extso |= $extso - fails << result unless result == true - end -end - -Dir.chdir('..') -FileUtils::makedirs('gems') -Dir.chdir('gems') -extout = $extout -unless gems.empty? - def self.timestamp_file(name, target_prefix = nil) - name = "$(arch)/gems/#{@gemname}#{target_prefix}" if name == '$(TARGET_SO_DIR)' - super - end - def self.create_makefile(*args, &block) + def create_makefile(*args, &block) + unless @gemname + if $static and (target = args.first).include?("/") + base = File.basename(target) + $defs << "-DInit_#{base}=Init_#{target.tr('/', '_')}" + $defs << "-DInitVM_#{base}=InitVM_#{target.tr('/', '_')}" + end + return super + end super(*args) do |conf| conf.find do |s| + s.sub!(%r(^(srcdir *= *)\$\(top_srcdir\)/\.bundle/gems/[^/]+(?=/))) { + "gem_#{$&}\n" "#{$1}$(gem_srcdir)" + } + s.sub!(/^(TIMESTAMP_DIR *= *)\$\(extout\)/) { + "TARGET_TOPDIR = $(topdir)/.bundle\n" "#{$1}$(TARGET_TOPDIR)" + } s.sub!(/^(TARGET_SO_DIR *= *)\$\(RUBYARCHDIR\)/) { - "TARGET_GEM_DIR = $(extout)/gems/$(arch)/#{@gemname}\n"\ + "TARGET_GEM_DIR = $(TARGET_TOPDIR)/extensions/$(gem_platform)"\ + "/$(ruby_version)#{$enable_shared ? '' : '-static'}/#{@gemname}\n"\ "#{$1}$(TARGET_GEM_DIR)$(target_prefix)" } end - conf.any? {|s| /^TARGET *= *\S/ =~ s} and conf << %{ + + conf = yield conf if block + + if conf.any? {|s| /^TARGET *= *\S/ =~ s} + conf << %{ +gem_platform = #{Gem::Platform.local} # default target all: +gem = #{@gemname} + build_complete = $(TARGET_GEM_DIR)/gem.build_complete install-so: build_complete +clean-so:: clean-build_complete +$(build_complete) $(OBJS): $(TARGET_SO_DIR_TIMESTAMP) + build_complete: $(build_complete) $(build_complete): $(TARGET_SO) $(Q) $(TOUCH) $@ +clean-build_complete: + -$(Q)$(RM) $(build_complete) + +install: gemspec +clean: clean-gemspec + +gemspec = $(TARGET_TOPDIR)/specifications/$(gem).gemspec +$(gemspec): $(gem_srcdir)/.bundled.$(gem).gemspec + $(Q) $(MAKEDIRS) $(@D) + $(Q) $(COPY) $(gem_srcdir)/.bundled.$(gem).gemspec $@ + +gemspec: $(gemspec) + +clean-gemspec: + -$(Q)$(RM) $(gemspec) + +LN_S = #{config_string('LN_S')} +CP_R = #{config_string('CP')} -r } + unless @inplace + %w[bin lib].each do |d| + next unless File.directory?("#{$top_srcdir}/#{@ext_prefix}/#{@gemname}/#{d}") + conf << %{ +install-rb: gem#{d} +clean-rb:: clean-gem#{d} + +gem#{d} = $(TARGET_TOPDIR)/gems/$(gem)/#{d} +gem#{d}:#{%{ $(gem#{d})\n$(gem#{d}): $(gem_srcdir)/#{d}} if $nmake} + $(Q) $(RUBY) $(top_srcdir)/tool/ln_sr.rb -q -f -T $(gem_srcdir)/#{d} $(gem#{d}) + +clean-gem#{d}: + $(Q) $(RM_RF) $(gem#{d}) +} + end + end + end + 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.fetch(d) do + $static_ext.any? {|t, | File.fnmatch?(t, d)} + end + + if !$nodynamic or $static + result = extmake(d, ext_prefix, !@gemname) or abort + extso |= $extso + fails << [d, result] unless result == true + end end -gems.each do |d| - $extout = extout.dup - @gemname = d[%r{\A[^/]+}] - extmake(d, 'gems') - extso |= $extso -end -$extout = extout -Dir.chdir('../ext') $top_srcdir = srcdir $topdir = "." @@ -623,32 +669,13 @@ extinit = Struct.new(:c, :o) { super("#{src}.c", "#{src}.#{$OBJEXT}") end }.new("extinit") -if $ignore - FileUtils.rm_f(extinit.to_a) if $clean - Dir.chdir ".." - if $clean - Dir.rmdir('ext') rescue nil - if $extout - FileUtils.rm_rf([extout+"/common", extout+"/include/ruby", extout+"/rdoc"]) - FileUtils.rm_rf(extout+"/"+CONFIG["arch"]) - if $clean != true - FileUtils.rm_rf(extout+"/include/"+CONFIG["arch"]) - FileUtils.rm_f($mflags.defined?("INSTALLED_LIST")||ENV["INSTALLED_LIST"]||".installed.list") - Dir.rmdir(extout+"/include") rescue nil - Dir.rmdir(extout) rescue nil - end - end - end - exit -end -$extinit ||= "" $extobjs ||= [] $extpath ||= [] $extflags ||= "" $extlibs ||= [] +extinits = [] unless $extlist.empty? - $extinit << "\n" unless $extinit.empty? list = $extlist.dup built = [] while e = list.shift @@ -662,27 +689,11 @@ unless $extlist.empty? next end base = File.basename(feature) - $extinit << " init(Init_#{base}, \"#{feature}.so\");\n" + extinits << feature $extobjs << format("ext/%s/%s.%s", target, base, $LIBEXT) built << target end - src = %{\ -#include "ruby/ruby.h" - -#define init(func, name) { \\ - extern void func(void); \\ - ruby_init_ext(name, func); \\ -} - -void ruby_init_ext(const char *name, void (*init)(void)); - -void Init_ext(void)\n{\n#$extinit} -} - if !modified?(extinit.c, MTIMES) || IO.read(extinit.c) != src - open(extinit.c, "w") {|fe| fe.print src} - end - $extpath.delete("$(topdir)") $extflags = libpathflag($extpath) << " " << $extflags.strip conf = [ @@ -692,7 +703,7 @@ void Init_ext(void)\n{\n#$extinit} ].map {|n, v| "#{n}=#{v}" if v &&= v[/\S(?:.*\S)?/] }.compact - puts(*conf) + puts(*conf) unless $subconfigure $stdout.flush $mflags.concat(conf) $makeflags.concat(conf) @@ -708,7 +719,7 @@ rubies = [] end } -Dir.chdir ".." +Dir.chdir dir unless $destdir.to_s.empty? $mflags.defined?("DESTDIR") or $mflags << "DESTDIR=#{$destdir}" end @@ -716,16 +727,19 @@ $makeflags.uniq! $mflags.unshift("topdir=#$topdir") ENV.delete("RUBYOPT") -if $configure_only and $command_output - exts.map! {|d| "ext/#{d}/."} - gems.map! {|d| "gems/#{d}/."} +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 "V0 = $(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 "override MFLAGS := $(filter-out -j%,$(MFLAGS))" if $gnumake + mf.puts "ext_build_dir = #{File.dirname($command_output)}" mf.puts def mf.macro(name, values, max = 70) @@ -743,12 +757,14 @@ if $configure_only and $command_output puts end + mf.macro "ruby", topruby + mf.macro "RUBY", ["$(ruby)"] mf.macro "extensions", exts - mf.macro "gems", gems 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)"' @@ -760,21 +776,30 @@ if $configure_only and $command_output submakeopts << 'EXTLIBS="$(EXTLIBS)"' end submakeopts << 'EXTLDFLAGS="$(EXTLDFLAGS)"' - submakeopts << 'UPDATE_LIBRARIES="$(UPDATE_LIBRARIES)"' + submakeopts << 'EXTINITS="$(EXTINITS)"' 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] + %w[RM RMDIRS RMDIR RMALL].each {|w| mf.macro w, [RbConfig::CONFIG[w]]} + if $nmake + message = ['@(for %I in (', ') do @echo.%~I)'] + else + message = ['@for line in', '; do echo "$$line"; done'] + end + mf.macro "MESSAGE_BEGIN", [message.first] + mf.macro "MESSAGE_END", [message.last] 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}: $(gems:/.=/#{tgt})" unless tgt == 'static' 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'}) $(gems:/.=/all)" + 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| @@ -785,63 +810,66 @@ if $configure_only and $command_output 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) $@" if $static + 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)" + submake = ["cd", (sep ? "$(@D:/=#{sep})" : "$(@D)"), "&&"] + config_string("exec") {|str| submake << str} + submake = (submake << "$(MAKE)").join(" ") end - gems = exts + gems targets.each do |tgt| - (tgt == 'static' ? exts : gems).each do |d| - mf.puts "#{d[0..-2]}#{tgt}:\n\t$(Q)#{submake} $(MFLAGS) V=$(V) $(@F)" + exts.each do |d| + d = d[0..-2] + t = "#{d}#{tgt}" + if clean = /^(dist|real)?clean$/.match(tgt) + deps = exts.select {|e|e.start_with?(d)}.map {|e|"#{e[0..-2]}#{tgt}"} - [t] + pd = [' clean-local', *deps].join(' ') + 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)" + if clean and clean.begin(1) + mf.puts "\t$(Q)$(RM) $(ext_build_dir)/exts.mk\n\t$(Q)$(RMDIRS) $(@D)" + end end end + mf.puts "\n""clean-local:\n\t$(Q)$(RM) $(ext_build_dir)/*~ $(ext_build_dir)/*.bak $(ext_build_dir)/core" mf.puts "\n""extso:\n" mf.puts "\t@echo EXTSO=$(EXTSO)" mf.puts "\n""note:\n" unless fails.empty? - mf.puts %Q<\t@echo "*** Following extensions failed to configure:"> - fails.each do |d, n, err| - d = "#{d}:#{n}:" - if err - d << " " << err + 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}:"> + mf.puts "\t$(MESSAGE_BEGIN) \\" + if parent + mf.puts %Q<\t"\tCould not be configured. It will not be installed." \\> + err and err.scan(/.+/) do |ee| + mf.puts %Q<\t"\t#{ee.gsub(/["`$^]/, '\\\\\\&')}" \\> + end + mf.puts %Q<\t"\tCheck #{ext_prefix}/#{ext}/mkmf.log for more details." \\> + else + mf.puts %Q<\t"\tSkipped because its parent was not configured." \\> end - mf.puts %Q<\t@echo "#{d}"> + mf.puts "\t$(MESSAGE_END)" end - mf.puts %Q<\t@echo "*** Fix the problems, then remove these directories and try again if you want."> - end - - end -elsif $command_output - message = "making #{rubies.join(', ')}" - message = "echo #{message}" - $mflags.concat(rubies) - $makeflags.concat(rubies) - cmd = $makeflags.map {|ss|ss.sub(/.*[$(){};\s].*/, %q['\&'])}.join(' ') - open($command_output, 'wb') do |ff| - case $command_output - when /\.sh\z/ - ff.puts message, "rm -f \"$0\"; exec \"$@\" #{cmd}" - when /\.bat\z/ - ["@echo off", message, "%* #{cmd}", "del %0 & exit %ERRORLEVEL%"].each do |ss| - ff.print ss, "\r\n" + 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 - else - ff.puts cmd end - ff.chmod(0755) end -elsif !$configure_only - message = "making #{rubies.join(', ')}" - puts message - $stdout.flush - $mflags.concat(rubies) - system($make, *$mflags) or exit($?.exitstatus) end # :startdoc: |
