added more documentation to get to 100% YARD coverage; fix YARD warnings

This commit is contained in:
Josh Holtrop 2014-06-16 15:33:22 -04:00
parent d87c4990b1
commit 912615535a
13 changed files with 309 additions and 39 deletions

View File

@ -268,8 +268,8 @@ env.Preprocess(target, source)
env.Preprocess("module-preprocessed.cc", "module.cc") env.Preprocess("module-preprocessed.cc", "module.cc")
``` ```
The Preprocess builder invokes either ${CC} or ${CXX} (depending on if the The Preprocess builder invokes either `${CC}` or `${CXX}` (depending on if the
source contains an extension in ${CXXSUFFIX} or not) and writes the source contains an extension in `${CXXSUFFIX}` or not) and writes the
preprocessed output to the target file. preprocessed output to the target file.
#### Program #### Program

View File

@ -15,6 +15,8 @@ require_relative "rscons/builders/program"
# Namespace module for rscons classes # Namespace module for rscons classes
module Rscons module Rscons
# Names of the default builders which will be added to all newly created
# {Environment} objects.
DEFAULT_BUILDERS = [ DEFAULT_BUILDERS = [
:CFile, :CFile,
:Disassemble, :Disassemble,
@ -24,9 +26,10 @@ module Rscons
:Program, :Program,
] ]
# Class to represent a fatal error while building a target.
class BuildError < RuntimeError; end class BuildError < RuntimeError; end
# Remove all generated files # Remove all generated files.
def self.clean def self.clean
cache = Cache.instance cache = Cache.instance
# remove all built files # remove all built files
@ -43,20 +46,27 @@ module Rscons
cache.clear cache.clear
end end
# Return whether the given path is an absolute filesystem path or not # Return whether the given path is an absolute filesystem path.
# @param path [String] the path to examine #
# @param path [String] the path to examine.
#
# @return [Boolean] Whether the given path is an absolute filesystem path.
def self.absolute_path?(path) def self.absolute_path?(path)
path =~ %r{^(/|\w:[\\/])} path =~ %r{^(/|\w:[\\/])}
end end
# Return a new path by changing the suffix in path to suffix. # Return a new path by changing the suffix in path to suffix.
# @param path [String] the path to alter #
# @param suffix [String] the new filename suffix # @param path [String] The path to alter.
# @param suffix [String] The new filename suffix, e.g. ".exe".
#
# @return [String] New path.
def self.set_suffix(path, suffix) def self.set_suffix(path, suffix)
path.sub(/\.[^.]*$/, suffix) path.sub(/\.[^.]*$/, suffix)
end end
# Return the system shell and arguments for executing a shell command. # Return the system shell and arguments for executing a shell command.
#
# @return [Array<String>] The shell and flag. # @return [Array<String>] The shell and flag.
def self.get_system_shell def self.get_system_shell
@@shell ||= @@shell ||=

View File

@ -18,6 +18,8 @@ module Rscons
# Manually record a given target as depending on the specified files. # Manually record a given target as depending on the specified files.
# #
# @param user_deps [Array<String>] Dependency files. # @param user_deps [Array<String>] Dependency files.
#
# @return [void]
def depends(*user_deps) def depends(*user_deps)
@env.depends(@target, *user_deps) @env.depends(@target, *user_deps)
end end

View File

