diff --git a/lib/rscons.rb b/lib/rscons.rb index 9a09e3c..e9cbbf6 100644 --- a/lib/rscons.rb +++ b/lib/rscons.rb @@ -23,6 +23,7 @@ module Rscons # Names of the default builders which will be added to all newly created # {Environment} objects. DEFAULT_BUILDERS = [ + :Barrier, :Command, :Copy, :Directory, @@ -66,6 +67,13 @@ module Rscons target.is_a?(Symbol) end + # Generate a random phony target name. + # + # @return [Symbol] Phony target name. + def gen_phony_target + ("t" + sprintf("%08x", rand(1_000_000..4_000_000_000))).to_sym + end + # Return the system shell and arguments for executing a shell command. # # @return [Array] The shell and flag. @@ -136,6 +144,7 @@ require_relative "rscons/builders/mixins/object_deps" require_relative "rscons/builders/mixins/program" # default builders +require_relative "rscons/builders/barrier" require_relative "rscons/builders/command" require_relative "rscons/builders/copy" require_relative "rscons/builders/directory" diff --git a/lib/rscons/builder_set.rb b/lib/rscons/builder_set.rb index 8373d78..f0bae36 100644 --- a/lib/rscons/builder_set.rb +++ b/lib/rscons/builder_set.rb @@ -37,7 +37,7 @@ module Rscons # The number of remaining build steps. def build_steps_remaining self.reduce(0) do |result, (target, builders)| - result + builders.size + result + builders.count {|b| !b.is_a?(Rscons::Builders::Barrier)} end end diff --git a/lib/rscons/builders/barrier.rb b/lib/rscons/builders/barrier.rb new file mode 100644 index 0000000..2328b9f --- /dev/null +++ b/lib/rscons/builders/barrier.rb @@ -0,0 +1,15 @@ +module Rscons + module Builders + # The Barrier builder does not perform any action. It exists as a builder + # on which to place dependencies to ensure that each of its sources are + # built before any build targets which depend on the barrier build target. + class Barrier < Builder + + # Run the builder. + def run(options) + true + end + + end + end +end diff --git a/lib/rscons/environment.rb b/lib/rscons/environment.rb index f27cd35..ebaaba6 100644 --- a/lib/rscons/environment.rb +++ b/lib/rscons/environment.rb @@ -397,7 +397,11 @@ module Rscons expand(ud) end @user_deps[target] ||= [] - @user_deps[target] = (@user_deps[target] + user_deps).uniq + (@user_deps[target] + user_deps).each do |ud| + unless Rscons.phony_target?(ud) || @user_deps[target].include?(ud) + @user_deps[target] << ud + end + end build_after(target, user_deps) end @@ -623,7 +627,9 @@ module Rscons # # @return [void] def run_builder(builder) - builder.build_step ||= get_next_build_step + unless builder.is_a?(Rscons::Builders::Barrier) + builder.build_step ||= get_next_build_step + end case result = builder.run({}) when Array result.each do |waititem| @@ -649,8 +655,10 @@ module Rscons Cache.instance.register_build(side_effect, nil, [], self, side_effect: true) @side_effects.delete(side_effect) end - @build_hooks[:post].each do |build_hook_block| - build_hook_block.call(builder) + unless builder.is_a?(Rscons::Builders::Barrier) + @build_hooks[:post].each do |build_hook_block| + build_hook_block.call(builder) + end end process_remove_wait(builder) else @@ -727,8 +735,10 @@ module Rscons if @builder_sets.size > 0 if builder = @builder_sets[0].get_next_builder_to_run(targets_still_building) builder.vars = @varset.merge(builder.vars) - @build_hooks[:pre].each do |build_hook_block| - build_hook_block.call(builder) + unless builder.is_a?(Rscons::Builders::Barrier) + @build_hooks[:pre].each do |build_hook_block| + build_hook_block.call(builder) + end end return run_builder(builder) end