lib/rscons/environment.rb in rscons-1.3.0 vs lib/rscons/environment.rb in rscons-1.4.0

- old
+ new

@@ -84,11 +84,11 @@ if clone.include?(:builders) @builders.each do |builder_name, builder| env.add_builder(builder) end end - env.append(@varset.clone) if clone.include?(:variables) + env.append(@varset) if clone.include?(:variables) env.build_root = @build_root if clone.include?(:build_root) if clone.include?(:build_dirs) @build_dirs.each do |src_dir, obj_dir| env.build_dir(src_dir, obj_dir) end @@ -162,42 +162,48 @@ end # Add a set of construction variables or environment options. # @see VarSet#append def append(*args) - @varset.send(:append, *args) + @varset.append(*args) end # Build all target specified in the Environment. # When a block is passed to Environment.new, this method is automatically # called after the block returns. def process - cache = Cache.new - targets_processed = {} - process_target = proc do |target| - targets_processed[target] ||= begin - @targets[target][:source].each do |src| - if @targets.include?(src) and not targets_processed.include?(src) - process_target.call(src) + unless @targets.empty? + clean_target_paths! + cache = Cache.instance + cache.clear_checksum_cache! + targets_processed = {} + 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][:source], - cache, - @targets[target][:vars] || {}) - unless result - cache.write - raise BuildError.new("Failed to build #{target}") + end + begin + @targets.each do |target, target_params| + process_target.call(target) end - result + ensure + cache.write end end - @targets.each do |target, info| - process_target.call(target) - end - cache.write end # Clear all targets registered for the Environment. def clear_targets @targets = {} @@ -244,29 +250,32 @@ print_command.call end end end - alias_method :orig_method_missing, :method_missing def method_missing(method, *args) if @builders.has_key?(method.to_s) - target, source, vars, *rest = args + target, sources, vars, *rest = args unless vars.nil? or vars.is_a?(Hash) or vars.is_a?(VarSet) raise "Unexpected construction variable set: #{vars.inspect}" end - source = [source] unless source.is_a?(Array) - @targets[target] = { - builder: @builders[method.to_s], - source: source, - vars: vars, - args: rest, - } + sources = [sources] unless sources.is_a?(Array) + add_target(target, @builders[method.to_s], sources, vars, rest) else - orig_method_missing(method, *args) + super end end + def add_target(target, builder, sources, vars, args) + @targets[target] = { + builder: builder, + sources: sources, + vars: vars, + args: args, + } + end + # Manually record a given target as depending on the specified # dependency files. def depends(target, *user_deps) @user_deps[target] ||= [] @user_deps[target] = (@user_deps[target] + user_deps).uniq @@ -319,13 +328,35 @@ build_operation = { builder: builder, target: target, sources: sources, vars: vars, + env: self, } build_hook_block.call(build_operation) end builder.run(target, sources, cache, self, vars) + end + + private + + # Expand all target paths that begin with ^/ to be relative to the + # Environment's build root, if present + def clean_target_paths! + if @build_root + expand = lambda do |path| + path.sub(%r{^\^(?=[\\/])}, @build_root) + end + + new_targets = {} + @targets.each_pair do |target, target_params| + target_params[:sources].map! do |source| + expand[source] + end + new_targets[expand[target]] = target_params + end + @targets = new_targets + end end # Parse dependencies for a given target from a Makefile. # This method is used internally by Rscons builders. # @param mf_fname [String] File name of the Makefile to read.