implement Cache to store info about target dependencies and checksums across invocations
This commit is contained in:
parent
9c69a45f77
commit
0bf71ae4d1
@ -17,19 +17,20 @@ module Rscons
|
||||
end
|
||||
|
||||
def run(target, sources, cache)
|
||||
unless cache.up_to_date?(target, sources)
|
||||
vars = {
|
||||
'TARGET' => target,
|
||||
'SOURCES' => sources,
|
||||
'DEPFILE' => target.set_suffix('.mf'),
|
||||
}
|
||||
@env.execute("CC #{target}", @env['CCCOM'], vars)
|
||||
command = @env.build_command(@env['CCCOM'], vars)
|
||||
unless cache.up_to_date?(target, command, sources)
|
||||
return false unless @env.execute("CC #{target}", command)
|
||||
deps = sources
|
||||
if File.exists?(vars['DEPFILE'])
|
||||
deps += @env.parse_makefile_deps(vars['DEPFILE'], target)
|
||||
FileUtils.rm_f(vars['DEPFILE'])
|
||||
end
|
||||
cache.register_build(target, deps.uniq)
|
||||
cache.register_build(target, command, deps.uniq)
|
||||
end
|
||||
target
|
||||
end
|
||||
|
@ -24,13 +24,15 @@ module Rscons
|
||||
builder.run(o_file, [source], cache)
|
||||
end
|
||||
end
|
||||
unless cache.up_to_date?(target, sources)
|
||||
vars = {
|
||||
'TARGET' => target,
|
||||
'SOURCES' => sources,
|
||||
'LD' => @env['LD'] || @env['CC'], # TODO: figure out whether to use CC or CXX
|
||||
}
|
||||
@env.execute("LD #{target}", @env['LDCOM'], vars)
|
||||
command = @env.build_command(@env['LDCOM'], vars)
|
||||
unless cache.up_to_date?(target, command, sources)
|
||||
return false unless @env.execute("LD #{target}", command)
|
||||
cache.register_build(target, command, sources)
|
||||
end
|
||||
target
|
||||
end
|
||||
|
@ -1,8 +1,36 @@
|
||||
require 'yaml'
|
||||
require 'fileutils'
|
||||
require 'digest/md5'
|
||||
require 'set'
|
||||
|
||||
module Rscons
|
||||
# Example cache:
|
||||
# {
|
||||
# 'program' => {
|
||||
# 'checksum' => 'A1B2C3D4',
|
||||
# 'command' => ['gcc', '-o', 'program', 'program.o'],
|
||||
# 'deps' => [
|
||||
# {
|
||||
# 'fname' => 'program.o',
|
||||
# 'checksum' => '87654321',
|
||||
# }
|
||||
# ],
|
||||
# }
|
||||
# 'program.o' => {
|
||||
# 'checksum' => '87654321',
|
||||
# 'command' => ['gcc', '-c', '-o', 'program.o', 'program.c'],
|
||||
# 'deps' => [
|
||||
# {
|
||||
# 'fname' => 'program.c',
|
||||
# 'checksum' => '456789ABC',
|
||||
# },
|
||||
# {
|
||||
# 'fname' => 'program.h',
|
||||
# 'checksum' => '7979764643',
|
||||
# }
|
||||
# ]
|
||||
# }
|
||||
# }
|
||||
class Cache
|
||||
# Constants
|
||||
CACHE_FILE = '.rsconscache'
|
||||
@ -15,6 +43,7 @@ module Rscons
|
||||
# Instance Methods
|
||||
def initialize
|
||||
@cache = YAML.load(File.read(CACHE_FILE)) rescue {}
|
||||
@lookup_checksums = {}
|
||||
end
|
||||
|
||||
def write
|
||||
@ -23,20 +52,43 @@ module Rscons
|
||||
end
|
||||
end
|
||||
|
||||
def up_to_date?(file, deps = nil)
|
||||
# TODO
|
||||
false
|
||||
def up_to_date?(target, command, deps)
|
||||
# target file must exist on disk
|
||||
return false unless File.exists?(target)
|
||||
# target must be registered in the cache
|
||||
return false unless @cache.has_key?(target)
|
||||
# command line used to build target must be identical
|
||||
return false unless @cache[target][:command] == command
|
||||
# all dependencies passed in must exist in cache (but cache may have more)
|
||||
return false unless (Set.new(deps) - Set.new(@cache[target][:deps])).empty?
|
||||
# all cached dependencies must have their checksums match
|
||||
@cache[target][:deps].map do |dep_cache|
|
||||
dep_cache[:checksum] == lookup_checksum(dep_cache[:fname])
|
||||
end.all?
|
||||
end
|
||||
|
||||
def register_build(target, deps)
|
||||
# TODO
|
||||
def register_build(target, command, deps)
|
||||
@cache[target] = {
|
||||
command: command,
|
||||
checksum: calculate_checksum(target),
|
||||
deps: deps.map do |dep|
|
||||
{
|
||||
fname: dep,
|
||||
checksum: lookup_checksum(dep),
|
||||
}
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
# Private Instance Methods
|
||||
private
|
||||
|
||||
def lookup_checksum(file)
|
||||
@lookup_checksums[file] || calculate_checksum(file)
|
||||
end
|
||||
|
||||
def calculate_checksum(file)
|
||||
Digest::MD5.hexdigest(File.read(file)).encode(__ENCODING__)
|
||||
@lookup_checksums[file] = Digest::MD5.hexdigest(File.read(file)).encode(__ENCODING__) rescue ''
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -74,8 +74,11 @@ module Rscons
|
||||
cache.write
|
||||
end
|
||||
|
||||
def execute(short_desc, command, extra_vars)
|
||||
command = @varset.merge(extra_vars).expand_varref(command)
|
||||
def build_command(command_template, extra_vars)
|
||||
@varset.merge(extra_vars).expand_varref(command_template)
|
||||
end
|
||||
|
||||
def execute(short_desc, command)
|
||||
if @varset[:echo] == :command
|
||||
puts command.map { |c| c =~ /\s/ ? "'#{c}'" : c }.join(' ')
|
||||
elsif @varset[:echo] == :short
|
||||
|
Loading…
x
Reference in New Issue
Block a user