[前][次][番号順一覧][スレッド一覧]

ruby-changes:36433

From: akr <ko1@a...>
Date: Thu, 20 Nov 2014 23:18:45 +0900 (JST)
Subject: [ruby-changes:36433] akr:r48514 (trunk): * tool/update-deps: Insert all dependencies found by compiler.

akr	2014-11-20 23:18:37 +0900 (Thu, 20 Nov 2014)

  New Revision: 48514

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=48514

  Log:
    * tool/update-deps: Insert all dependencies found by compiler.

  Modified files:
    trunk/ChangeLog
    trunk/tool/update-deps
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 48513)
+++ ChangeLog	(revision 48514)
@@ -1,3 +1,7 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Thu Nov 20 23:17:11 2014  Tanaka Akira  <akr@f...>
+
+	* tool/update-deps: Insert all dependencies found by compiler.
+
 Thu Nov 20 15:51:01 2014  NARUSE, Yui  <naruse@r...>
 
 	* ext/nkf/depend (nkf.o): add nkf.c as dependency.
Index: tool/update-deps
===================================================================
--- tool/update-deps	(revision 48513)
+++ tool/update-deps	(revision 48514)
@@ -25,6 +25,7 @@ https://github.com/ruby/ruby/blob/trunk/tool/update-deps#L25
 require 'optparse'
 require 'stringio'
 require 'pathname'
+require 'open3'
 require 'pp'
 
 ENV['LC_ALL'] = 'C'
@@ -34,6 +35,9 @@ $opt_a = false https://github.com/ruby/ruby/blob/trunk/tool/update-deps#L35
 $opt_actual_fix = false
 $i_not_found = false
 
+DEPENDENCIES_SECTION_START_MARK = "\# AUTOGENERATED DEPENDENCIES START\n"
+DEPENDENCIES_SECTION_END_MARK = "\# AUTOGENERATED DEPENDENCIES END\n"
+
 def optionparser
   op = OptionParser.new
   op.banner = 'Usage: ruby tool/update-deps'
@@ -45,7 +49,11 @@ end https://github.com/ruby/ruby/blob/trunk/tool/update-deps#L49
 
 def read_make_deps(cwd)
   dependencies = {}
