# -*- makefile -*- V = 0 V0 = $(V:0=) Q1 = $(V:1=) Q = $(Q1:0=@) ECHO1 = $(V:1=@:) ECHO = $(ECHO1:0=@echo) <% require './rbconfig' macros = {} deps = [] notes = {} rubies = [] exeext = RbConfig::CONFIG['EXEEXT'] gnumake = false confexts = nil opt = OptionParser.new do |o| o.on('--gnumake=BOOL') {|v| gnumake = v == 'yes'} o.on('--configure-exts=FILE') {|v| confexts = v} o.order!(ARGV) end confexts &&= File.read(confexts).scan(/^(?:ext|gem)s: (.*\.mk)/).flatten rescue nil confexts ||= [] macros["old_extensions"] = [] distclean = [] contpat = /(?>(?>[^\\\n]|\\.)*\\\n)*(?>[^\\\n]|\\.)*/ Dir.glob("{ext,.bundle/gems}/*/exts.mk") do |e| gem = e.start_with?(".bundle/gems/") dir = File.dirname(e) s = File.read(e) s.scan(/^(extensions|SUBMAKEOPTS|EXT[A-Z]+|MFLAGS|MESSAGE_(?:BEGIN|END)|NOTE_[A-Z]+)[ \t]*=[ \t]*(#{contpat})$/o) do |n, v| v.gsub!(/\\\n[ \t]*/, ' ') if v.empty? distclean << dir if n == "extensions" next end n = "old_extensions" if n == "extensions" and !confexts.include?(e) v = v.split m = macros[n] ||= [] case n when "LIBS" m.concat(v) else macros[n] = m | v end break if n == "old_extensions" end if gem r = "" else r = s[/^all static: (.+)$/, 1] deps << $& rubies |= r.split if r r = "(?:#{Regexp.new(r)})|" end s.scan(%r"^(ext/\S+)/[^/\s:]+:[ \t]*\1/static$| ^(?:#{r} all|static|install(?:-(?:so|rb))?| (?:dist|real)?clean ):.+$ "x) do deps << $&.sub(/ +note$/, '') end s.scan(%r"^(note(?:-\w+)?):(:)?[ \t]*(#{contpat})\n((?:\t.+\n)*)"o) do |(t, m, d, n)| note = (notes[t] ||= [[m||""], []]) note[0] |= d.split(/(?:\\\n|[ \t])[ \t]*/) n = n.split(/^/) if m note[1].concat(n) else note[1] |= n end end end deps.uniq! macros["cleandirs"] = distclean.map {|d| "#{d}/."} deps.map! {|d| /\A(?:dist|real)?clean(?=:)/ =~ d ? d + " $(cleandirs:/.=/#{$&})" : d } # NOTE: Only if extensions are configured as static and dynamic heterogeneously # (e.g. --with-static-linked-ext=foo or ext/Setup can mix static and dynamic # extensions), EXTOBJS may contain both extinit.o and dmyext.o. In such case, # prefer extinit.o, which does actual Init_${ext} function calls for statically # linked extensions, and drop dmyext.o, which does nothing but just to make the # linker happy. if objs = macros["EXTOBJS"] and objs.any? {|e|e.start_with?("ext/extinit.")} objs.delete_if {|e|e.start_with?("dmyext.")} end macros.default = [].freeze class Array def fold(h, w = 70) return "" if empty? w -= h ret = [s = String.new] each do |e| if s.size + e.size + 1 > w ret << (s = String.new) end s << " " << e end ret.join(" \\\n" + "\t" * (h / 8) + " " * (h % 8)) end end @erbout = _erbout def self.column w = 0 @erbout[/^.*\z/].scan(/\t|([^\t]+)/) {|s,| w += (s ? s.size : 8 - w % 8)} w end objext = RbConfig::CONFIG["OBJEXT"] sep = RbConfig::CONFIG['BUILD_FILE_SEPARATOR'] sep = nil if sep and sep.empty? if gnumake submake = "$(MAKE) -C $(@D)" else submake = ["cd", (sep ? "$(@D:/=#{sep})" : "$(@D)"), "&&"] exec = RbConfig::CONFIG["exec"] and !exec.empty? and submake << exec submake = (submake << "$(MAKE)").join(" ") mflags = " $(MFLAGS)" end -%> % macros.each_pair do |k, v| <%=k%> =<%= v.fold(column) %> % end % RbConfig::MAKEFILE_CONFIG.keys.grep(/RM/) do |k| <%=k%> = <%=RbConfig::MAKEFILE_CONFIG[k]%> % end all: static: clean: -$(Q)$(RM) ext/extinit.<%= objext %> distclean: -$(Q)$(RM) ext/extinit.c % deps.each do |d| <%= d %> % end % rubies.each do |ruby| <%= ruby %>: $(Q)$(MAKE)<%=mflags%> $(SUBMAKEOPTS) $@ % end % if rubies.size > 1 <%= rubies[1..-1].join(' ')%>: <%= rubies[0] %> % end libencs: $(Q)$(MAKE)<%=mflags%> -f enc.mk V=$(V) MINIRUBY="$(MINIRUBY)" $@ ext/extinit.<%=objext%>: $(Q)$(MAKE)<%=mflags%> V=$(V) EXTINITS="$(EXTINITS)" $@ % exts = (macros["extensions"] + macros["old_extensions"]) % exts.map! {|e|e.chomp("/.")}.sort % %w[all static install install-so install-rb].each do |tgt| % exts.each do |d| % pext = File.dirname(d) <%=d%>/<%=tgt%>:<% if exts.include?(pext) %> <%=pext%>/<%=tgt%><% end %> $(Q)<%= submake %><%=mflags%> V=$(V) $(@F) % end % end % distclean = exts | distclean % %w[clean distclean realclean].each do |tgt| % distclean.each do |d| % deps = exts.select {|e|e.start_with?("#{d}/")}.map {|e|"#{e}/#{tgt}"} <%=d%>/<%=tgt%>:<% unless deps.empty? %> <%=deps.join(' ')%><% end %> % unless tgt == "clean" $(ECHO) $(@F)ing $(@D) % end % if exts.include?(d) $(Q)<%= submake %><%=mflags%> V=$(V) $(@F) % end % unless tgt == "clean" $(Q)$(RM) <%=d[%r[\A(?:\.[^/]+/)?(?:[^/]+/)?[^/]+]]%>/exts.mk -$(Q)$(RMDIRS) $(@D) % end % end % end extso: @echo EXTSO=$(EXTSO) % notes.each_pair do |k, (d, n)| <%= k %>:<%= d.join(' ') %> <%= n.join("") %> % end remove-old-extensions: $(old_extensions:/.=/distclean)