@ -7,14 +7,17 @@ module Rscons
# Class to hold an object that knows how to build a certain type of file. # Class to hold an object that knows how to build a certain type of file.
class Builder class Builder
# Return the name of the builder. # Return the name of the builder.
#
# If not overridden this defaults to the last component of the class name. # If not overridden this defaults to the last component of the class name.
def name def name
self.class.name.split(":").last self.class.name.split(":").last
end end
# Return a set of default variable values for the Environment to use # Return a set of default construction variables for the builder.
# unless the user overrides any. #
# @param env [Environment] The Environment. # @param env [Environment] The Environment.
#
# @return [Hash] Default construction variables.
def default_variables(env) def default_variables(env)
{} {}
end end
@ -39,16 +42,33 @@ module Rscons
# Return whether this builder object is capable of producing a given target # Return whether this builder object is capable of producing a given target
# file name from a given source file name. # file name from a given source file name.
#
# @param target [String] The target file name. # @param target [String] The target file name.
# @param source [String, Array] The source file name(s). # @param source [String, Array] The source file name(s).
# @param env [Environment] The Environment. # @param env [Environment] The Environment.
#
# @return [Boolean]
# Whether this builder object is capable of producing a given target
# file name from a given source file name.
def produces?(target, source, env) def produces?(target, source, env)
false false
end end
# Check if the cache is up to date for the target and if not execute the # Check if the cache is up to date for the target and if not execute the
# build command. # build command.
# Return the name of the target or false on failure. #
# @param short_cmd_string [String]
# Short description of build action to be printed when env.echo ==
# :short.
# @param target [String] Name of the target file.
# @param command [Array<String>]
# The command to execute to build the target.
# @param sources [Array<String>] Source file name(s).
# @param env [Environment] The Environment executing the builder.
# @param cache [Cache] The Cache object.
#
# @return [String,false]
# The name of the target on success or false on failure.
def standard_build(short_cmd_string, target, command, sources, env, cache) def standard_build(short_cmd_string, target, command, sources, env, cache)
unless cache.up_to_date?(target, command, sources, env) unless cache.up_to_date?(target, command, sources, env)
cache.mkdir_p(File.dirname(target)) cache.mkdir_p(File.dirname(target))

View File