-  make_p = `make -p all miniruby ruby golf 2> /dev/null`
+  make_p, make_p_stderr, make_p_status = Open3.capture3("make -p all miniruby ruby golf")
+  if !make_p_status.success?
+    puts make_p_stderr
+    raise "make failed"
+  end
   dirstack = [cwd]
   curdir = nil
   make_p.scan(%r{Entering\ directory\ ['`](.*)'|
@@ -108,7 +116,7 @@ end https://github.com/ruby/ruby/blob/trunk/tool/update-deps#L116
 #  raise ArgumentError, "can not find #{filename} (hint: #{hint0})"
 #end
 
-def read_single_actual_deps(path_i, cwd)
+def read_single_cc_deps(path_i, cwd)
   files = {}
   path_i.each_line.with_index {|line, lineindex|
     next if /\A\# \d+ "(.*)"/ !~ line
@@ -130,7 +138,7 @@ def read_single_actual_deps(path_i, cwd) https://github.com/ruby/ruby/blob/trunk/tool/update-deps#L138
       dep = compiler_wd + dep
     end
     if !dep.file?
-      warn "file not found: #{dep}"
+      warn "warning: file not found: #{dep}"
       next
     end
     next if !dep.to_s.start_with?(cwd.to_s) # omit system headers.
@@ -139,18 +147,18 @@ def read_single_actual_deps(path_i, cwd) https://github.com/ruby/ruby/blob/trunk/tool/update-deps#L147
   deps
 end
 
-def read_actual_deps(cwd)
+def read_cc_deps(cwd)
   deps = {}
   Pathname.glob('**/*.o').sort.each {|fn_o|
     fn_i = fn_o.sub_ext('.i')
     if !fn_i.exist?
-      warn "not found: #{fn_i}"
+      warn "warning: not found: #{fn_i}"
       $i_not_found = true
       next
     end
     path_o = cwd + fn_o
     path_i = cwd + fn_i
-    deps[path_o] = read_single_actual_deps(path_i, cwd)
+    deps[path_o] = read_single_cc_deps(path_i, cwd)
   }
   deps
 end
@@ -165,12 +173,12 @@ def concentrate(dependencies, cwd) https://github.com/ruby/ruby/blob/trunk/tool/update-deps#L173
       rel
     }
     if %r{\A\.\.(/|\z)} =~ target.to_s
-      warn "out of tree target: #{target}"
+      warn "warning: out of tree target: #{target}"
       next
     end
     sources = sources.reject {|s|
       if %r{\A\.\.(/|\z)} =~ s.to_s
-        warn "out of tree source: #{s}"
+        warn "warning: out of tree source: #{s}"
         true
       else
         false
@@ -226,7 +234,7 @@ def in_makefile(target, source) https://github.com/ruby/ruby/blob/trunk/tool/update-deps#L234
     ["enc/depend", target2, source2]
   when %r{\Aext/}
     unless File.exist?("#{File.dirname(target)}/extconf.rb")
-      warn "not found: #{File.dirname(target)}/extconf.rb"
+      warn "warning: not found: #{File.dirname(target)}/extconf.rb"
     end
     target2 = File.basename(target)
     case source
@@ -235,10 +243,10 @@ def in_makefile(target, source) https://github.com/ruby/ruby/blob/trunk/tool/update-deps#L243
     when %r{\A\.ext/include/[^/]+/ruby/} then source2 = "$(arch_hdrdir)/ruby/#{$'}"
     when %r{\A#{Regexp.escape File.dirname(target)}/extconf\.h\z} then source2 = "$(RUBY_EXTCONF_H)"
     when %r{\A#{Regexp.escape File.dirname(target)}/} then source2 = $'
-    when 'id.h' then source2 = '{$(VPATH)}id.h'
-    when 'parse.h' then source2 = '{$(VPATH)}parse.h'
-    when 'lex.c' then source2 = '{$(VPATH)}lex.c'
-    when 'probes.h' then source2 = '{$(VPATH)}probes.h'
+    when 'id.h' then source2 = '$(topdir)/id.h'
+    when 'parse.h' then source2 = '$(topdir)/parse.h'
+    when 'lex.c' then source2 = '$(topdir)/lex.c'
+    when 'probes.h' then source2 = '$(topdir)/probes.h'
     else source2 = "$(top_srcdir)/#{source}"
     end
     ["#{File.dirname(target)}/depend", target2, source2]
@@ -247,39 +255,101 @@ def in_makefile(target, source) https://github.com/ruby/ruby/blob/trunk/tool/update-deps#L255
   end
 end
 
-def compare_deps(make_deps, actual_deps, out=$stdout)
-  targets = sort_paths(actual_deps.keys)
-  targets.each {|target|
-    actual_sources = actual_deps[target]
-    if !make_deps.has_key?(target)
-      warn "no makefile dependency for #{target}"
-    else
-      make_sources = make_deps[target]
-      sort_paths(actual_sources | make_sources).each {|source|
-        makefile, target2, source2 = in_makefile(target, source)
-        lines = begin
-          File.readlines(makefile)
-        rescue Errno::ENOENT
-          []
+def show_deps(tag, deps)
+  targets = sort_paths(deps.keys)
+  targets.each {|t|
+    sources = sort_paths(deps[t])
+    sources.each {|s|
+      puts "#{tag} #{t}: #{s}"
+    }
+  }
+end
+
+def detect_dependencies(out=$stdout)
+  cwd = Pathname.pwd
+  make_deps = read_make_deps(cwd)
+  #pp make_deps
+  make_deps = concentrate(make_deps, cwd)
+  #pp make_deps
+  cc_deps = read_cc_deps(cwd)
+  #pp cc_deps
+  cc_deps = concentrate(cc_deps, cwd)
+  #pp cc_deps
+  return make_deps, cc_deps
+end
+
+def compare_deps(make_deps, cc_deps, out=$stdout)
+  targets = make_deps.keys | cc_deps.keys
+
+  makefiles = {}
+
+  make_lines_hash = {}
+  make_deps.each {|t, sources|
+    sources.each {|s|
+      makefile, t2, s2 = in_makefile(t, s)
+      makefiles[makefile] = true
+      make_lines_hash[makefile] ||= Hash.new(false)
+      make_lines_hash[makefile]["#{t2}: #{s2}"] = true
+    }
+  }
+
+  cc_lines_hash = {}
+  cc_deps.each {|t, sources|
+    sources.each {|s|
+      makefile, t2, s2 = in_makefile(t, s)
+      makefiles[makefile] = true
+      cc_lines_hash[makefile] ||= Hash.new(false)
+      cc_lines_hash[makefile]["#{t2}: #{s2}"] = true
+    }
+  }
+
+  makefiles.keys.sort.each {|makefile|
+    cc_lines = cc_lines_hash[makefile] || Hash.new(false)
+    make_lines = make_lines_hash[makefile] || Hash.new(false)
+    content = begin
+      File.read(makefile)
+    rescue Errno::ENOENT
+      ''
+    end
+    if /^#{Regexp.escape DEPENDENCIES_SECTION_START_MARK}
+        ((?:.*\n)*)
+        #{Regexp.escape DEPENDENCIES_SECTION_END_MARK}/x =~ content
+      pre_post_part = [$`, $']
+      current_lines = Hash.new(false)
+      $1.each_line {|line| current_lines[line.chomp] = true }
+      (cc_lines.keys | current_lines.keys | make_lines.keys).sort.each {|line|
+        status = [cc_lines[line], current_lines[line], make_lines[line]]
+        case status
+        when [true, true, true]
+          # no problem
+        when [true, true, false]
+          out.puts "warning #{makefile} : #{line}  (make doesn't detect written dependency)"
+        when [true, false, true]
+          out.puts "add_auto #{makefile} : #{line}  (harmless)" # This is automatically updatable.
+        when [true, false, false]
+          out.puts "add_auto #{makefile} : #{line}  (harmful)" # This is automatically updatable.
+        when [false, true, true]
+          out.puts "del_cc #{makefile} : #{line}" # Not automatically updatable because build on other OS may need the dependency.
+        when [false, true, false]
+          out.puts "del_cc #{makefile} : #{line}  (Curious.  make doesn't detect this dependency.)" # Not automatically updatable because build on other OS may need the dependency.
+        when [false, false, true]
+          out.puts "del_make #{makefile} : #{line}" # Not automatically updatable because the dependency is written manually.
+        else
+          raise "unexpected status: #{status.inspect}"
         end
-        #depline = "#{target2}: #{source2} \# #{target}: #{source}\n"
-        depline = "#{target2}: #{source2}\n"
-        if !make_sources.include?(source)
-          out.puts "add #{makefile} : #{depline}"
-        elsif !actual_sources.include?(source)
-          if lines.include? depline
-            out.puts "delL #{makefile} : #{depline}" # delL stands for del line
-          else
-            out.puts "delP #{makefile} : #{depline}" # delP stands for del prerequisite
-          end
+      }
+    else
+      (cc_lines.keys | make_lines.keys).sort.each {|line|
+        status = [cc_lines[line], make_lines[line]]
+        case status
+        when [true, true]
+          # no problem
+        when [true, false]
+          out.puts "add_manual #{makefile} : #{line}" # Not automatically updatable because makefile has no section to update automatically.
+        when [false, true]
+          out.puts "del_manual #{makefile} : #{line}" # Not automatically updatable because makefile has no section to update automatically.
         else
-          if $opt_a
-            if lines.include? depline
-              out.puts "okL #{makefile} : #{depline}" # okL stands for ok line
-            else
-              out.puts "okP #{makefile} : #{depline}" # okP stands for ok prerequisite
-            end
-          end
+          raise "unexpected status: #{status.inspect}"
         end
       }
     end
@@ -287,104 +357,84 @@ def compare_deps(make_deps, actual_deps, https://github.com/ruby/ruby/blob/trunk/tool/update-deps#L357
 end
 
 def main_show(out=$stdout)
-  cwd = Pathname.pwd
-  make_deps = read_make_deps(cwd)
-  #pp make_deps
-  make_deps = concentrate(make_deps, cwd)
-  #pp make_deps
-  actual_deps = read_actual_deps(cwd)
-  #pp actual_deps
-  actual_deps = concentrate(actual_deps, cwd)
-  #pp actual_deps
-  compare_deps(make_deps, actual_deps, out)
+  make_deps, cc_deps = detect_dependencies(out)
+  compare_deps(make_deps, cc_deps, out)
 end
 
 def extract_deplines(problems)
   adds = {}
-  dels = {}
+  others = {}
   problems.each_line {|line|
     case line
-    when /\Aadd (\S+) : (\S.*\n)\z/
-      (adds[$1] ||= []) << $2
-    when /\AdelL (\S+) : (\S.*\n)\z/
-      (dels[$1] ||= []) << $2
-    when /\AdelP (\S+) : (\S.*\n)\z/
-      (dels[$1] ||= []) << $2
-    when /\AokL (\S+) : (\S.*\n)\z/
-    when /\AokP (\S+) : (\S.*\n)\z/
-      (adds[$1] ||= []) << $2
+    when /\Aadd_auto (\S+) : ((\S+): (\S+))/
+      (adds[$1] ||= []) << [line, "#{$2}\n"]
+    when /\A(?:del_cc|del_make|add_manual|del_manual|warning) (\S+) : /
+      (others[$1] ||= []) << line
+    else
+      raise "unexpected line: #{line.inspect}"
     end
   }
-  return adds, dels
+  return adds, others
 end
 
-DEPENDENCIES_SECTION_START_MARK = "\# AUTOGENERATED DEPENDENCIES START\n"
-DEPENDENCIES_SECTION_END_MARK = "\# AUTOGENERATED DEPENDENCIES END\n"
-
 def main_actual_fix(problems)
-  adds, dels = extract_deplines(problems)
-  (adds.keys | dels.keys).sort.each {|makefile|
+  adds, others = extract_deplines(problems)
+  (adds.keys | others.keys).sort.each {|makefile|
     content = begin
       File.read(makefile)
     rescue Errno::ENOENT
-      ''
+      nil
     end
-    if /^#{Regexp.escape DEPENDENCIES_SECTION_START_MARK}((?:.*\n)*)#{Regexp.escape DEPENDENCIES_SECTION_END_MARK}/ =~ content
-      pre_post_part = [$`, $']
-      lines = $1.lines.to_a
-    else
-      pre_post_part = nil
-      lines = []
-    end
-
-    lines_original = lines.dup
 
-    if dels[makefile]
-      lines -= dels[makefile]
-    end
-    if adds[makefile]
-      lines.concat(adds[makefile] - lines)
-    end
-
-    if lines == lines_original
-      next
+    if content &&
+       /^#{Regexp.escape DEPENDENCIES_SECTION_START_MARK}
+        ((?:.*\n)*)
+        #{Regexp.escape DEPENDENCIES_SECTION_END_MARK}/x =~ content
+      pre_dep_post = [$`, $1, $']
+    else
+      pre_dep_post = nil
     end
 
-    lines.sort!
-
-    if pre_post_part
-      new_content = [
-        pre_post_part.first,
-        DEPENDENCIES_SECTION_START_MARK,
-        *lines,
-        DEPENDENCIES_SECTION_END_MARK,
-        pre_post_part.last
-      ].join
-      tmp_makefile = "#{makefile}.new#{$$}"
-      File.write(tmp_makefile, new_content)
-      File.rename tmp_makefile, makefile
-      puts "modified: #{makefile}"
-    else
+    if pre_dep_post && adds[makefile]
+      pre_lines, dep_lines, post_lines = pre_dep_post
+      dep_lines = dep_lines.lines.to_a
+      add_lines = adds[makefile].map(&:last)
+      new_lines = (dep_lines | add_lines).sort.uniq
       new_content = [
+        pre_lines,
         DEPENDENCIES_SECTION_START_MARK,
-        *lines,
+        *new_lines,
         DEPENDENCIES_SECTION_END_MARK,
+        post_lines
       ].join
-      if !File.exist?(makefile)
-        if !lines.empty?
-          File.open(makefile, 'w') {|f|
-            f.print new_content
-          }
-          puts "created: #{makefile}"
-        end
+      if content != new_content
+        puts "modified: #{makefile}"
+        tmp_makefile = "#{makefile}.new.#{$$}"
+        File.write(tmp_makefile, new_content)
+        File.rename tmp_makefile, makefile
+        (add_lines - lines).each {|line| puts "  added #{line}" }
       else
+        puts "not modified: #{makefile}"
+      end
+      if others[makefile]
+        others[makefile].each {|line| puts "  #{line}" }
+      end
+    else
+      if pre_dep_post
+        puts "no addtional lines: #{makefile}"
+      elsif content
         puts "no dependencies section: #{makefile}"
-        (lines_original - lines).each {|line|
-          puts "  del: #{line}"
-        }
-        (lines - lines_original).each {|line|
-          puts "  add: #{line}"
-        }
+      else
+        puts "no makefile: #{makefile}"
+      end
+      if adds[makefile]
+        puts "  warning: dependencies section was exist at previous phase."
+      end
+      if adds[makefile]
+        adds[makefile].map(&:first).each {|line| puts "  #{line}" }
+      end
+      if others[makefile]
+        others[makefile].each {|line| puts "  #{line}" }
       end
     end
   }
@@ -410,5 +460,5 @@ end https://github.com/ruby/ruby/blob/trunk/tool/update-deps#L460
 
 run
 if $i_not_found
-  warn "missing *.i files, see help in #$0 and ensure ccache is disabled"
+  warn "warning: missing *.i files, see help in #$0 and ensure ccache is disabled"
 end

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]