process jobs from the JobSet
This commit is contained in:
parent
e1d8dfbab6
commit
3601359c08
@ -38,7 +38,7 @@ module Rscons
|
|||||||
# when the block returns, the {#process} method is automatically called.
|
# when the block returns, the {#process} method is automatically called.
|
||||||
def initialize(options = {})
|
def initialize(options = {})
|
||||||
@varset = VarSet.new
|
@varset = VarSet.new
|
||||||
@targets = {}
|
@job_set = JobSet.new
|
||||||
@user_deps = {}
|
@user_deps = {}
|
||||||
@builders = {}
|
@builders = {}
|
||||||
@build_dirs = []
|
@build_dirs = []
|
||||||
@ -280,40 +280,24 @@ module Rscons
|
|||||||
#
|
#
|
||||||
# @return [void]
|
# @return [void]
|
||||||
def process
|
def process
|
||||||
while @targets.size > 0
|
cache = Cache.instance
|
||||||
expand_paths!
|
begin
|
||||||
targets = @targets
|
while job = @job_set.get_next_job_to_run
|
||||||
@targets = {}
|
expand_paths(job)
|
||||||
cache = Cache.instance
|
# TODO: have Cache determine when checksums may be invalid based on
|
||||||
cache.clear_checksum_cache!
|
# file size and/or timestamp.
|
||||||
targets_processed = Set.new
|
cache.clear_checksum_cache!
|
||||||
process_target = proc do |target|
|
result = run_builder(job[:builder],
|
||||||
unless targets_processed.include?(target)
|
job[:target],
|
||||||
targets_processed << target
|
job[:sources],
|
||||||
targets[target].each do |target_params|
|
cache,
|
||||||
target_params[:sources].each do |src|
|
job[:vars])
|
||||||
if targets.include?(src) and not targets_processed.include?(src)
|
unless result
|
||||||
process_target.call(src)
|
raise BuildError.new("Failed to build #{job[:target]}")
|
||||||
end
|
|
||||||
end
|
|
||||||
result = run_builder(target_params[:builder],
|
|
||||||
target,
|
|
||||||
target_params[:sources],
|
|
||||||
cache,
|
|
||||||
target_params[:vars] || {})
|
|
||||||
unless result
|
|
||||||
raise BuildError.new("Failed to build #{target}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
begin
|
ensure
|
||||||
targets.each_key do |target|
|
cache.write
|
||||||
process_target.call(target)
|
|
||||||
end
|
|
||||||
ensure
|
|
||||||
cache.write
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -321,7 +305,7 @@ module Rscons
|
|||||||
#
|
#
|
||||||
# @return [void]
|
# @return [void]
|
||||||
def clear_targets
|
def clear_targets
|
||||||
@targets = {}
|
@job_set.clear!
|
||||||
end
|
end
|
||||||
|
|
||||||
# Expand a construction variable reference.
|
# Expand a construction variable reference.
|
||||||
@ -389,7 +373,7 @@ module Rscons
|
|||||||
sources = Array(sources)
|
sources = Array(sources)
|
||||||
builder = @builders[method.to_s]
|
builder = @builders[method.to_s]
|
||||||
build_target = builder.create_build_target(env: self, target: target, sources: sources)
|
build_target = builder.create_build_target(env: self, target: target, sources: sources)
|
||||||
add_target(build_target.to_s, builder, sources, vars, rest)
|
add_target(build_target.to_s, builder, sources, vars || {}, rest)
|
||||||
build_target
|
build_target
|
||||||
else
|
else
|
||||||
super
|
super
|
||||||
@ -402,17 +386,11 @@ module Rscons
|
|||||||
# @param builder [Builder] The {Builder} to use to build the target.
|
# @param builder [Builder] The {Builder} to use to build the target.
|
||||||
# @param sources [Array<String>] Source file name(s).
|
# @param sources [Array<String>] Source file name(s).
|
||||||
# @param vars [Hash] Construction variable overrides.
|
# @param vars [Hash] Construction variable overrides.
|
||||||
# @param args [Object] Any extra arguments passed to the {Builder}.
|
# @param args [Object] Deprecated; unused.
|
||||||
#
|
#
|
||||||
# @return [void]
|
# @return [void]
|
||||||
def add_target(target, builder, sources, vars, args)
|
def add_target(target, builder, sources, vars, args)
|
||||||
@targets[target] ||= []
|
@job_set.add_job(builder, target, sources, vars)
|
||||||
@targets[target] << {
|
|
||||||
builder: builder,
|
|
||||||
sources: sources,
|
|
||||||
vars: vars,
|
|
||||||
args: args,
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Manually record a given target as depending on the specified files.
|
# Manually record a given target as depending on the specified files.
|
||||||
@ -676,26 +654,20 @@ module Rscons
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Expand target and source paths before invoking builders.
|
# Expand target and source paths of a job before invoking the builder.
|
||||||
#
|
#
|
||||||
# This method expand construction variable references in the target and
|
# This method expand construction variable references in the target and
|
||||||
# source file names before passing them to the builder. It also expands
|
# source file names before passing them to the builder. It also expands
|
||||||
# "^/" prefixes to the Environment's build root if a build root is defined.
|
# "^/" prefixes to the Environment's build root if a build root is defined.
|
||||||
#
|
#
|
||||||
# @return [void]
|
# @return [void]
|
||||||
def expand_paths!
|
def expand_paths(job)
|
||||||
@targets = @targets.reduce({}) do |result, (target, target_params_list)|
|
job[:target] = expand_path(job[:target]) if @build_root
|
||||||
target = expand_path(target) if @build_root
|
job[:target] = expand_varref(job[:target])
|
||||||
target = expand_varref(target)
|
job[:sources] = job[:sources].map do |source|
|
||||||
result[target] = target_params_list.map do |target_params|
|
source = expand_path(source) if @build_root
|
||||||
sources = target_params[:sources].map do |source|
|
expand_varref(source)
|
||||||
source = expand_path(source) if @build_root
|
end.flatten
|
||||||
expand_varref(source)
|
|
||||||
end.flatten
|
|
||||||
target_params.merge(sources: sources)
|
|
||||||
end
|
|
||||||
result
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Parse dependencies for a given target from a Makefile.
|
# Parse dependencies for a given target from a Makefile.
|
||||||
|
@ -20,7 +20,12 @@ module Rscons
|
|||||||
# @param vars [Hash]
|
# @param vars [Hash]
|
||||||
# Construction variable overrides.
|
# Construction variable overrides.
|
||||||
def add_job(builder, target, sources, vars)
|
def add_job(builder, target, sources, vars)
|
||||||
@jobs[target] = {
|
# We allow multiple jobs to be registered per target for cases like:
|
||||||
|
# env.Directory("dest")
|
||||||
|
# env.Install("dest", "bin")
|
||||||
|
# env.Install("dest", "share")
|
||||||
|
@jobs[target] ||= []
|
||||||
|
@jobs[target] << {
|
||||||
builder: builder,
|
builder: builder,
|
||||||
target: target,
|
target: target,
|
||||||
sources: sources,
|
sources: sources,
|
||||||
@ -39,18 +44,27 @@ module Rscons
|
|||||||
evaluated_targets = Set.new
|
evaluated_targets = Set.new
|
||||||
attempt = lambda do |target|
|
attempt = lambda do |target|
|
||||||
evaluated_targets << target
|
evaluated_targets << target
|
||||||
@jobs[target][:sources].each do |src|
|
@jobs[target][0][:sources].each do |src|
|
||||||
if @jobs.include?(src) and not evaluated_targets.include?(src)
|
if @jobs.include?(src) and not evaluated_targets.include?(src)
|
||||||
return attempt[src]
|
return attempt[src]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
job = @jobs[target].merge(target: target)
|
job = @jobs[target][0].merge(target: target)
|
||||||
@jobs.delete(target)
|
if @jobs[target].size > 1
|
||||||
|
@jobs[target].slice!(0)
|
||||||
|
else
|
||||||
|
@jobs.delete(target)
|
||||||
|
end
|
||||||
return job
|
return job
|
||||||
end
|
end
|
||||||
attempt[@jobs.first.first]
|
attempt[@jobs.first.first]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Remove all jobs from the JobSet.
|
||||||
|
def clear!
|
||||||
|
@jobs.clear
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -966,4 +966,15 @@ EOF
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "Environment#clear_targets" do
|
||||||
|
it "clears registered targets" do
|
||||||
|
test_dir('header')
|
||||||
|
env = Rscons::Environment.new do |env|
|
||||||
|
env.Program('header', Dir['*.c'])
|
||||||
|
env.clear_targets
|
||||||
|
end
|
||||||
|
expect(lines).to eq []
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -169,7 +169,7 @@ module Rscons
|
|||||||
|
|
||||||
cache = "cache"
|
cache = "cache"
|
||||||
expect(Cache).to receive(:instance).and_return(cache)
|
expect(Cache).to receive(:instance).and_return(cache)
|
||||||
expect(cache).to receive(:clear_checksum_cache!)
|
allow(cache).to receive(:clear_checksum_cache!)
|
||||||
expect(env).to receive(:run_builder).with(anything, "a.out", ["main.c"], cache, {}).and_return(true)
|
expect(env).to receive(:run_builder).with(anything, "a.out", ["main.c"], cache, {}).and_return(true)
|
||||||
expect(cache).to receive(:write)
|
expect(cache).to receive(:write)
|
||||||
|
|
||||||
@ -183,7 +183,7 @@ module Rscons
|
|||||||
|
|
||||||
cache = "cache"
|
cache = "cache"
|
||||||
expect(Cache).to receive(:instance).and_return(cache)
|
expect(Cache).to receive(:instance).and_return(cache)
|
||||||
expect(cache).to receive(:clear_checksum_cache!)
|
allow(cache).to receive(:clear_checksum_cache!)
|
||||||
expect(env).to receive(:run_builder).with(anything, "main.o", ["other.cc"], cache, {}).and_return("main.o")
|
expect(env).to receive(:run_builder).with(anything, "main.o", ["other.cc"], cache, {}).and_return("main.o")
|
||||||
expect(env).to receive(:run_builder).with(anything, "a.out", ["main.o"], cache, {}).and_return("a.out")
|
expect(env).to receive(:run_builder).with(anything, "a.out", ["main.o"], cache, {}).and_return("a.out")
|
||||||
expect(cache).to receive(:write)
|
expect(cache).to receive(:write)
|
||||||
@ -198,7 +198,7 @@ module Rscons
|
|||||||
|
|
||||||
cache = "cache"
|
cache = "cache"
|
||||||
expect(Cache).to receive(:instance).and_return(cache)
|
expect(Cache).to receive(:instance).and_return(cache)
|
||||||
expect(cache).to receive(:clear_checksum_cache!)
|
allow(cache).to receive(:clear_checksum_cache!)
|
||||||
expect(env).to receive(:run_builder).with(anything, "main.o", ["other.cc"], cache, {}).and_return(false)
|
expect(env).to receive(:run_builder).with(anything, "main.o", ["other.cc"], cache, {}).and_return(false)
|
||||||
expect(cache).to receive(:write)
|
expect(cache).to receive(:write)
|
||||||
|
|
||||||
@ -221,18 +221,6 @@ module Rscons
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#clear_targets" do
|
|
||||||
it "resets @targets to an empty hash" do
|
|
||||||
env = Environment.new
|
|
||||||
env.Program("a.out", "main.o")
|
|
||||||
expect(env.instance_variable_get(:@targets).keys).to eq(["a.out"])
|
|
||||||
|
|
||||||
env.clear_targets
|
|
||||||
|
|
||||||
expect(env.instance_variable_get(:@targets).keys).to eq([])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "#build_command" do
|
describe "#build_command" do
|
||||||
it "returns a command based on the variables in the Environment" do
|
it "returns a command based on the variables in the Environment" do
|
||||||
env = Environment.new
|
env = Environment.new
|
||||||
@ -299,18 +287,6 @@ module Rscons
|
|||||||
expect {env.foobar}.to raise_error /undefined method .foobar./
|
expect {env.foobar}.to raise_error /undefined method .foobar./
|
||||||
end
|
end
|
||||||
|
|
||||||
it "records the target when the target method is a known builder" do
|
|
||||||
env = Environment.new
|
|
||||||
expect(env.instance_variable_get(:@targets)).to eq({})
|
|
||||||
env.Object("target.o", ["src1.c", "src2.c"], var: "val")
|
|
||||||
target = env.instance_variable_get(:@targets)["target.o"]
|
|
||||||
expect(target).to_not be_nil
|
|
||||||
expect(target[0][:builder].is_a?(Builder)).to be_truthy
|
|
||||||
expect(target[0][:sources]).to eq ["src1.c", "src2.c"]
|
|
||||||
expect(target[0][:vars]).to eq({var: "val"})
|
|
||||||
expect(target[0][:args]).to eq []
|
|
||||||
end
|
|
||||||
|
|
||||||
it "raises an error when vars is not a Hash" do
|
it "raises an error when vars is not a Hash" do
|
||||||
env = Environment.new
|
env = Environment.new
|
||||||
expect { env.Program("a.out", "main.c", "other") }.to raise_error /Unexpected construction variable set/
|
expect { env.Program("a.out", "main.c", "other") }.to raise_error /Unexpected construction variable set/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user