create Builder instance for each build operation - close #88

This commit is contained in:
josh committed 2019-02-10 17:27:40 -05:00
1 parent 12f1909d35
commit aac32d20b0
28 files changed
+181 -147

No files matched your search

+1
View File
@@ -3,6 +3,7 @@ require_relative "rscons/application"
require_relative "rscons/basic_environment"
require_relative "rscons/build_target"
require_relative "rscons/builder"
require_relative "rscons/builder_builder"
require_relative "rscons/cache"
require_relative "rscons/configure_op"
require_relative "rscons/environment"
+37 -26
View File
@@ -6,21 +6,49 @@ module Rscons
# Class to hold an object that knows how to build a certain type of file.
class Builder
class << self
# Return the name of the builder.
#
# If not overridden this defaults to the last component of the class name.
#
# @return [String] The name of the builder.
def name
super.split(":").last
end
# Return a set of build features that this builder provides.
#
# @return [Array<String>]
# Set of build features that this builder provides.
def features
[]
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]
# The source file name.
# @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)
false
end
end
# Return the name of the builder.
#
# If not overridden this defaults to the last component of the class name.
#
# @return [String] The name of the builder.
def name
self.class.name.split(":").last
end
# Return a set of build features that this builder provides.
#
# @return [Array<String>]
# Set of build features that this builder provides.
def features
[]
self.class.name
end
# Create a BuildTarget object for this build target.
@@ -43,23 +71,6 @@ module Rscons
BuildTarget.new(options)
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]
# The source file name.
# @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)
false
end
# Set up a build operation using this builder.
#
# This method is called when a build target is registered using this
+33
View File
@@ -0,0 +1,33 @@
module Rscons
# A class that knows how to build an instance of another Builder class when
# it is needed.
class BuilderBuilder
# @return [String] Builder name.
attr_reader :name
# Create a BuilderBuilder.
#
# @param name [String]
# Builder name.
# @param builder_class [Class]
# The {Builder} class to be instantiated.
# @param builder_args [Array]
# Any extra arguments to be passed to the builder class.
# @param builder_block [Proc, nil]
# Optional block to be passed to the {Builder} class's #new method.
def initialize(name, builder_class, *builder_args, &builder_block)
@name = name
@builder_class = builder_class
@builder_args = builder_args
@builder_block = builder_block
end
# Act like a regular {Builder} class object but really instantiate the
# requested {Builder} class, potentially with extra arguments and a block.
def new(*args)
@builder_class.new(*args, *@builder_args, &@builder_block)
end
end
end
+1 -1
View File
@@ -43,7 +43,7 @@ module Rscons
# Check the cache and copy if necessary
unless cache.up_to_date?(dest, :Copy, [src], env)
unless printed_message
env.print_builder_run_message("#{name} #{target}", nil)
env.print_builder_run_message("#{self.class.name} #{target}", nil)
printed_message = true
end
cache.mkdir_p(File.dirname(dest))
+20 -18
View File
@@ -53,24 +53,26 @@ module Rscons
'DCCMD' => ['${DC}', '-c', '-o', '${_TARGET}', '${DDEPGEN}', '${INCPREFIX}${D_IMPORT_PATH}', '${DFLAGS}', '${_SOURCES}'],
)
# 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]
# The source file name.
# @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)
target.end_with?(*env['OBJSUFFIX']) and
KNOWN_SUFFIXES.find do |compiler, suffix_var|
source.end_with?(*env[suffix_var])
end
class << self
# 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]
# The source file name.
# @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)
target.end_with?(*env['OBJSUFFIX']) and
KNOWN_SUFFIXES.find do |compiler, suffix_var|
source.end_with?(*env[suffix_var])
end
end
end
# Run the builder to produce a build target.
+1 -1
View File
@@ -36,7 +36,7 @@ module Rscons
env.produces(target, vars['_DEPFILE'])
# Store vars back into options so new keys are accessible in #finalize.
options[:vars] = vars
standard_threaded_build("#{name} #{target}", target, command, sources, env, cache)
standard_threaded_build("#{self.class.name} #{target}", target, command, sources, env, cache)
end
# Finalize the build operation.
+8 -6
View File
@@ -14,12 +14,14 @@ module Rscons
'SHLDCMD' => ['${SHLD}', '-o', '${_TARGET}', '${SHLDFLAGS}', '${_SOURCES}', '${SHLIBDIRPREFIX}${LIBPATH}', '${SHLIBLINKPREFIX}${LIBS}']
)
# Return a set of build features that this builder provides.
#
# @return [Array<String>]
# Set of build features that this builder provides.
def features
%w[shared]
class << self
# Return a set of build features that this builder provides.
#
# @return [Array<String>]
# Set of build features that this builder provides.
def features
%w[shared]
end
end
# Create a BuildTarget object for this build target.
+27 -25
View File
@@ -30,32 +30,34 @@ module Rscons
'SHDCCMD' => ['${SHDC}', '-c', '-o', '${_TARGET}', '${INCPREFIX}${D_IMPORT_PATH}', '${SHDFLAGS}', '${_SOURCES}'],
)
# Return a set of build features that this builder provides.
#
# @return [Array<String>]
# Set of build features that this builder provides.
def features
%w[shared]
end
class << self
# Return a set of build features that this builder provides.
#
# @return [Array<String>]
# Set of build features that this builder provides.
def features
%w[shared]
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]
# The source file name.
# @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)
target.end_with?(*env['OBJSUFFIX']) and
KNOWN_SUFFIXES.find do |compiler, suffix_var|
source.end_with?(*env[suffix_var])
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]
# The source file name.
# @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)
target.end_with?(*env['OBJSUFFIX']) and
KNOWN_SUFFIXES.find do |compiler, suffix_var|
source.end_with?(*env[suffix_var])
end
end
end
# Run the builder to produce a build target.
+11 -24
View File
@@ -1,39 +1,26 @@
module Rscons
module Builders
# A Generic builder class whose name and operation is defined at
# instantiation.
# A Generic builder which has its operation is defined at instantiation.
#
# @since 1.8.0
class SimpleBuilder < Builder
# @return [String] The name of this builder.
attr_reader :name
# Create a new builder with the given name and action.
# Create a new builder with the given action.
#
# @param name [String,Symbol] The name of the builder when registered.
# @param block [Block]
# The action to perform when the builder is processed. The provided
# block must return the target file on success or false on failure.
# The provided block should have the same signature as {Builder#run}.
def initialize(name, &block)
@name = name.to_s
@block = block
# @param run_proc [Proc]
# A Proc to execute when the builder runs. The provided block must
# provide the have the same signature as {Builder#run}.
def initialize(&run_proc)
@run_proc = run_proc
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)
@block.call(target, sources, cache, env, vars)
# Method signature described by {Builder#run}.
def run(*args)
@run_proc.call(*args)
end
end
end
end
+17 -16
View File
@@ -72,13 +72,14 @@ module Rscons
@side_effects = {}
@job_set = JobSet.new(@registered_build_dependencies, @side_effects)
@user_deps = {}
# Hash of builder name (String) => builder class (Class).
@builders = {}
@build_hooks = {pre: [], post: []}
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)
add_builder(builder_class)
end
end
@echo =
@@ -146,22 +147,22 @@ module Rscons
env
end
# Add a {Builder} object to the Environment.
# Add a {Builder} to the Environment.
#
# @overload add_builder(builder)
# @overload add_builder(builder_class)
#
# Add the given builder to the Environment.
#
# @param builder [Builder] An instance of the builder to register.
# @param builder_class [Class] A builder class to register.
#
# @overload add_builder(builder,&action)
# @overload add_builder(name,&action)
#
# Create a new {Builders::SimpleBuilder} instance and add it to the
# environment.
#
# @since 1.8.0
#
# @param builder [String,Symbol]
# @param name [String,Symbol]
# The name of the builder to add.
#
# @param action [Block]
@@ -170,11 +171,11 @@ module Rscons
# {Rscons::Builder#run}.
#
# @return [void]
def add_builder(builder, &action)
if not builder.is_a? Rscons::Builder
builder = Rscons::Builders::SimpleBuilder.new(builder, &action)
def add_builder(builder_class, &action)
if builder_class.is_a?(String) or builder_class.is_a?(Symbol)
builder_class = BuilderBuilder.new(builder_class.to_s, Rscons::Builders::SimpleBuilder, &action)
end
@builders[builder.name] = builder
@builders[builder_class.name] = builder_class
end
# Add a build hook to the Environment.
@@ -351,7 +352,7 @@ module Rscons
unless vars.is_a?(Hash) or vars.is_a?(VarSet)
raise "Unexpected construction variable set: #{vars.inspect}"
end
builder = @builders[method.to_s]
builder = @builders[method.to_s].new
target = expand_path(expand_varref(target))
sources = Array(sources).map do |source|
expand_path(expand_varref(source))
@@ -789,22 +790,22 @@ module Rscons
# @return [Builder, nil]
# The builder found, if any.
def find_builder_for(target, source, features)
@builders.values.find do |builder|
features_met?(builder, features) and builder.produces?(target, source, self)
@builders.values.find do |builder_class|
features_met?(builder_class, features) and builder_class.produces?(target, source, self)
end
end
# Determine if a builder meets the requested features.
#
# @param builder [Builder]
# @param builder_class [Class]
# The builder.
# @param features [Array<String>]
# See {#register_builds}.
#
# @return [Boolean]
# Whether the builder meets the requested features.
def features_met?(builder, features)
builder_features = builder.features
def features_met?(builder_class, features)
builder_features = builder_class.features
features.all? do |feature|
want_feature = true
if feature =~ /^-(.*)$/