From e863c9a564b469137231fbb8500100aac1172952 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Tue, 5 Nov 2013 12:43:50 -0500 Subject: [PATCH] Environment: rework process() - improve efficiency - give errors for the dependency that failed instead of the top-level target --- lib/rscons/environment.rb | 34 +++++++++++++++++---------------- spec/rscons/environment_spec.rb | 16 +++++++++++++++- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/lib/rscons/environment.rb b/lib/rscons/environment.rb index f4fd2de..cdd52c1 100644 --- a/lib/rscons/environment.rb +++ b/lib/rscons/environment.rb @@ -125,26 +125,28 @@ module Rscons # called after the block returns. def process cache = Cache.new - targets_processed = Set.new + targets_processed = {} process_target = proc do |target| - if @targets[target][:source].map do |src| - targets_processed.include?(src) or not @targets.include?(src) or process_target.call(src) - end.all? - run_builder(@targets[target][:builder], - target, - @targets[target][:source], - cache, - @targets[target][:vars] || {}) - else - false + targets_processed[target] ||= begin + @targets[target][:source].each do |src| + if @targets.include?(src) and not targets_processed.include?(src) + process_target.call(src) + end + end + result = run_builder(@targets[target][:builder], + target, + @targets[target][:source], + cache, + @targets[target][:vars] || {}) + unless result + cache.write + raise BuildError.new("Failed to build #{target}") + end + result end end @targets.each do |target, info| - next if targets_processed.include?(target) - unless process_target.call(target) - cache.write - raise BuildError.new("Failed to build #{target}") - end + process_target.call(target) end cache.write end diff --git a/spec/rscons/environment_spec.rb b/spec/rscons/environment_spec.rb index fec1ee5..f00a826 100644 --- a/spec/rscons/environment_spec.rb +++ b/spec/rscons/environment_spec.rb @@ -113,6 +113,20 @@ module Rscons env.process end + it "builds dependent targets first" do + env = Environment.new + env.Program("a.out", "main.o") + env.Object("main.o", "other.cc") + + cache = "cache" + Cache.should_receive(:new).and_return(cache) + env.should_receive(:run_builder).with(anything, "main.o", ["other.cc"], cache, {}).and_return("main.o") + env.should_receive(:run_builder).with(anything, "a.out", ["main.o"], cache, {}).and_return("a.out") + cache.should_receive(:write) + + env.process + end + it "raises a BuildError when building fails" do env = Environment.new env.Program("a.out", "main.o") @@ -123,7 +137,7 @@ module Rscons env.should_receive(:run_builder).with(anything, "main.o", ["other.cc"], cache, {}).and_return(false) cache.should_receive(:write) - expect { env.process }.to raise_error BuildError, /Failed.to.build.a\.out/ + expect { env.process }.to raise_error BuildError, /Failed.to.build.main.o/ end end