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.