lib/rscons/environment.rb in rscons-0.2.2 vs lib/rscons/environment.rb in rscons-0.3.0

- old
+ new

@@ -7,68 +7,80 @@ # rules for building targets. class Environment # Hash of +{"builder_name" => builder_object}+ pairs. attr_reader :builders + # :command, :short, or :off + attr_accessor :echo + # String or +nil+ - attr_accessor :build_root + attr_reader :build_root + def build_root=(build_root) + @build_root = build_root.gsub('\\', '/') + end # Create an Environment object. - # @param variables [Hash] - # The variables hash can contain construction variables, which are - # uppercase strings (such as "CC" or "LDFLAGS"), user variables, which - # are lowercase strings (such as "sources"), and RScons options, which - # are lowercase symbols (such as :echo). + # @param options [Hash] + # Possible options keys: + # :echo => :command, :short, or :off (default :short) + # :build_root => String specifying build root directory (default nil) + # :exclude_builders => true to omit adding default builders (default false) # If a block is given, the Environment object is yielded to the block and # when the block returns, the {#process} method is automatically called. - def initialize(variables = {}) - @varset = VarSet.new(variables) + def initialize(options = {}) + @varset = VarSet.new @targets = {} + @user_deps = {} @builders = {} @build_dirs = [] @build_hooks = [] - @varset[:exclude_builders] ||= [] - unless @varset[:exclude_builders] == :all - exclude_builders = Set.new(@varset[:exclude_builders] || []) - DEFAULT_BUILDERS.each do |builder_class| - unless exclude_builders.include?(builder_class.short_name) - add_builder(builder_class.new) - end + unless options[:exclude_builders] + DEFAULT_BUILDERS.each do |builder_class_name| + builder_class = Builders.const_get(builder_class_name) + builder_class or raise "Could not find builder class #{builder_class_name}" + add_builder(builder_class.new) end end - @varset[:echo] ||= :short + @echo = options[:echo] || :short + @build_root = options[:build_root] if block_given? yield self self.process end end # Make a copy of the Environment object. # The cloned environment will contain a copy of all environment options, - # construction variables, and builders. It will not contain a copy of the - # targets, build hooks, build directories, or the build root. If a block - # is given, the Environment object is yielded to the block and when the - # block returns, the {#process} method is automatically called. - def clone(variables = {}) - env = self.class.new - @builders.each do |builder_name, builder| - env.add_builder(builder) + # construction variables, and builders (unless :exclude_builders => true is + # passed as an option). It will not contain a copy of the targets, build + # hooks, build directories, or the build root. If a block is given, the + # Environment object is yielded to the block and when the block returns, + # the {#process} method is automatically called. The possible options keys + # match those documented in the #initialize method. + def clone(options = {}) + env = self.class.new( + echo: options[:echo] || @echo, + build_root: options[:build_root], + exclude_builders: true) + unless options[:exclude_builders] + @builders.each do |builder_name, builder| + env.add_builder(builder) + end end env.append(@varset.clone) - env.append(variables) if block_given? yield env env.process end env end # Add a {Builder} object to the Environment. def add_builder(builder) - @builders[builder.class.short_name] = builder + @builders[builder.name] = builder var_defs = builder.default_variables(self) if var_defs var_defs.each_pair do |var, val| @varset[var] ||= val end @@ -97,11 +109,11 @@ else build_fname.sub!(%r{^#{src_dir}/}, "#{obj_dir}/") end end if @build_root and not found_match - unless source_fname.start_with?('/') or source_fname =~ %r{^\w:[\\/]} + unless source_fname.absolute_path? or build_fname.start_with?("#{@build_root}/") build_fname = "#{@build_root}/#{build_fname}" end end build_fname.gsub!('\\', '/') build_fname @@ -154,10 +166,15 @@ process_target.call(target) end cache.write end + # Clear all targets registered for the Environment. + def clear_targets + @targets = {} + end + # Build a command line from the given template, resolving references to # variables using the Environment's construction variables and any extra # variables specified. # @param command_template [Array] template for the command with variable # references @@ -167,25 +184,25 @@ def build_command(command_template, extra_vars) @varset.merge(extra_vars).expand_varref(command_template) end # Execute a builder command - # @param short_desc [String] Message to print if the Environment's :echo + # @param short_desc [String] Message to print if the Environment's echo # mode is set to :short # @param command [Array] The command to execute. # @param options [Hash] Optional options to pass to Kernel#system. def execute(short_desc, command, options = {}) print_command = proc do puts command.map { |c| c =~ /\s/ ? "'#{c}'" : c }.join(' ') end - if @varset[:echo] == :command + if @echo == :command print_command.call - elsif @varset[:echo] == :short + elsif @echo == :short puts short_desc end system(*command, options).tap do |result| - unless result or @varset[:echo] == :command + unless result or @echo == :command $stdout.write "Failed command was: " print_command.call end end end @@ -207,18 +224,31 @@ else orig_method_missing(method, *args) end 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 + end + + # Return the list of user dependencies for a given target, or +nil+ for + # none. + def get_user_deps(target) + @user_deps[target] + end + # Build a list of source files into files containing one of the suffixes # given by suffixes. # This method is used internally by RScons builders. # @param sources [Array] List of source files to build. # @param suffixes [Array] List of suffixes to try to convert source files into. # @param cache [Cache] The Cache. # @param vars [Hash] Extra variables to pass to the builder. # Return a list of the converted file names. - def build_sources(sources, suffixes, cache, vars = {}) + def build_sources(sources, suffixes, cache, vars) sources.map do |source| if source.has_suffix?(suffixes) source else converted = nil