diff options
Diffstat (limited to 'tool/update-deps')
-rwxr-xr-x | tool/update-deps | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/tool/update-deps b/tool/update-deps new file mode 100755 index 0000000000..edb36b6d6b --- /dev/null +++ b/tool/update-deps @@ -0,0 +1,139 @@ +#!/usr/bin/ruby + +# tool/update-deps assists you to update dependencies in common.mk. + +# This script uses preprocessed source files (*.i) to extract +# dependencies. +# It is possible to generate *.i using gcc with -save-temps option as: +# +# ./configure CFLAGS='-save-temps' +# make all golf +# +# After that, tool/update-deps generate common.mk with up-to-date dependencies. +# Currently, the result is not perfect around version.o, compile.o, etc. +# So you must see each changes and incorporate right changes. +# +# ./tool/update-deps > z +# wdiff =(sed -e 's/\\$//' common.mk ) =(sed -e 's/\\$//' z) |less -j 5 -p '\{\+|\+\}|\[-|-\]' +# vi common.mk + +src = File.read("common.mk") + +includes_macro = {} +src.scan(/^([A-Z_]+_H_INCLUDES)[ \t]*=(([^\\\n]|\\(.|\n))*)\n/) { + name = $1 + vals = $2 + #STDERR.puts vals.inspect + vals.gsub!(/\\\n/, ' ') + vals.gsub!(/\{\$\(VPATH\)\}/, '') + vals.gsub!(/thread_\$\(THREAD_MODEL\)/, 'thread_pthread') + vals = vals.strip.split(/\s+/) + includes_macro[name] = vals + #STDERR.puts [name, vals].inspect +} + +begin + again = false + includes_macro.each {|name, vals| + vals.map! {|val| + if /\A\$\((.*_H_INCLUDES)\)\z/ =~ val + again = true + includes_macro.fetch($1) + else + val + end + } + vals.flatten! + } +end while again + +src.gsub!(/^([0-9a-z._]+)\.\$\(OBJEXT\):(.*\n(?:[ ].*\n)*)/) { + #STDERR.puts $&.inspect + matched = $& + basename = $1 + deps = $2 + dd = deps.dup + dd.gsub!(/\{\$\(VPATH\)\}/, '') + dd.gsub!(/\\\n/, ' ') + dd.gsub!(/thread_\$\(THREAD_MODEL\)/, 'thread_pthread') + used_imacro = {} + includes_macro.each {|k, v| + if dd.sub!(/\$\(#{Regexp.escape k}\)/) { v.join(' ') } + used_imacro[k] = true + end + } + dd = dd.strip.split(/\s+/) + if !File.file?("#{basename}.o") + warn "#{basename}.o not found." + else + unless File.file? "#{basename}.i" + puts "#{basename}.i not found." + next + end + incs = [] + File.foreach("#{basename}.i") {|line| + next unless /^# \d+ "([^"]*)"/ =~ line + inc = $1 + next if %r{\A[/<]} =~ inc + inc.sub!(%r{\A\./}, '') + inc.sub!(%r{\Ainclude/ruby/}, '') or + inc.sub!(%r{\Ainclude/}, '') or + inc.sub!(%r{\A\.ext/include/[^/]+/ruby/}, '') or + inc.sub!(%r{\Aenc/}, '') or + inc.sub!(%r{\Amissing/}, '') + #p inc + incs << inc + } + incs.uniq! + incs = incs.sort_by {|inc| [(dd.index(inc) || dd.length), incs.index(inc)] } + add = incs - dd + if !add.empty? || true + if incs[0] != dd[0] + raise "first file not matched: #{incs[0].inspect} v.s. #{dd[0].inspect}" + end + depline = "#{basename}.$(OBJEXT):" + used_imacro.each_key {|k| + if includes_macro[k].all? {|v| incs.include? v } + im = "$(#{k})" + incs.map! {|inc| + if includes_macro[k].include? inc + im0 = im + im = nil + im0 + else + inc + end + } + incs.compact! + else + needless = includes_macro[k].reject {|v| incs.include? v } + STDERR.puts "#{basename}.$(OBJEXT) can't use #{k}. #{needless.join(' ')} is not used." + end + } + + incs.each {|inc| + inc = inc.sub(/\Athread_pthread/, 'thread_$(THREAD_MODEL)') + if /_INCLUDES\)\z/ =~ inc + # use $(RUBY_H_INCLUDES) as is. + elsif inc == 'revision.h' + inc = '$(srcdir)/revision.h' + else + inc = "{$(VPATH)}#{inc}" + end + depline << " #{inc}" + } + lines = [] + while 72 < depline.length && depline.sub!(/\A(.{0,72}|.{72}.*?) /, '') + lines << $& + end + lines << depline + matched = lines.join("\\\n ") + matched << "\n" + end + end + #STDERR.puts matched.inspect + matched +} + +puts src + |