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
|
end
|
||||||
|
|
||||||
def run(target, sources, cache)
|
def run(target, sources, cache)
|
||||||
unless cache.up_to_date?(target, sources)
|
vars = {
|
||||||
vars = {
|
'TARGET' => target,
|
||||||
'TARGET' => target,
|
'SOURCES' => sources,
|
||||||
'SOURCES' => sources,
|
'DEPFILE' => target.set_suffix('.mf'),
|
||||||
'DEPFILE' => target.set_suffix('.mf'),
|
}
|
||||||
}
|
command = @env.build_command(@env['CCCOM'], vars)
|
||||||
@env.execute("CC #{target}", @env['CCCOM'], vars)
|
unless cache.up_to_date?(target, command, sources)
|
||||||
|
return false unless @env.execute("CC #{target}", command)
|
||||||
deps = sources
|
deps = sources
|
||||||
if File.exists?(vars['DEPFILE'])
|
if File.exists?(vars['DEPFILE'])
|
||||||
deps += @env.parse_makefile_deps(vars['DEPFILE'], target)
|
deps += @env.parse_makefile_deps(vars['DEPFILE'], target)
|
||||||
FileUtils.rm_f(vars['DEPFILE'])
|
FileUtils.rm_f(vars['DEPFILE'])
|
||||||
end
|
end
|
||||||
cache.register_build(target, deps.uniq)
|
cache.register_build(target, command, deps.uniq)
|
||||||
end
|
end
|
||||||
target
|
target
|
||||||
end
|
end
|
||||||
|
@ -24,13 +24,15 @@ module Rscons
|
|||||||
builder.run(o_file, [source], cache)
|
builder.run(o_file, [source], cache)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
unless cache.up_to_date?(target, sources)
|
vars = {
|
||||||
vars = {
|
'TARGET' => target,
|
||||||
'TARGET' => target,
|
'SOURCES' => sources,
|
||||||
'SOURCES' => sources,
|
'LD' => @env['LD'] || @env['CC'], # TODO: figure out whether to use CC or CXX
|
||||||
'LD' => @env['LD'] || @env['CC'], # TODO: figure out whether to use CC or CXX
|
}
|
||||||
}
|
command = @env.build_command(@env['LDCOM'], vars)
|
||||||
@env.execute("LD #{target}", @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
|
end
|
||||||
target
|
target
|
||||||
end
|
end
|
||||||
|
@ -1,8 +1,36 @@
|
|||||||
require 'yaml'
|
require 'yaml'
|
||||||
require 'fileutils'
|
require 'fileutils'
|
||||||
require 'digest/md5'
|
require 'digest/md5'
|
||||||
|
require 'set'
|
||||||
|
|
||||||
module Rscons
|
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
|
class Cache
|
||||||
# Constants
|
# Constants
|
||||||
CACHE_FILE = '.rsconscache'
|
CACHE_FILE = '.rsconscache'
|
||||||
@ -15,6 +43,7 @@ module Rscons
|
|||||||
# Instance Methods
|
# Instance Methods
|
||||||
def initialize
|
def initialize
|
||||||
@cache = YAML.load(File.read(CACHE_FILE)) rescue {}
|
@cache = YAML.load(File.read(CACHE_FILE)) rescue {}
|
||||||
|
@lookup_checksums = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
def write
|
def write
|
||||||
@ -23,20 +52,43 @@ module Rscons
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def up_to_date?(file, deps = nil)
|
def up_to_date?(target, command, deps)
|
||||||
# TODO
|
# target file must exist on disk
|
||||||
false
|
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
|
end
|
||||||
|
|
||||||
def register_build(target, deps)
|
def register_build(target, command, deps)
|
||||||
# TODO
|
@cache[target] = {
|
||||||
|
command: command,
|
||||||
|
checksum: calculate_checksum(target),
|
||||||
|
deps: deps.map do |dep|
|
||||||
|
{
|
||||||
|
fname: dep,
|
||||||
|
checksum: lookup_checksum(dep),
|
||||||
|
}
|
||||||
|
end
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
# Private Instance Methods
|
# Private Instance Methods
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def lookup_checksum(file)
|
||||||
|
@lookup_checksums[file] || calculate_checksum(file)
|
||||||
|
end
|
||||||
|
|
||||||
def calculate_checksum(file)
|
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
|
end
|
||||||
end
|
end
|
||||||
|
@ -74,8 +74,11 @@ module Rscons
|
|||||||
cache.write
|
cache.write
|
||||||
end
|
end
|
||||||
|
|
||||||
def execute(short_desc, command, extra_vars)
|
def build_command(command_template, extra_vars)
|
||||||
command = @varset.merge(extra_vars).expand_varref(command)
|
@varset.merge(extra_vars).expand_varref(command_template)
|
||||||
|
end
|
||||||
|
|
||||||
|
def execute(short_desc, command)
|
||||||
if @varset[:echo] == :command
|
if @varset[:echo] == :command
|
||||||
puts command.map { |c| c =~ /\s/ ? "'#{c}'" : c }.join(' ')
|
puts command.map { |c| c =~ /\s/ ? "'#{c}'" : c }.join(' ')
|
||||||
elsif @varset[:echo] == :short
|
elsif @varset[:echo] == :short
|
||||||
|
Loading…
x
Reference in New Issue
Block a user