From 29a8684f909b42f3efb03c1e8d468321c61dc07b Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Wed, 28 Jan 2015 17:10:36 -0500 Subject: [PATCH] support registering multiple build targets with the same path - close #26 --- lib/rscons/environment.rb | 51 ++++++++++++++++++--------------- spec/build_tests_spec.rb | 14 +++++++++ spec/rscons/environment_spec.rb | 8 +++--- 3 files changed, 46 insertions(+), 27 deletions(-) diff --git a/lib/rscons/environment.rb b/lib/rscons/environment.rb index a230c9e..3f2f5b5 100644 --- a/lib/rscons/environment.rb +++ b/lib/rscons/environment.rb @@ -280,33 +280,35 @@ module Rscons # # @return [void] def process - expand_paths! while @targets.size > 0 + expand_paths! targets = @targets @targets = {} cache = Cache.instance cache.clear_checksum_cache! - targets_processed = {} + targets_processed = Set.new 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) + unless targets_processed.include?(target) + targets_processed << target + targets[target].each do |target_params| + target_params[:sources].each do |src| + if targets.include?(src) and not targets_processed.include?(src) + process_target.call(src) + 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 - 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 end begin - targets.each do |target, target_params| + targets.each_key do |target| process_target.call(target) end ensure @@ -404,7 +406,8 @@ module Rscons # # @return [void] def add_target(target, builder, sources, vars, args) - @targets[target] = { + @targets[target] ||= [] + @targets[target] << { builder: builder, sources: sources, vars: vars, @@ -679,14 +682,16 @@ module Rscons # # @return [void] def expand_paths! - @targets = @targets.reduce({}) do |result, (target, target_params)| - sources = target_params[:sources].map do |source| - source = expand_path(source) if @build_root - expand_varref(source) - end.flatten + @targets = @targets.reduce({}) do |result, (target, target_params_list)| target = expand_path(target) if @build_root target = expand_varref(target) - result[target] = target_params.merge(sources: sources) + result[target] = target_params_list.map do |target_params| + sources = target_params[:sources].map do |source| + source = expand_path(source) if @build_root + expand_varref(source) + end.flatten + target_params.merge(sources: sources) + end result end end diff --git a/spec/build_tests_spec.rb b/spec/build_tests_spec.rb index 63e6598..337e66f 100644 --- a/spec/build_tests_spec.rb +++ b/spec/build_tests_spec.rb @@ -764,4 +764,18 @@ EOF expect(`./simple`).to eq "This is a simple C program\n" end + it "supports registering multiple build targets with the same target path" do + test_dir("build_dir") + Rscons::Environment.new do |env| + env["CPPPATH"] << "src/two" + env.Object("one.o", "src/one/one.c") + env.Object("one.o", "src/two/two.c") + end + expect(File.exists?("one.o")).to be_truthy + expect(lines).to eq([ + "CC one.o", + "CC one.o", + ]) + end + end diff --git a/spec/rscons/environment_spec.rb b/spec/rscons/environment_spec.rb index 5d1045f..e81219b 100644 --- a/spec/rscons/environment_spec.rb +++ b/spec/rscons/environment_spec.rb @@ -305,10 +305,10 @@ module Rscons 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[:builder].is_a?(Builder)).to be_truthy - expect(target[:sources]).to eq ["src1.c", "src2.c"] - expect(target[:vars]).to eq({var: "val"}) - expect(target[:args]).to eq [] + 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