1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 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
|