@ -7,6 +7,11 @@ module Rscons
# env.CFile("parser.tab.cc", "parser.yy") # env.CFile("parser.tab.cc", "parser.yy")
# env.CFile("lex.yy.cc", "parser.ll") # env.CFile("lex.yy.cc", "parser.ll")
class CFile < Builder class CFile < Builder
# Return default construction variables for the builder.
#
# @param env [Environment] The Environment using the builder.
#
# @return [Hash] Default construction variables for the builder.
def default_variables(env) def default_variables(env)
{ {
"YACC" => "bison", "YACC" => "bison",
@ -18,6 +23,16 @@ module Rscons
} }
end end
# Run the builder to produce a build target.
#
# @param target [String] Target file name.
# @param sources [Array<String>] Source file name(s).
# @param cache [Cache] The Cache object.
# @param env [Environment] The Environment executing the builder.
# @param vars [Hash,VarSet] Extra construction variables.
#
# @return [String,false]
# Name of the target file on success or false on failure.
def run(target, sources, cache, env, vars) def run(target, sources, cache, env, vars)
vars = vars.merge({ vars = vars.merge({
"_TARGET" => target, "_TARGET" => target,

View File

@ -2,6 +2,11 @@ module Rscons
module Builders module Builders
# The Disassemble builder produces a disassembly listing of a source file. # The Disassemble builder produces a disassembly listing of a source file.
class Disassemble < Builder class Disassemble < Builder
# Return default construction variables for the builder.
#
# @param env [Environment] The Environment using the builder.
#
# @return [Hash] Default construction variables for the builder.
def default_variables(env) def default_variables(env)
{ {
"OBJDUMP" => "objdump", "OBJDUMP" => "objdump",
@ -10,6 +15,16 @@ module Rscons
} }
end end
# Run the builder to produce a build target.
#
# @param target [String] Target file name.
# @param sources [Array<String>] Source file name(s).
# @param cache [Cache] The Cache object.
# @param env [Environment] The Environment executing the builder.
# @param vars [Hash,VarSet] Extra construction variables.
#
# @return [String,false]
# Name of the target file on success or false on failure.
def run(target, sources, cache, env, vars) def run(target, sources, cache, env, vars)
vars = vars.merge("_SOURCES" => sources) vars = vars.merge("_SOURCES" => sources)
command = env.build_command("${DISASM_CMD}", vars) command = env.build_command("${DISASM_CMD}", vars)

View File

@ -2,6 +2,11 @@ module Rscons
module Builders module Builders
# A default Rscons builder that produces a static library archive. # A default Rscons builder that produces a static library archive.
class Library < Builder class Library < Builder
# Return default construction variables for the builder.
#
# @param env [Environment] The Environment using the builder.
#
# @return [Hash] Default construction variables for the builder.
def default_variables(env) def default_variables(env)
{ {
'AR' => 'ar', 'AR' => 'ar',
@ -11,6 +16,16 @@ module Rscons
} }
end end
# Run the builder to produce a build target.
#
# @param target [String] Target file name.
# @param sources [Array<String>] Source file name(s).
# @param cache [Cache] The Cache object.
# @param env [Environment] The Environment executing the builder.
# @param vars [Hash,VarSet] Extra construction variables.
#
# @return [String,false]
# Name of the target file on success or false on failure.
def run(target, sources, cache, env, vars) def run(target, sources, cache, env, vars)
# build sources to linkable objects # build sources to linkable objects
objects = env.build_sources(sources, env.expand_varref(["${OBJSUFFIX}", "${LIBSUFFIX}"], vars).flatten, cache, vars) objects = env.build_sources(sources, env.expand_varref(["${OBJSUFFIX}", "${LIBSUFFIX}"], vars).flatten, cache, vars)

View File

@ -3,6 +3,7 @@ module Rscons
# A default Rscons builder which knows how to produce an object file from # A default Rscons builder which knows how to produce an object file from
# various types of source files. # various types of source files.
class Object < Builder class Object < Builder
# Mapping of known sources from which to build object files.
KNOWN_SUFFIXES = { KNOWN_SUFFIXES = {
"AS" => "ASSUFFIX", "AS" => "ASSUFFIX",
"CC" => "CSUFFIX", "CC" => "CSUFFIX",
@ -10,6 +11,11 @@ module Rscons
"DC" => "DSUFFIX", "DC" => "DSUFFIX",
} }
# Return default construction variables for the builder.
#
# @param env [Environment] The Environment using the builder.
#
# @return [Hash] Default construction variables for the builder.
def default_variables(env) def default_variables(env)
{ {
'OBJSUFFIX' => '.o', 'OBJSUFFIX' => '.o',
@ -51,12 +57,32 @@ module Rscons
} }
end end
# Return whether this builder object is capable of producing a given target
# file name from a given source file name.
#
# @param target [String] The target file name.
# @param source [String, Array] The source file name(s).
# @param env [Environment] The Environment.
#
# @return [Boolean]
# Whether this builder object is capable of producing a given target
# file name from a given source file name.
def produces?(target, source, env) def produces?(target, source, env)
target.end_with?(*env['OBJSUFFIX']) and KNOWN_SUFFIXES.find do |compiler, suffix_var| target.end_with?(*env['OBJSUFFIX']) and KNOWN_SUFFIXES.find do |compiler, suffix_var|
source.end_with?(*env[suffix_var]) source.end_with?(*env[suffix_var])
end end
end end
# Run the builder to produce a build target.
#
# @param target [String] Target file name.
# @param sources [Array<String>] Source file name(s).
# @param cache [Cache] The Cache object.
# @param env [Environment] The Environment executing the builder.
# @param vars [Hash,VarSet] Extra construction variables.
#
# @return [String,false]
# Name of the target file on success or false on failure.
def run(target, sources, cache, env, vars) def run(target, sources, cache, env, vars)
vars = vars.merge({ vars = vars.merge({
'_TARGET' => target, '_TARGET' => target,

View File

@ -2,12 +2,27 @@ module Rscons
module Builders module Builders
# The Preprocess builder invokes the C preprocessor # The Preprocess builder invokes the C preprocessor
class Preprocess < Builder class Preprocess < Builder
# Return default construction variables for the builder.
#
# @param env [Environment] The Environment using the builder.
#
# @return [Hash] Default construction variables for the builder.
def default_variables(env) def default_variables(env)
{ {
"CPP_CMD" => ["${_PREPROCESS_CC}", "-E", "-o", "${_TARGET}", "-I${CPPPATH}", "${CPPFLAGS}", "${CFLAGS}", "${_SOURCES}"], "CPP_CMD" => ["${_PREPROCESS_CC}", "-E", "-o", "${_TARGET}", "-I${CPPPATH}", "${CPPFLAGS}", "${CFLAGS}", "${_SOURCES}"],
} }
end end
# Run the builder to produce a build target.
#
# @param target [String] Target file name.
# @param sources [Array<String>] Source file name(s).
# @param cache [Cache] The Cache object.
# @param env [Environment] The Environment executing the builder.
# @param vars [Hash,VarSet] Extra construction variables.
#
# @return [String,false]
# Name of the target file on success or false on failure.
def run(target, sources, cache, env, vars) def run(target, sources, cache, env, vars)
pp_cc = if sources.find {|s| s.end_with?(*env.expand_varref("${CXXSUFFIX}", vars))} pp_cc = if sources.find {|s| s.end_with?(*env.expand_varref("${CXXSUFFIX}", vars))}
"${CXX}" "${CXX}"

View File

@ -3,6 +3,11 @@ module Rscons
# A default Rscons builder that knows how to link object files into an # A default Rscons builder that knows how to link object files into an
# executable program. # executable program.
class Program < Builder class Program < Builder
# Return default construction variables for the builder.
#
# @param env [Environment] The Environment using the builder.
#
# @return [Hash] Default construction variables for the builder.
def default_variables(env) def default_variables(env)
{ {
'OBJSUFFIX' => '.o', 'OBJSUFFIX' => '.o',
@ -18,6 +23,20 @@ module Rscons
} }
end end
# Create a BuildTarget object for this build target.
#
# The build target filename is given a ".exe" suffix if Rscons is
# executing on a Windows platform and no other suffix is given.
#
# @param options [Hash] Options to create the BuildTarget with.
# @option options [Environment] :env
# The Environment.
# @option options [String] :target
# The user-supplied target name.
# @option options [Array<String>] :sources
# The user-supplied source file name(s).
#
# @return [BuildTarget]
def create_build_target(options) def create_build_target(options)
my_options = options.dup my_options = options.dup
unless my_options[:target] =~ /\./ unless my_options[:target] =~ /\./
@ -26,6 +45,16 @@ module Rscons
super(my_options) super(my_options)
end end
# Run the builder to produce a build target.
#
# @param target [String] Target file name.
# @param sources [Array<String>] Source file name(s).
# @param cache [Cache] The Cache object.
# @param env [Environment] The Environment executing the builder.
# @param vars [Hash,VarSet] Extra construction variables.
#
# @return [String,false]
# Name of the target file on success or false on failure.
def run(target, sources, cache, env, vars) def run(target, sources, cache, env, vars)
# build sources to linkable objects # build sources to linkable objects
objects = env.build_sources(sources, env.expand_varref(["${OBJSUFFIX}", "${LIBSUFFIX}"], vars).flatten, cache, vars) objects = env.build_sources(sources, env.expand_varref(["${OBJSUFFIX}", "${LIBSUFFIX}"], vars).flatten, cache, vars)

View File

@ -84,7 +84,8 @@ module Rscons
@dirty = false @dirty = false
end end
# Check if target(s) are up to date # Check if target(s) are up to date.
#
# @param targets [String, Array] The name(s) of the target file(s). # @param targets [String, Array] The name(s) of the target file(s).
# @param command [String, Array] The command used to build the target. # @param command [String, Array] The command used to build the target.
# @param deps [Array] List of the target's dependency files. # @param deps [Array] List of the target's dependency files.
@ -93,6 +94,7 @@ module Rscons
# @option options [Boolean] :strict_deps # @option options [Boolean] :strict_deps
# Only consider a target up to date if its list of dependencies is # Only consider a target up to date if its list of dependencies is
# exactly equal (including order) to the cached list of dependencies # exactly equal (including order) to the cached list of dependencies
#
# @return [Boolean] # @return [Boolean]
# True value if the targets are all up to date, meaning that, # True value if the targets are all up to date, meaning that,
# for each target: # for each target:
@ -144,11 +146,14 @@ module Rscons
true true
end end
# Store cache information about target(s) built by a builder # Store cache information about target(s) built by a builder.
#
# @param targets [String, Array] The name of the target(s) built. # @param targets [String, Array] The name of the target(s) built.
# @param command [String, Array] The command used to build the target. # @param command [String, Array] The command used to build the target.
# @param deps [Array] List of dependencies for the target. # @param deps [Array] List of dependencies for the target.
# @param env [Environment] The {Rscons::Environment}. # @param env [Environment] The {Rscons::Environment}.
#
# @return [void]
def register_build(targets, command, deps, env) def register_build(targets, command, deps, env)
Array(targets).each do |target| Array(targets).each do |target|
@cache["targets"][target] = { @cache["targets"][target] = {
@ -171,13 +176,19 @@ module Rscons
end end
end end
# Return a list of targets that have been built # Return a list of targets that have been built.
#
# @return [Array<String>] List of targets that have been built.
def targets def targets
@cache["targets"].keys @cache["targets"].keys
end end
# Make any needed directories and record the ones that are created for # Make any needed directories and record the ones that are created for
# removal upon a "clean" operation. # removal upon a "clean" operation.
#
# @param path [String] Directory to create.
#
# @return [void]
def mkdir_p(path) def mkdir_p(path)
parts = path.split(/[\\\/]/) parts = path.split(/[\\\/]/)
parts.each_index do |i| parts.each_index do |i|
@ -191,7 +202,10 @@ module Rscons
end end
end end
# Return a list of directories which were created as a part of the build # Return a list of directories which were created as a part of the build.
#
# @return [Array<String>]
# List of directories which were created as a part of the build.
def directories def directories
@cache["directories"].keys @cache["directories"].keys
end end
@ -213,14 +227,20 @@ module Rscons
end end
# Return a file's checksum, or the previously calculated checksum for # Return a file's checksum, or the previously calculated checksum for
# the same file # the same file.
#
# @param file [String] The file name. # @param file [String] The file name.
#
# @return [String] The file's checksum.
def lookup_checksum(file) def lookup_checksum(file)
@lookup_checksums[file] || calculate_checksum(file) @lookup_checksums[file] || calculate_checksum(file)
end end
# Calculate and return a file's checksum # Calculate and return a file's checksum.
#
# @param file [String] The file name. # @param file [String] The file name.
#
# @return [String] The file's checksum.
def calculate_checksum(file) def calculate_checksum(file)
@lookup_checksums[file] = Digest::MD5.hexdigest(File.read(file, mode: "rb")) rescue "" @lookup_checksums[file] = Digest::MD5.hexdigest(File.read(file, mode: "rb")) rescue ""
end end

View File

@ -7,25 +7,33 @@ module Rscons
# contains a collection of construction variables, options, builders, and # contains a collection of construction variables, options, builders, and
# rules for building targets. # rules for building targets.
class Environment class Environment
# Hash of +{"builder_name" => builder_object}+ pairs. # @return [Hash] Set of \{"builder_name" => builder_object} pairs.
attr_reader :builders attr_reader :builders
# :command, :short, or :off # :command, :short, or :off
attr_accessor :echo attr_accessor :echo
# String or +nil+ # @return [String, nil] The build root.
attr_reader :build_root attr_reader :build_root
# Set the build root.
#
# @param build_root [String] The build root.
def build_root=(build_root) def build_root=(build_root)
@build_root = build_root @build_root = build_root
@build_root.gsub!('\\', '/') if @build_root @build_root.gsub!('\\', '/') if @build_root
end end
# Create an Environment object. # Create an Environment object.
#
# @param options [Hash] # @param options [Hash]
# Possible options keys: # @option options [Symbol] :echo
# :echo => :command, :short, or :off (default :short) # :command, :short, or :off (default :short)
# :build_root => String specifying build root directory (default nil) # @option options [String] :build_root
# :exclude_builders => true to omit adding default builders (default false) # Build root directory (default nil)
# @option options [Boolean] :exclude_builders
# Whether to omit adding default builders (default false)
#
# If a block is given, the Environment object is yielded to the block and # If a block is given, the Environment object is yielded to the block and
# when the block returns, the {#process} method is automatically called. # when the block returns, the {#process} method is automatically called.
def initialize(options = {}) def initialize(options = {})
@ -108,6 +116,10 @@ module Rscons
end end
# Add a {Builder} object to the Environment. # Add a {Builder} object to the Environment.
#
# @param builder [Builder] The {Builder} object to add.
#
# @return [void]
def add_builder(builder) def add_builder(builder)
@builders[builder.name] = builder @builders[builder.name] = builder
var_defs = builder.default_variables(self) var_defs = builder.default_variables(self)
@ -119,19 +131,45 @@ module Rscons
end end
# Add a build hook to the Environment. # Add a build hook to the Environment.
#
# @yield [build_op]
# Invoke the given block with the current build operation.
# @yieldparam build_op [Hash]
# Hash with keys:
# - :builder - The builder object in use.
# - :target - Target file name.
# - :sources - List of source file(s).
# - :vars - Set of construction variable values in use.
# - :env - The Environment invoking the builder.
#
# @return [void]
def add_build_hook(&block) def add_build_hook(&block)
@build_hooks << block @build_hooks << block
end end
# Specify a build directory for this Environment. # Specify a build directory for this Environment.
#
# Source files from src_dir will produce object files under obj_dir. # Source files from src_dir will produce object files under obj_dir.
#
# @param src_dir [String] Path to the source directory.
# @param obj_dir [String] Path to the object directory.
#
# @return [void]
def build_dir(src_dir, obj_dir) def build_dir(src_dir, obj_dir)
src_dir = src_dir.gsub('\\', '/') if src_dir.is_a?(String) src_dir = src_dir.gsub('\\', '/') if src_dir.is_a?(String)
@build_dirs << [src_dir, obj_dir] @build_dirs << [src_dir, obj_dir]
end end
# Return the file name to be built from source_fname with suffix suffix. # Return the file name to be built from +source_fname+ with suffix
# +suffix+.
#
# This method takes into account the Environment's build directories. # This method takes into account the Environment's build directories.
#
# @param source_fname [String] Source file name.
# @param suffix [String] Suffix, including "." if desired.
#
# @return [String]
# The file name to be built from +source_fname+ with suffix +suffix+.
def get_build_fname(source_fname, suffix) def get_build_fname(source_fname, suffix)
build_fname = Rscons.set_suffix(source_fname, suffix).gsub('\\', '/') build_fname = Rscons.set_suffix(source_fname, suffix).gsub('\\', '/')
found_match = @build_dirs.find do |src_dir, obj_dir| found_match = @build_dirs.find do |src_dir, obj_dir|
@ -151,26 +189,32 @@ module Rscons
end end
# Access a construction variable or environment option. # Access a construction variable or environment option.
#
# @see VarSet#[] # @see VarSet#[]
def [](*args) def [](*args)
@varset.send(:[], *args) @varset.send(:[], *args)
end end
# Set a construction variable or environment option. # Set a construction variable or environment option.
#
# @see VarSet#[]= # @see VarSet#[]=
def []=(*args) def []=(*args)
@varset.send(:[]=, *args) @varset.send(:[]=, *args)
end end
# Add a set of construction variables or environment options. # Add a set of construction variables or environment options.
#
# @see VarSet#append # @see VarSet#append
def append(*args) def append(*args)
@varset.append(*args) @varset.append(*args)
end end
# Build all target specified in the Environment. # Build all build targets specified in the Environment.
#
# When a block is passed to Environment.new, this method is automatically # When a block is passed to Environment.new, this method is automatically
# called after the block returns. # called after the block returns.
#
# @return [void]
def process def process
unless @targets.empty? unless @targets.empty?
expand_paths! expand_paths!
@ -227,13 +271,16 @@ module Rscons
end end
alias_method :build_command, :expand_varref alias_method :build_command, :expand_varref
# Execute a builder command # 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 # mode is set to :short
# @param command [Array] The command to execute. # @param command [Array] The command to execute.
# @param options [Hash] Optional options, possible keys: # @param options [Hash] Optional options, possible keys:
# - :env - environment Hash to pass to Kernel#system. # - :env - environment Hash to pass to Kernel#system.
# - :options - options Hash to pass to Kernel#system. # - :options - options Hash to pass to Kernel#system.
#
# @return [true,false,nil] Return value from Kernel.system().
def execute(short_desc, command, options = {}) def execute(short_desc, command, options = {})
print_command = proc do print_command = proc do
puts command.map { |c| c =~ /\s/ ? "'#{c}'" : c }.join(' ') puts command.map { |c| c =~ /\s/ ? "'#{c}'" : c }.join(' ')
@ -253,6 +300,14 @@ module Rscons
end end
end end
# Define a build target.
#
# @param method [Symbol] Method name.
# @param args [Array] Method arguments.
#
# @return [BuildTarget]
# The {BuildTarget} object registered, if the method called is a
# {Builder}.
def method_missing(method, *args) def method_missing(method, *args)
if @builders.has_key?(method.to_s) if @builders.has_key?(method.to_s)
target, sources, vars, *rest = args target, sources, vars, *rest = args
@ -269,6 +324,15 @@ module Rscons
end end
end end
# Add a build target.
#
# @param target [String] Build target file name.
# @param builder [Builder] The {Builder} to use to build the target.
# @param sources [Array<String>] Source file name(s).
# @param vars [Hash] Construction variable overrides.
# @param args [Object] Any extra arguments passed to the {Builder}.
#
# @return [void]
def add_target(target, builder, sources, vars, args) def add_target(target, builder, sources, vars, args)
@targets[target] = { @targets[target] = {
builder: builder, builder: builder,
@ -290,20 +354,28 @@ module Rscons
@user_deps[target] = (@user_deps[target] + user_deps).uniq @user_deps[target] = (@user_deps[target] + user_deps).uniq
end end
# Return the list of user dependencies for a given target, or +nil+ for # Return the list of user dependencies for a given target.
# none. #
# @param target [String] Target file name.
#
# @return [Array<String>,nil]
# List of user-specified dependencies for the target, or nil if none were
# specified.
def get_user_deps(target) def get_user_deps(target)
@user_deps[target] @user_deps[target]
end end
# Build a list of source files into files containing one of the suffixes # Build a list of source files into files containing one of the suffixes
# given by suffixes. # given by suffixes.
#
# This method is used internally by Rscons builders. # This method is used internally by Rscons builders.
#
# @param sources [Array] List of source files to build. # @param sources [Array] List of source files to build.
# @param suffixes [Array] List of suffixes to try to convert source files into. # @param suffixes [Array] List of suffixes to try to convert source files into.
# @param cache [Cache] The Cache. # @param cache [Cache] The Cache.
# @param vars [Hash] Extra variables to pass to the builder. # @param vars [Hash] Extra variables to pass to the builder.
# Return a list of the converted file names. #
# @return [Array<String>] List of the converted file name(s).
def build_sources(sources, suffixes, cache, vars) def build_sources(sources, suffixes, cache, vars)
sources.map do |source| sources.map do |source|
if source.end_with?(*suffixes) if source.end_with?(*suffixes)
@ -325,12 +397,14 @@ module Rscons
end end
# Invoke a builder to build the given target based on the given sources. # Invoke a builder to build the given target based on the given sources.
#
# @param builder [Builder] The Builder to use. # @param builder [Builder] The Builder to use.
# @param target [String] The target output file. # @param target [String] The target output file.
# @param sources [Array] List of source files. # @param sources [Array] List of source files.
# @param cache [Cache] The Cache. # @param cache [Cache] The Cache.
# @param vars [Hash] Extra variables to pass to the builder. # @param vars [Hash] Extra variables to pass to the builder.
# Return the result of the builder's run() method. #
# @return [String,false] Return value from the {Builder}'s +run+ method.
def run_builder(builder, target, sources, cache, vars) def run_builder(builder, target, sources, cache, vars)
vars = @varset.merge(vars) vars = @varset.merge(vars)
@build_hooks.each do |build_hook_block| @build_hooks.each do |build_hook_block|
@ -516,6 +590,8 @@ module Rscons
# This method expand construction variable references in the target and # This method expand construction variable references in the target and
# source file names before passing them to the builder. It also expands # source file names before passing them to the builder. It also expands
# "^/" prefixes to the Environment's build root if a build root is defined. # "^/" prefixes to the Environment's build root if a build root is defined.
#
# @return [void]
def expand_paths! def expand_paths!
@targets = @targets.reduce({}) do |result, (target, target_params)| @targets = @targets.reduce({}) do |result, (target, target_params)|
sources = target_params[:sources].map do |source| sources = target_params[:sources].map do |source|
@ -530,9 +606,13 @@ module Rscons
end end
# Parse dependencies for a given target from a Makefile. # Parse dependencies for a given target from a Makefile.
#
# This method is used internally by Rscons builders. # This method is used internally by Rscons builders.
#
# @param mf_fname [String] File name of the Makefile to read. # @param mf_fname [String] File name of the Makefile to read.
# @param target [String] Name of the target to gather dependencies for. # @param target [String] Name of the target to gather dependencies for.
#
# @return [Array<String>] Paths of dependency files.
def self.parse_makefile_deps(mf_fname, target) def self.parse_makefile_deps(mf_fname, target)
deps = [] deps = []
buildup = '' buildup = ''

View File

@ -1,9 +1,9 @@
module Rscons module Rscons
# This class represents a collection of variables which can be accessed # This class represents a collection of variables which supports efficient
# as certain types. # deep cloning.
# Only nil, strings, arrays, and hashes should be stored in a VarSet.
class VarSet class VarSet
# Create a VarSet. # Create a VarSet.
#
# @param vars [Hash] Optional initial variables. # @param vars [Hash] Optional initial variables.
def initialize(vars = {}) def initialize(vars = {})
@my_vars = {} @my_vars = {}
@ -11,8 +11,10 @@ module Rscons
append(vars) append(vars)
end end
# Access the value of variable as a particular type # Access the value of variable.
#
# @param key [String, Symbol] The variable name. # @param key [String, Symbol] The variable name.
#
# @return [Object] The variable's value. # @return [Object] The variable's value.
def [](key) def [](key)
if @my_vars.include?(key) if @my_vars.include?(key)
@ -29,15 +31,19 @@ module Rscons
end end
# Assign a value to a variable. # Assign a value to a variable.
#
# @param key [String, Symbol] The variable name. # @param key [String, Symbol] The variable name.
#
# @param val [Object] The value to set. # @param val [Object] The value to set.
def []=(key, val) def []=(key, val)
@my_vars[key] = val @my_vars[key] = val
end end
# Check if the VarSet contains a variable. # Check if the VarSet contains a variable.
#
# @param key [String, Symbol] The variable name. # @param key [String, Symbol] The variable name.
# @return [true, false] Whether the VarSet contains a variable. #
# @return [Boolean] Whether the VarSet contains the variable.
def include?(key) def include?(key)
if @my_vars.include?(key) if @my_vars.include?(key)
true true
@ -48,8 +54,11 @@ module Rscons
end end
end end
# Add or overwrite a set of variables # Add or overwrite a set of variables.
#
# @param values [VarSet, Hash] New set of variables. # @param values [VarSet, Hash] New set of variables.
#
# @return [self]
def append(values) def append(values)
coa! coa!
if values.is_a?(VarSet) if values.is_a?(VarSet)
@ -62,7 +71,10 @@ module Rscons
end end
# Create a new VarSet object based on the first merged with other. # Create a new VarSet object based on the first merged with other.
#
# @param other [VarSet, Hash] Other variables to add or overwrite. # @param other [VarSet, Hash] Other variables to add or overwrite.
#
# @return [VarSet] The newly created VarSet.
def merge(other = {}) def merge(other = {})
coa! coa!
varset = self.class.new varset = self.class.new
@ -71,9 +83,13 @@ module Rscons
end end
alias_method :clone, :merge alias_method :clone, :merge
# Replace "$" variable references in varref with the variables values, # Replace "$\{var}" variable references in varref with the expanded
# recursively. # variables' values, recursively.
#
# @param varref [String, Array] Value containing references to variables. # @param varref [String, Array] Value containing references to variables.
#
# @return [String, Array]
# Expanded value with "$\{var}" variable references replaced.
def expand_varref(varref) def expand_varref(varref)
if varref.is_a?(Array) if varref.is_a?(Array)
varref.map do |ent| varref.map do |ent|
@ -99,6 +115,8 @@ module Rscons
private private
# Move all VarSet variables into the copy-on-access list. # Move all VarSet variables into the copy-on-access list.
#
# @return [void]
def coa! def coa!
unless @my_vars.empty? unless @my_vars.empty?
@coa_vars.unshift(@my_vars) @coa_vars.unshift(@my_vars)
@ -107,8 +125,13 @@ module Rscons
end end
# Create a deep copy of an object. # Create a deep copy of an object.
# @param obj [nil, String, Array, Hash] Object to deep copy. #
# @return [nil, String, Array, Hash] Deep copied value. # Only objects which are of type String, Array, or Hash are deep copied.
# Any other object just has its referenced copied.
#
# @param obj [Object] Object to deep copy.
#
# @return [Object] Deep copied value.
def deep_dup(obj) def deep_dup(obj)
obj_class = obj.class obj_class = obj.class
if obj_class == Hash if obj_class == Hash