diff --git a/lib/rscons/environment.rb b/lib/rscons/environment.rb index 24a6a0e..5b40799 100644 --- a/lib/rscons/environment.rb +++ b/lib/rscons/environment.rb @@ -176,29 +176,31 @@ module Rscons cache.clear_checksum_cache! targets_processed = {} unless @targets.empty? - process_target = proc do |target| - targets_processed[target] ||= begin - @targets[target][:sources].each do |src| - if @targets.include?(src) and not targets_processed.include?(src) - process_target.call(src) + begin + process_target = proc do |target| + targets_processed[target] ||= begin + @targets[target][:sources].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][:sources], + cache, + @targets[target][:vars] || {}) + unless result + raise BuildError.new("Failed to build #{target}") + end + result end - result = run_builder(@targets[target][:builder], - target, - @targets[target][:sources], - cache, - @targets[target][:vars] || {}) - unless result - cache.write - raise BuildError.new("Failed to build #{target}") - end - result end + @targets.each do |target, target_params| + process_target.call(target) + end + ensure + cache.write end - @targets.each do |target, target_params| - process_target.call(target) - end - cache.write end end diff --git a/spec/rscons/environment_spec.rb b/spec/rscons/environment_spec.rb index 09b9347..eaca0c9 100644 --- a/spec/rscons/environment_spec.rb +++ b/spec/rscons/environment_spec.rb @@ -176,6 +176,21 @@ module Rscons expect { env.process }.to raise_error BuildError, /Failed.to.build.main.o/ end + + it "writes the cache when the Builder raises an exception" do + env = Environment.new + env.Object("module.o", "module.c") + + cache = "cache" + Cache.should_receive(:instance).and_return(cache) + cache.should_receive(:clear_checksum_cache!) + env.stub(:run_builder) do |builder, target, sources, cache, vars| + raise "Ruby exception thrown by builder" + end + cache.should_receive(:write) + + expect { env.process }.to raise_error RuntimeError, /Ruby exception thrown by builder/ + end end describe "#clear_targets" do