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/object"
|
||||||
require "rscons/builders/program"
|
require "rscons/builders/program"
|
||||||
|
|
||||||
|
# Namespace module for rscons classes
|
||||||
module Rscons
|
module Rscons
|
||||||
DEFAULT_BUILDERS = [
|
DEFAULT_BUILDERS = [
|
||||||
Object,
|
Object,
|
||||||
|
@ -1,8 +1,18 @@
|
|||||||
module Rscons
|
module Rscons
|
||||||
|
# Class to hold an object that knows how to build a certain type of file.
|
||||||
class Builder
|
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)
|
def default_variables(env)
|
||||||
{}
|
{}
|
||||||
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.
|
||||||
def produces?(target, source, env)
|
def produces?(target, source, env)
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
module Rscons
|
module Rscons
|
||||||
|
# A default RScons builder which knows how to produce an object file from
|
||||||
|
# various types of source files.
|
||||||
class Object < Builder
|
class Object < Builder
|
||||||
def default_variables(env)
|
def default_variables(env)
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
module Rscons
|
module Rscons
|
||||||
|
# A default RScons builder that knows how to link object files into an
|
||||||
|
# executable program.
|
||||||
class Program < Builder
|
class Program < Builder
|
||||||
def default_variables(env)
|
def default_variables(env)
|
||||||
{
|
{
|
||||||
|
@ -5,46 +5,55 @@ require 'set'
|
|||||||
require 'rscons/version'
|
require 'rscons/version'
|
||||||
|
|
||||||
module Rscons
|
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:
|
# Example cache:
|
||||||
# {
|
# {
|
||||||
# version: '1.2.3',
|
# version: '1.2.3',
|
||||||
# targets: {
|
# targets: {
|
||||||
# 'program' => {
|
# 'program' => {
|
||||||
# 'checksum' => 'A1B2C3D4',
|
# 'checksum' => 'A1B2C3D4',
|
||||||
# 'command' => ['gcc', '-o', 'program', 'program.o'],
|
# 'command' => ['gcc', '-o', 'program', 'program.o'],
|
||||||
# 'deps' => [
|
# 'deps' => [
|
||||||
# {
|
# {
|
||||||
# 'fname' => 'program.o',
|
# 'fname' => 'program.o',
|
||||||
# 'checksum' => '87654321',
|
# 'checksum' => '87654321',
|
||||||
# }
|
# }
|
||||||
# ],
|
# ],
|
||||||
# }
|
# }
|
||||||
# 'program.o' => {
|
# 'program.o' => {
|
||||||
# 'checksum' => '87654321',
|
# 'checksum' => '87654321',
|
||||||
# 'command' => ['gcc', '-c', '-o', 'program.o', 'program.c'],
|
# 'command' => ['gcc', '-c', '-o', 'program.o', 'program.c'],
|
||||||
# 'deps' => [
|
# 'deps' => [
|
||||||
# {
|
# {
|
||||||
# 'fname' => 'program.c',
|
# 'fname' => 'program.c',
|
||||||
# 'checksum' => '456789ABC',
|
# 'checksum' => '456789ABC',
|
||||||
# },
|
# },
|
||||||
# {
|
# {
|
||||||
# 'fname' => 'program.h',
|
# 'fname' => 'program.h',
|
||||||
# 'checksum' => '7979764643',
|
# 'checksum' => '7979764643',
|
||||||
# }
|
# }
|
||||||
# ]
|
# ]
|
||||||
|
# }
|
||||||
# }
|
# }
|
||||||
# }
|
# }
|
||||||
# }
|
|
||||||
class Cache
|
class Cache
|
||||||
# Constants
|
#### Constants
|
||||||
|
|
||||||
|
# Name of the file to store cache information in
|
||||||
CACHE_FILE = '.rsconscache'
|
CACHE_FILE = '.rsconscache'
|
||||||
|
|
||||||
# Class Methods
|
#### Class Methods
|
||||||
|
|
||||||
|
# Remove the cache file
|
||||||
def self.clear
|
def self.clear
|
||||||
FileUtils.rm_f(CACHE_FILE)
|
FileUtils.rm_f(CACHE_FILE)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Instance Methods
|
#### Instance Methods
|
||||||
|
|
||||||
|
# Create a Cache object and load in the previous contents from the cache
|
||||||
|
# file.
|
||||||
def initialize
|
def initialize
|
||||||
@cache = YAML.load(File.read(CACHE_FILE)) rescue {
|
@cache = YAML.load(File.read(CACHE_FILE)) rescue {
|
||||||
targets: {},
|
targets: {},
|
||||||
@ -53,12 +62,30 @@ module Rscons
|
|||||||
@lookup_checksums = {}
|
@lookup_checksums = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Write the cache to disk to be loaded next time.
|
||||||
def write
|
def write
|
||||||
File.open(CACHE_FILE, 'w') do |fh|
|
File.open(CACHE_FILE, 'w') do |fh|
|
||||||
fh.puts(YAML.dump(@cache))
|
fh.puts(YAML.dump(@cache))
|
||||||
end
|
end
|
||||||
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 = {})
|
def up_to_date?(target, command, deps, options = {})
|
||||||
# target file must exist on disk
|
# target file must exist on disk
|
||||||
return false unless File.exists?(target)
|
return false unless File.exists?(target)
|
||||||
@ -84,6 +111,10 @@ module Rscons
|
|||||||
end.all?
|
end.all?
|
||||||
end
|
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)
|
def register_build(target, command, deps)
|
||||||
@cache[:targets][target] = {
|
@cache[:targets][target] = {
|
||||||
command: command,
|
command: command,
|
||||||
@ -100,10 +131,15 @@ module Rscons
|
|||||||
# Private Instance Methods
|
# Private Instance Methods
|
||||||
private
|
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)
|
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
|
||||||
|
# @param file [String] The file name.
|
||||||
def calculate_checksum(file)
|
def calculate_checksum(file)
|
||||||
@lookup_checksums[file] = Digest::MD5.hexdigest(File.read(file)).encode(__ENCODING__) rescue ''
|
@lookup_checksums[file] = Digest::MD5.hexdigest(File.read(file)).encode(__ENCODING__) rescue ''
|
||||||
end
|
end
|
||||||
|
@ -2,14 +2,17 @@ require 'set'
|
|||||||
require 'fileutils'
|
require 'fileutils'
|
||||||
|
|
||||||
module Rscons
|
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
|
class Environment
|
||||||
|
# [Array] of {Builder} objects.
|
||||||
attr_reader :builders
|
attr_reader :builders
|
||||||
|
|
||||||
# Initialize a newly constructed Environment object
|
# Create an Environment object.
|
||||||
# === Arguments
|
# @param variables [Hash]
|
||||||
# +variables+ _Hash_ ::
|
# The variables hash can contain both construction variables, which are
|
||||||
# the variables hash can contain both construction variables, which are
|
# uppercase strings (such as "CC" or "LDFLAGS"), and RScons options,
|
||||||
# uppercase strings (such as "CC" or "LDFLAGS"), and rscons options,
|
|
||||||
# which are lowercase symbols (such as :echo).
|
# which are lowercase symbols (such as :echo).
|
||||||
def initialize(variables = {})
|
def initialize(variables = {})
|
||||||
@varset = VarSet.new(variables)
|
@varset = VarSet.new(variables)
|
||||||
@ -36,6 +39,10 @@ module Rscons
|
|||||||
end
|
end
|
||||||
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 = {})
|
def clone(variables = {})
|
||||||
env = Environment.new()
|
env = Environment.new()
|
||||||
@builders.each do |builder_name, builder|
|
@builders.each do |builder_name, builder|
|
||||||
@ -54,6 +61,7 @@ module Rscons
|
|||||||
env
|
env
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Add a {Builder} object to the Environment.
|
||||||
def add_builder(builder)
|
def add_builder(builder)
|
||||||
@builders[builder.class.short_name] = builder
|
@builders[builder.class.short_name] = builder
|
||||||
var_defs = builder.default_variables(self)
|
var_defs = builder.default_variables(self)
|
||||||
@ -64,10 +72,16 @@ module Rscons
|
|||||||
end
|
end
|
||||||
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)
|
def build_dir(src_dir, obj_dir)
|
||||||
@build_dirs[src_dir.gsub('\\', '/')] = obj_dir.gsub('\\', '/')
|
@build_dirs[src_dir.gsub('\\', '/')] = obj_dir.gsub('\\', '/')
|
||||||
end
|
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)
|
def get_build_fname(source_fname, suffix)
|
||||||
build_fname = source_fname.set_suffix(suffix).gsub('\\', '/')
|
build_fname = source_fname.set_suffix(suffix).gsub('\\', '/')
|
||||||
@build_dirs.each do |src_dir, obj_dir|
|
@build_dirs.each do |src_dir, obj_dir|
|
||||||
@ -77,26 +91,37 @@ module Rscons
|
|||||||
build_fname
|
build_fname
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Access a construction variable or environment option.
|
||||||
|
# @see VarSet#[]
|
||||||
def [](*args)
|
def [](*args)
|
||||||
@varset.send(:[], *args)
|
@varset.send(:[], *args)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Set a construction variable or environment option.
|
||||||
|
# @see VarSet#[]=
|
||||||
def []=(*args)
|
def []=(*args)
|
||||||
@varset.send(:[]=, *args)
|
@varset.send(:[]=, *args)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Add a set of construction variables or environment options.
|
||||||
|
# @see VarSet#append
|
||||||
def append(*args)
|
def append(*args)
|
||||||
@varset.send(:append, *args)
|
@varset.send(:append, *args)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Return a list of target file names
|
||||||
def targets
|
def targets
|
||||||
@targets.keys
|
@targets.keys
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Return a list of sources needed to build target target.
|
||||||
def target_sources(target)
|
def target_sources(target)
|
||||||
@targets[target][:source] rescue nil
|
@targets[target][:source] rescue nil
|
||||||
end
|
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
|
def process
|
||||||
cache = Cache.new
|
cache = Cache.new
|
||||||
targets_processed = Set.new
|
targets_processed = Set.new
|
||||||
@ -123,10 +148,23 @@ module Rscons
|
|||||||
cache.write
|
cache.write
|
||||||
end
|
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)
|
def build_command(command_template, extra_vars)
|
||||||
@varset.merge(extra_vars).expand_varref(command_template)
|
@varset.merge(extra_vars).expand_varref(command_template)
|
||||||
end
|
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 = {})
|
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(' ')
|
||||||
@ -159,6 +197,10 @@ module Rscons
|
|||||||
end
|
end
|
||||||
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)
|
def parse_makefile_deps(mf_fname, target)
|
||||||
deps = []
|
deps = []
|
||||||
buildup = ''
|
buildup = ''
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
|
# Standard Ruby Module class.
|
||||||
class Module
|
class Module
|
||||||
|
# @return the base module name (not the fully qualified name)
|
||||||
def short_name
|
def short_name
|
||||||
name.split(':').last
|
name.split(':').last
|
||||||
end
|
end
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
|
# Standard Ruby String class.
|
||||||
class String
|
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)
|
def has_suffix?(suffix)
|
||||||
if suffix
|
if suffix
|
||||||
suffix = [suffix] if suffix.is_a?(String)
|
suffix = [suffix] if suffix.is_a?(String)
|
||||||
@ -6,6 +10,9 @@ class String
|
|||||||
end
|
end
|
||||||
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 = '')
|
def set_suffix(suffix = '')
|
||||||
sub(/\.[^.]*$/, suffix)
|
sub(/\.[^.]*$/, suffix)
|
||||||
end
|
end
|
||||||
|
@ -1,11 +1,23 @@
|
|||||||
module Rscons
|
module Rscons
|
||||||
|
# This class represents a collection of variables which can be accessed
|
||||||
|
# as certain types
|
||||||
class VarSet
|
class VarSet
|
||||||
|
# The underlying hash
|
||||||
attr_reader :vars
|
attr_reader :vars
|
||||||
|
|
||||||
|
# Create a VarSet
|
||||||
|
# @param vars [Hash] Optional initial variables.
|
||||||
def initialize(vars = {})
|
def initialize(vars = {})
|
||||||
@vars = vars
|
@vars = vars
|
||||||
end
|
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)
|
def [](key, type = nil)
|
||||||
val = @vars[key]
|
val = @vars[key]
|
||||||
if type == :array and val.is_a?(String)
|
if type == :array and val.is_a?(String)
|
||||||
@ -17,21 +29,31 @@ module Rscons
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Assign a value to a variable.
|
||||||
|
# @param key [String, Symbol] The variable name.
|
||||||
|
# @param val [Object] The value.
|
||||||
def []=(key, val)
|
def []=(key, val)
|
||||||
@vars[key] = val
|
@vars[key] = val
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Add or overwrite a set of variables
|
||||||
|
# @param values [VarSet, Hash] New set of variables.
|
||||||
def append(values)
|
def append(values)
|
||||||
values = values.vars if values.is_a?(VarSet)
|
values = values.vars if values.is_a?(VarSet)
|
||||||
@vars.merge!(values)
|
@vars.merge!(values)
|
||||||
self
|
self
|
||||||
end
|
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 = {})
|
def merge(other = {})
|
||||||
VarSet.new(Marshal.load(Marshal.dump(@vars))).append(other)
|
VarSet.new(Marshal.load(Marshal.dump(@vars))).append(other)
|
||||||
end
|
end
|
||||||
alias_method :clone, :merge
|
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)
|
def expand_varref(varref)
|
||||||
if varref.is_a?(Array)
|
if varref.is_a?(Array)
|
||||||
varref.map do |ent|
|
varref.map do |ent|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
module Rscons
|
module Rscons
|
||||||
|
# gem version
|
||||||
VERSION = "0.0.1"
|
VERSION = "0.0.1"
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user