create Builder instance for each build operation - close #88
This commit is contained in:
1 parent
12f1909d35
commit
aac32d20b0
28 files changed
+181
-147
No files matched your search
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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))
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
@@ -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 =~ /^-(.*)$/
|
||||
|
||||
Reference in new issue
Block a user