add/update YARD documentation
This commit is contained in:
parent
c0a69a5055
commit
8d4be1b51a
@ -11,6 +11,7 @@ require "rscons/monkey/string"
|
||||
require "rscons/builders/object"
|
||||
require "rscons/builders/program"
|
||||
|
||||
# Namespace module for rscons classes
|
||||
module Rscons
|
||||
DEFAULT_BUILDERS = [
|
||||
Object,
|
||||
|
@ -1,8 +1,18 @@
|
||||
module Rscons
|
||||
# Class to hold an object that knows how to build a certain type of file.
|
||||
class Builder
|
||||
# Return a set of default variable values for the Environment to use
|
||||
# unless the user overrides any.
|
||||
# @param env [Environment] The Environment.
|
||||
def default_variables(env)
|
||||
{}
|
||||
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.
|
||||
def produces?(target, source, env)
|
||||
false
|
||||
end
|
||||
|
@ -1,4 +1,6 @@
|
||||
module Rscons
|
||||
# A default RScons builder which knows how to produce an object file from
|
||||
# various types of source files.
|
||||
class Object < Builder
|
||||
def default_variables(env)
|
||||
{
|
||||
|
@ -1,4 +1,6 @@
|
||||
module Rscons
|
||||
# A default RScons builder that knows how to link object files into an
|
||||
# executable program.
|
||||
class Program < Builder
|
||||
def default_variables(env)
|
||||
{
|
||||
|
@ -5,46 +5,55 @@ require 'set'
|
||||
require 'rscons/version'
|
||||
|
||||
module Rscons
|
||||
# The Cache class keeps track of file checksums, build target commands and
|
||||
# dependencies in a YAML file which persists from one invocation to the next.
|
||||
# Example cache:
|
||||
# {
|
||||
# version: '1.2.3',
|
||||
# targets: {
|
||||
# 'program' => {
|
||||
# 'checksum' => 'A1B2C3D4',
|
||||
# 'command' => ['gcc', '-o', 'program', 'program.o'],
|
||||
# 'deps' => [
|
||||
# {
|
||||
# 'fname' => 'program.o',
|
||||
# 'checksum' => '87654321',
|
||||
# }
|
||||
# ],
|
||||
# }
|
||||
# 'program.o' => {
|
||||
# 'checksum' => '87654321',
|
||||
# 'command' => ['gcc', '-c', '-o', 'program.o', 'program.c'],
|
||||
# 'deps' => [
|
||||
# {
|
||||
# 'fname' => 'program.c',
|
||||
# 'checksum' => '456789ABC',
|
||||
# },
|
||||
# {
|
||||
# 'fname' => 'program.h',
|
||||
# 'checksum' => '7979764643',
|
||||
# }
|
||||
# ]
|
||||
# {
|
||||
# version: '1.2.3',
|
||||
# targets: {
|
||||
# 'program' => {
|
||||
# 'checksum' => 'A1B2C3D4',
|
||||
# 'command' => ['gcc', '-o', 'program', 'program.o'],
|
||||
# 'deps' => [
|
||||
# {
|
||||
# 'fname' => 'program.o',
|
||||
# 'checksum' => '87654321',
|
||||
# }
|
||||
# ],
|
||||
# }
|
||||
# 'program.o' => {
|
||||
# 'checksum' => '87654321',
|
||||
# 'command' => ['gcc', '-c', '-o', 'program.o', 'program.c'],
|
||||
# 'deps' => [
|
||||
# {
|
||||
# 'fname' => 'program.c',
|
||||
# 'checksum' => '456789ABC',
|
||||
# },
|
||||
# {
|
||||
# 'fname' => 'program.h',
|
||||
# 'checksum' => '7979764643',
|
||||
# }
|
||||
# ]
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
class Cache
|
||||
# Constants
|
||||
#### Constants
|
||||
|
||||
# Name of the file to store cache information in
|
||||
CACHE_FILE = '.rsconscache'
|
||||
|
||||
# Class Methods
|
||||
#### Class Methods
|
||||
|
||||
# Remove the cache file
|
||||
def self.clear
|
||||
FileUtils.rm_f(CACHE_FILE)
|
||||
end
|
||||
|
||||
# Instance Methods
|
||||
#### Instance Methods
|
||||
|
||||
# Create a Cache object and load in the previous contents from the cache
|
||||
# file.
|
||||
def initialize
|
||||
@cache = YAML.load(File.read(CACHE_FILE)) rescue {
|
||||
targets: {},
|
||||
@ -53,12 +62,30 @@ module Rscons
|
||||
@lookup_checksums = {}
|
||||
end
|
||||
|
||||
# Write the cache to disk to be loaded next time.
|
||||
def write
|
||||
File.open(CACHE_FILE, 'w') do |fh|
|
||||
fh.puts(YAML.dump(@cache))
|
||||
end
|
||||
end
|
||||
|
||||
# Check if a target is up to date
|
||||
# @param target [String] The name of the target file.
|
||||
# @param command [Array] The command used to build the target.
|
||||
# @param deps [Array] List of the target's dependency files.
|
||||
# @param options [Hash] Optional options. Can contain the following keys:
|
||||
# :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 true value if the target is up to date, meaning that:
|
||||
# - the target exists on disk
|
||||
# - the cache has information for the target
|
||||
# - 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
|
||||
def up_to_date?(target, command, deps, options = {})
|
||||
# target file must exist on disk
|
||||
return false unless File.exists?(target)
|
||||
@ -84,6 +111,10 @@ module Rscons
|
||||
end.all?
|
||||
end
|
||||
|
||||
# Store cache information about a target built by a builder
|
||||
# @param target [String] The name of the target.
|
||||
# @param command [Array] The command used to build the target.
|
||||
# @param deps [Array] List of dependencies for the target.
|
||||
def register_build(target, command, deps)
|
||||
@cache[:targets][target] = {
|
||||
command: command,
|
||||
@ -100,10 +131,15 @@ module Rscons
|
||||
# Private Instance Methods
|
||||
private
|
||||
|
||||
# Return a file's checksum, or the previously calculated checksum for
|
||||
# the same file
|
||||
# @param file [String] The file name.
|
||||
def lookup_checksum(file)
|
||||
@lookup_checksums[file] || calculate_checksum(file)
|
||||
end
|
||||
|
||||
# Calculate and return a file's checksum
|
||||
# @param file [String] The file name.
|
||||
def calculate_checksum(file)
|
||||
@lookup_checksums[file] = Digest::MD5.hexdigest(File.read(file)).encode(__ENCODING__) rescue ''
|
||||
end
|
||||
|
@ -2,14 +2,17 @@ require 'set'
|
||||
require 'fileutils'
|
||||
|
||||
module Rscons
|
||||
# The Environment class is the main programmatic interface to RScons. It
|
||||
# contains a collection of construction variables, options, builders, and
|
||||
# rules for building targets.
|
||||
class Environment
|
||||
# [Array] of {Builder} objects.
|
||||
attr_reader :builders
|
||||
|
||||
# Initialize a newly constructed Environment object
|
||||
# === Arguments
|
||||
# +variables+ _Hash_ ::
|
||||
# the variables hash can contain both construction variables, which are
|
||||
# uppercase strings (such as "CC" or "LDFLAGS"), and rscons options,
|
||||
# Create an Environment object.
|
||||
# @param variables [Hash]
|
||||
# The variables hash can contain both construction variables, which are
|
||||
# uppercase strings (such as "CC" or "LDFLAGS"), and RScons options,
|
||||
# which are lowercase symbols (such as :echo).
|
||||
def initialize(variables = {})
|
||||
@varset = VarSet.new(variables)
|
||||
@ -36,6 +39,10 @@ module Rscons
|
||||
end
|
||||
end
|
||||
|
||||
# Make a copy of the Environment object.
|
||||
# The cloned environment will contain a copy of all environment options,
|
||||
# construction variables, builders, and build directories. It will not
|
||||
# contain a copy of the targets.
|
||||
def clone(variables = {})
|
||||
env = Environment.new()
|
||||
@builders.each do |builder_name, builder|
|
||||
@ -54,6 +61,7 @@ module Rscons
|
||||
env
|
||||
end
|
||||
|
||||
# Add a {Builder} object to the Environment.
|
||||
def add_builder(builder)
|
||||
@builders[builder.class.short_name] = builder
|
||||
var_defs = builder.default_variables(self)
|
||||
@ -64,10 +72,16 @@ module Rscons
|
||||
end
|
||||
end
|
||||
|
||||
# Specify a build directory for this Environment.
|
||||
# Source files from src_dir will produce object files under obj_dir.
|
||||
def build_dir(src_dir, obj_dir)
|
||||
@build_dirs[src_dir.gsub('\\', '/')] = obj_dir.gsub('\\', '/')
|
||||
end
|
||||
|
||||
# Return the file name to be built from source_fname with suffix suffix.
|
||||
# This method takes into account the Environment's build directories.
|
||||
# It also creates any parent directories needed to be able to open and
|
||||
# write to the output file.
|
||||
def get_build_fname(source_fname, suffix)
|
||||
build_fname = source_fname.set_suffix(suffix).gsub('\\', '/')
|
||||
@build_dirs.each do |src_dir, obj_dir|
|
||||
@ -77,26 +91,37 @@ module Rscons
|
||||
build_fname
|
||||
end
|
||||
|
||||
# Access a construction variable or environment option.
|
||||
# @see VarSet#[]
|
||||
def [](*args)
|
||||
@varset.send(:[], *args)
|
||||
end
|
||||
|
||||
# Set a construction variable or environment option.
|
||||
# @see VarSet#[]=
|
||||
def []=(*args)
|
||||
@varset.send(:[]=, *args)
|
||||
end
|
||||
|
||||
# Add a set of construction variables or environment options.
|
||||
# @see VarSet#append
|
||||
def append(*args)
|
||||
@varset.send(:append, *args)
|
||||
end
|
||||
|
||||
# Return a list of target file names
|
||||
def targets
|
||||
@targets.keys
|
||||
end
|
||||
|
||||
# Return a list of sources needed to build target target.
|
||||
def target_sources(target)
|
||||
@targets[target][:source] rescue nil
|
||||
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 = Set.new
|
||||
@ -123,10 +148,23 @@ module Rscons
|
||||
cache.write
|
||||
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
|
||||
# @param extra_vars [Hash, VarSet] extra variables to use in addition to
|
||||
# (or replace) the Environment's construction variables when building
|
||||
# the command
|
||||
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
|
||||
# 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(' ')
|
||||
@ -159,6 +197,10 @@ module Rscons
|
||||
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.
|
||||
# @param target [String] Name of the target to gather dependencies for.
|
||||
def parse_makefile_deps(mf_fname, target)
|
||||
deps = []
|
||||
buildup = ''
|
||||
|
@ -1,4 +1,6 @@
|
||||
# Standard Ruby Module class.
|
||||
class Module
|
||||
# @return the base module name (not the fully qualified name)
|
||||
def short_name
|
||||
name.split(':').last
|
||||
end
|
||||
|
@ -1,4 +1,8 @@
|
||||
# Standard Ruby String class.
|
||||
class String
|
||||
# Check if the given string ends with any of the supplied suffixes
|
||||
# @param suffix [String, Array] The suffix to look for.
|
||||
# @return a true value if the string ends with one of the suffixes given.
|
||||
def has_suffix?(suffix)
|
||||
if suffix
|
||||
suffix = [suffix] if suffix.is_a?(String)
|
||||
@ -6,6 +10,9 @@ class String
|
||||
end
|
||||
end
|
||||
|
||||
# Return a new string with the suffix (dot character and extension) changed
|
||||
# to the given suffix.
|
||||
# @param suffix [String] The new suffix.
|
||||
def set_suffix(suffix = '')
|
||||
sub(/\.[^.]*$/, suffix)
|
||||
end
|
||||
|
@ -1,11 +1,23 @@
|
||||
module Rscons
|
||||
# This class represents a collection of variables which can be accessed
|
||||
# as certain types
|
||||
class VarSet
|
||||
# The underlying hash
|
||||
attr_reader :vars
|
||||
|
||||
# Create a VarSet
|
||||
# @param vars [Hash] Optional initial variables.
|
||||
def initialize(vars = {})
|
||||
@vars = vars
|
||||
end
|
||||
|
||||
# Access the value of variable as a particular type
|
||||
# @param key [String, Symbol] The variable name.
|
||||
# @param type [Symbol, nil] Optional specification of the type desired.
|
||||
# If the variable is a String and type is :array, a 1-element array with
|
||||
# the variable value will be returned. If the variable is an Array and
|
||||
# type is :string, the first element from the variable value will be
|
||||
# returned.
|
||||
def [](key, type = nil)
|
||||
val = @vars[key]
|
||||
if type == :array and val.is_a?(String)
|
||||
@ -17,21 +29,31 @@ module Rscons
|
||||
end
|
||||
end
|
||||
|
||||
# Assign a value to a variable.
|
||||
# @param key [String, Symbol] The variable name.
|
||||
# @param val [Object] The value.
|
||||
def []=(key, val)
|
||||
@vars[key] = val
|
||||
end
|
||||
|
||||
# Add or overwrite a set of variables
|
||||
# @param values [VarSet, Hash] New set of variables.
|
||||
def append(values)
|
||||
values = values.vars if values.is_a?(VarSet)
|
||||
@vars.merge!(values)
|
||||
self
|
||||
end
|
||||
|
||||
# Create a new VarSet object based on the first merged with other.
|
||||
# @param other [VarSet, Hash] Other variables to add or overwrite.
|
||||
def merge(other = {})
|
||||
VarSet.new(Marshal.load(Marshal.dump(@vars))).append(other)
|
||||
end
|
||||
alias_method :clone, :merge
|
||||
|
||||
# Replace "$" variable references in varref with the variables values,
|
||||
# recursively.
|
||||
# @param varref [String, Array] Value containing references to variables.
|
||||
def expand_varref(varref)
|
||||
if varref.is_a?(Array)
|
||||
varref.map do |ent|
|
||||
|
@ -1,3 +1,4 @@
|
||||
module Rscons
|
||||
# gem version
|
||||
VERSION = "0.0.1"
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user