def up_to_date?(targets, command, deps, env, options = {})
      Array(targets).each do |target|
        cache_key = get_cache_key(target)

        unless Rscons.phony_target?(target)
          # target file must exist on disk
          unless File.exists?(target)
            if options[:debug]
              puts "Target #{target} needs rebuilding because it does not exist on disk"
            end
            return false
          end
        end

        # target must be registered in the cache
        unless @cache["targets"].has_key?(cache_key)
          if options[:debug]
            puts "Target #{target} needs rebuilding because there is no cached build information for it"
          end
          return false
        end

        unless Rscons.phony_target?(target)
          # target must have the same checksum as when it was built last
          unless @cache["targets"][cache_key]["checksum"] == lookup_checksum(target)
            if options[:debug]
              puts "Target #{target} needs rebuilding because it has been changed on disk since being built last"
            end
            return false
          end
        end

        # command used to build target must be identical
        unless @cache["targets"][cache_key]["command"] == Digest::MD5.hexdigest(command.inspect)
          if options[:debug]
            puts "Target #{target} needs rebuilding because the command used to build it has changed"
          end
          return false
        end

        cached_deps = @cache["targets"][cache_key]["deps"] || []
        cached_deps_fnames = cached_deps.map { |dc| dc["fname"] }
        if options[:strict_deps]
          # depedencies passed in must exactly equal those in the cache
          unless deps == cached_deps_fnames
            if options[:debug]
              puts "Target #{target} needs rebuilding because the :strict_deps option is given and the set of dependencies does not match the previous set of dependencies"
            end
            return false
          end
        else
          # all dependencies passed in must exist in cache (but cache may have more)
          unless (Set.new(deps) - Set.new(cached_deps_fnames)).empty?
            if options[:debug]
              puts "Target #{target} needs rebuilding because there are new dependencies"
            end
            return false
          end
        end

        # set of user dependencies must match
        user_deps = env.get_user_deps(target) || []
        cached_user_deps = @cache["targets"][cache_key]["user_deps"] || []
        cached_user_deps_fnames = cached_user_deps.map { |dc| dc["fname"] }
        unless user_deps == cached_user_deps_fnames
          if options[:debug]
            puts "Target #{target} needs rebuilding because the set of user-specified dependency files has changed"
          end
          return false
        end

        # all cached dependencies must have their checksums match
        (cached_deps + cached_user_deps).each do |dep_cache|
          unless dep_cache["checksum"] == lookup_checksum(dep_cache["fname"])
            if options[:debug]
              puts "Target #{target} needs rebuilding because dependency file #{dep_cache["fname"]} has changed"
            end
            return false
          end
        end
      end

      true
    end
def up_to_date?(targets, command, deps, env, options = {})
      Array(targets).each do |target|
        cache_key = get_cache_key(target)

        unless Rscons.phony_target?(target)
          # target file must exist on disk
          unless File.exists?(target)
            if options[:debug]
              puts "Target #{target} needs rebuilding because it does not exist on disk"
            end
            return false
          end
        end

        # target must be registered in the cache
        unless @cache["targets"].has_key?(cache_key)
          if options[:debug]
            puts "Target #{target} needs rebuilding because there is no cached build information for it"
          end
          return false
        end

        unless Rscons.phony_target?(target)
          # target must have the same checksum as when it was built last
          unless @cache["targets"][cache_key]["checksum"] == lookup_checksum(target)
            if options[:debug]
              puts "Target #{target} needs rebuilding because it has been changed on disk since being built last"
            end
            return false
          end
        end

        # command used to build target must be identical
        unless @cache["targets"][cache_key]["command"] == Digest::MD5.hexdigest(command.inspect)
          if options[:debug]
            puts "Target #{target} needs rebuilding because the command used to build it has changed"
          end
          return false
        end

        cached_deps = @cache["targets"][cache_key]["deps"] || []
        cached_deps_fnames = cached_deps.map { |dc| dc["fname"] }
        if options[:strict_deps]
          # depedencies passed in must exactly equal those in the cache
          unless deps == cached_deps_fnames
            if options[:debug]
              puts "Target #{target} needs rebuilding because the :strict_deps option is given and the set of dependencies does not match the previous set of dependencies"
            end
            return false
          end
        else
          # all dependencies passed in must exist in cache (but cache may have more)
          unless (Set.new(deps) - Set.new(cached_deps_fnames)).empty?
            if options[:debug]
              puts "Target #{target} needs rebuilding because there are new dependencies"
            end
            return false
          end
        end

        # set of user dependencies must match
        user_deps = env.get_user_deps(target) || []
        cached_user_deps = @cache["targets"][cache_key]["user_deps"] || []
        cached_user_deps_fnames = cached_user_deps.map { |dc| dc["fname"] }
        unless user_deps == cached_user_deps_fnames
          if options[:debug]
            puts "Target #{target} needs rebuilding because the set of user-specified dependency files has changed"
          end
          return false
        end

        # all cached dependencies must have their checksums match
        (cached_deps + cached_user_deps).each do |dep_cache|
          unless dep_cache["checksum"] == lookup_checksum(dep_cache["fname"])
            if options[:debug]
              puts "Target #{target} needs rebuilding because dependency file #{dep_cache["fname"]} has changed"
            end
            return false
          end
        end
      end

      true
    end
Check if target(s) are up to date.

 @param targets [Symbol, String, Array<String>]
   The name(s) of the target file(s).
 @param command [String, Array, Hash]
   The command used to build the target. The command parameter can
   actually be a String, Array, or Hash and could contain information
   other than just the actual command used to build the target. For the
   purposes of the Cache, any difference in the command argument will
   trigger a rebuild.
 @param deps [Array<String>] List of the target's dependency files.
 @param env [Environment] The Rscons::Environment.
 @param options [Hash] Optional options.
 @option options [Boolean] :debug
   If turned on, this causes the Cache to print messages explaining why
   a build target is out of date. This could aid a builder author in
   debugging the operation of their builder.
 @option options [Boolean] :strict_deps
   Only consider a target up to date if its list of dependencies is
   exactly equal (including order) to the cached list of dependencies

 @return [Boolean]
   True value if the targets are all up to date, meaning that,
   for each target:
   - the target exists on disk
   - the cache has information for the target
   - the target's checksum matches its checksum when it was last built
   - the command used to build the target is the same as last time
   - all dependencies listed are also listed in the cache, or, if
     :strict_deps was given in options, the list of dependencies is
     exactly equal to those cached
   - each cached dependency file's current checksum matches the checksum
     stored in the cache file