Rework builder features to be returned by Builder#features instead of taken into account by Builder#produces?
This commit is contained in:
parent
b7f609b7e8
commit
010607d3b0
@ -24,6 +24,14 @@ module Rscons
|
|||||||
{}
|
{}
|
||||||
end
|
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
|
||||||
|
|
||||||
# Create a BuildTarget object for this build target.
|
# Create a BuildTarget object for this build target.
|
||||||
#
|
#
|
||||||
# Builder sub-classes can override this method to manipulate parameters
|
# Builder sub-classes can override this method to manipulate parameters
|
||||||
@ -47,35 +55,17 @@ 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.
|
||||||
#
|
#
|
||||||
# @overload produces?(target, source, env)
|
# @param target [String]
|
||||||
#
|
# The target file name.
|
||||||
# @param target [String]
|
# @param source [String]
|
||||||
# The target file name.
|
# The source file name.
|
||||||
# @param source [String]
|
# @param env [Environment]
|
||||||
# The source file name.
|
# The Environment.
|
||||||
# @param env [Environment]
|
|
||||||
# The Environment.
|
|
||||||
#
|
|
||||||
# @overload produces?(options)
|
|
||||||
#
|
|
||||||
# @since 1.10.0
|
|
||||||
#
|
|
||||||
# @param options [Hash]
|
|
||||||
# Options.
|
|
||||||
# @option options [String] :target
|
|
||||||
# Target file name.
|
|
||||||
# @option options [String] :source
|
|
||||||
# Source file name.
|
|
||||||
# @option options [Environment] :env
|
|
||||||
# The Environment.
|
|
||||||
# @option options [Hash] :features
|
|
||||||
# Features that this builder must satisfy.
|
|
||||||
# See {Environment#register_builds}.
|
|
||||||
#
|
#
|
||||||
# @return [Boolean]
|
# @return [Boolean]
|
||||||
# Whether this builder object is capable of producing a given target
|
# 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.
|
||||||
def produces?(options)
|
def produces?(target, source, env)
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -62,16 +62,18 @@ 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 options [Hash]
|
# @param target [String]
|
||||||
# Options.
|
# The target file name.
|
||||||
|
# @param source [String]
|
||||||
|
# The source file name.
|
||||||
|
# @param env [Environment]
|
||||||
|
# The Environment.
|
||||||
#
|
#
|
||||||
# @return [Boolean]
|
# @return [Boolean]
|
||||||
# Whether this builder object is capable of producing a given target
|
# 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.
|
||||||
def produces?(options)
|
def produces?(target, source, env)
|
||||||
target, source, env, features = options.values_at(:target, :source, :env, :features)
|
target.end_with?(*env['OBJSUFFIX']) and
|
||||||
(not features[:shared]) and
|
|
||||||
target.end_with?(*env['OBJSUFFIX']) and
|
|
||||||
KNOWN_SUFFIXES.find do |compiler, suffix_var|
|
KNOWN_SUFFIXES.find do |compiler, suffix_var|
|
||||||
source.end_with?(*env[suffix_var])
|
source.end_with?(*env[suffix_var])
|
||||||
end
|
end
|
||||||
|
@ -21,6 +21,14 @@ module Rscons
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
# Create a BuildTarget object for this build target.
|
# Create a BuildTarget object for this build target.
|
||||||
#
|
#
|
||||||
# The build target filename is given a platform-dependent suffix if no
|
# The build target filename is given a platform-dependent suffix if no
|
||||||
@ -61,7 +69,7 @@ module Rscons
|
|||||||
suffixes = env.expand_varref(["${OBJSUFFIX}", "${LIBSUFFIX}"], vars)
|
suffixes = env.expand_varref(["${OBJSUFFIX}", "${LIBSUFFIX}"], vars)
|
||||||
# Register builders to build each source to an object file or library.
|
# Register builders to build each source to an object file or library.
|
||||||
env.register_builds(target, sources, suffixes, vars,
|
env.register_builds(target, sources, suffixes, vars,
|
||||||
features: {shared: true})
|
features: %w[shared])
|
||||||
end
|
end
|
||||||
|
|
||||||
# Run the builder to produce a build target.
|
# Run the builder to produce a build target.
|
||||||
|
@ -37,19 +37,29 @@ module Rscons
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# 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
|
# 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 options [Hash]
|
# @param target [String]
|
||||||
# Options.
|
# The target file name.
|
||||||
|
# @param source [String]
|
||||||
|
# The source file name.
|
||||||
|
# @param env [Environment]
|
||||||
|
# The Environment.
|
||||||
#
|
#
|
||||||
# @return [Boolean]
|
# @return [Boolean]
|
||||||
# Whether this builder object is capable of producing a given target
|
# 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.
|
||||||
def produces?(options)
|
def produces?(target, source, env)
|
||||||
target, source, env, features = options.values_at(:target, :source, :env, :features)
|
target.end_with?(*env['OBJSUFFIX']) and
|
||||||
features[:shared] and
|
|
||||||
target.end_with?(*env['OBJSUFFIX']) and
|
|
||||||
KNOWN_SUFFIXES.find do |compiler, suffix_var|
|
KNOWN_SUFFIXES.find do |compiler, suffix_var|
|
||||||
source.end_with?(*env[suffix_var])
|
source.end_with?(*env[suffix_var])
|
||||||
end
|
end
|
||||||
|
@ -236,15 +236,15 @@ module Rscons
|
|||||||
# Suffix, including "." if desired.
|
# Suffix, including "." if desired.
|
||||||
# @param options [Hash]
|
# @param options [Hash]
|
||||||
# Extra options.
|
# Extra options.
|
||||||
# @option options [Hash] :features
|
# @option options [Array<String>] :features
|
||||||
# Builder features to be used for this build. See {#register_builds}.
|
# Builder features to be used for this build. See {#register_builds}.
|
||||||
#
|
#
|
||||||
# @return [String]
|
# @return [String]
|
||||||
# The file name to be built from +source_fname+ with suffix +suffix+.
|
# The file name to be built from +source_fname+ with suffix +suffix+.
|
||||||
def get_build_fname(source_fname, suffix, options = {})
|
def get_build_fname(source_fname, suffix, options = {})
|
||||||
build_fname = Rscons.set_suffix(source_fname, suffix).gsub('\\', '/')
|
build_fname = Rscons.set_suffix(source_fname, suffix).gsub('\\', '/')
|
||||||
options[:features] ||= {}
|
options[:features] ||= []
|
||||||
extra_path = options[:features][:shared] ? "/_shared" : ""
|
extra_path = options[:features].include?("shared") ? "/_shared" : ""
|
||||||
found_match = @build_dirs.find do |src_dir, obj_dir|
|
found_match = @build_dirs.find do |src_dir, obj_dir|
|
||||||
if src_dir.is_a?(Regexp)
|
if src_dir.is_a?(Regexp)
|
||||||
build_fname.sub!(src_dir, "#{obj_dir}#{extra_path}")
|
build_fname.sub!(src_dir, "#{obj_dir}#{extra_path}")
|
||||||
@ -516,10 +516,7 @@ module Rscons
|
|||||||
converted = nil
|
converted = nil
|
||||||
suffixes.each do |suffix|
|
suffixes.each do |suffix|
|
||||||
converted_fname = get_build_fname(source, suffix)
|
converted_fname = get_build_fname(source, suffix)
|
||||||
builder = @builders.values.find do |builder|
|
if builder = find_builder_for(converted_fname, source, [])
|
||||||
builder_produces?(builder, target: converted_fname, source: source)
|
|
||||||
end
|
|
||||||
if builder
|
|
||||||
converted = run_builder(builder, converted_fname, [source], cache, vars)
|
converted = run_builder(builder, converted_fname, [source], cache, vars)
|
||||||
return nil unless converted
|
return nil unless converted
|
||||||
break
|
break
|
||||||
@ -548,13 +545,16 @@ module Rscons
|
|||||||
# Extra variables to pass to the builders.
|
# Extra variables to pass to the builders.
|
||||||
# @param options [Hash]
|
# @param options [Hash]
|
||||||
# Extra options.
|
# Extra options.
|
||||||
# @option options [Hash] :features
|
# @option options [Array<String>] :features
|
||||||
# Set of features the builder must provide.
|
# Set of features the builder must provide. Each feature can be proceeded
|
||||||
# * :shared - builder builds a shared object/library
|
# by a "-" character to indicate that the builder must /not/ provide the
|
||||||
|
# given feature.
|
||||||
|
# * shared - builder builds a shared object/library
|
||||||
#
|
#
|
||||||
# @return [Array<String>]
|
# @return [Array<String>]
|
||||||
# List of the output file name(s).
|
# List of the output file name(s).
|
||||||
def register_builds(target, sources, suffixes, vars, options = {})
|
def register_builds(target, sources, suffixes, vars, options = {})
|
||||||
|
options[:features] ||= []
|
||||||
@registered_build_dependencies[target] ||= Set.new
|
@registered_build_dependencies[target] ||= Set.new
|
||||||
sources.map do |source|
|
sources.map do |source|
|
||||||
if source.end_with?(*suffixes)
|
if source.end_with?(*suffixes)
|
||||||
@ -563,14 +563,7 @@ module Rscons
|
|||||||
output_fname = nil
|
output_fname = nil
|
||||||
suffixes.each do |suffix|
|
suffixes.each do |suffix|
|
||||||
attempt_output_fname = get_build_fname(source, suffix, features: options[:features])
|
attempt_output_fname = get_build_fname(source, suffix, features: options[:features])
|
||||||
builder = @builders.values.find do |builder|
|
if builder = find_builder_for(attempt_output_fname, source, options[:features])
|
||||||
builder_produces?(
|
|
||||||
builder,
|
|
||||||
target: attempt_output_fname,
|
|
||||||
source: source,
|
|
||||||
features: options[:features])
|
|
||||||
end
|
|
||||||
if builder
|
|
||||||
output_fname = attempt_output_fname
|
output_fname = attempt_output_fname
|
||||||
self.__send__(builder.name, output_fname, source, vars)
|
self.__send__(builder.name, output_fname, source, vars)
|
||||||
@registered_build_dependencies[target] << output_fname
|
@registered_build_dependencies[target] << output_fname
|
||||||
@ -955,31 +948,43 @@ module Rscons
|
|||||||
tc: tc))
|
tc: tc))
|
||||||
end
|
end
|
||||||
|
|
||||||
# Determine if a builder produces an output file of a given name with
|
# Find a builder that meets the requested features and produces a target
|
||||||
# requested features.
|
# of the requested name.
|
||||||
|
#
|
||||||
|
# @param target [String]
|
||||||
|
# Target file name.
|
||||||
|
# @param source [String]
|
||||||
|
# Source file name.
|
||||||
|
# @param features [Array<String>]
|
||||||
|
# See {#register_builds}.
|
||||||
|
#
|
||||||
|
# @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)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Determine if a builder meets the requested features.
|
||||||
#
|
#
|
||||||
# @param builder [Builder]
|
# @param builder [Builder]
|
||||||
# The builder.
|
# The builder.
|
||||||
# @param options [Hash]
|
# @param features [Array<String>]
|
||||||
# Options for {Builder#produces?}.
|
# See {#register_builds}.
|
||||||
# @option options [String] :target
|
|
||||||
# Target file name.
|
|
||||||
# @option options [String] :source
|
|
||||||
# Source file name.
|
|
||||||
# @option options [Hash] :features
|
|
||||||
# Builder features. See {#register_builds}.
|
|
||||||
#
|
#
|
||||||
# @return [Boolean]
|
# @return [Boolean]
|
||||||
# Whether the builder produces a file of the given name from the source
|
# Whether the builder meets the requested features.
|
||||||
# given with the features given.
|
def features_met?(builder, features)
|
||||||
def builder_produces?(builder, options)
|
builder_features = builder.features
|
||||||
if builder.method(:produces?).arity == 3
|
features.all? do |feature|
|
||||||
builder.produces?(options[:target], options[:source], self)
|
want_feature = true
|
||||||
else
|
if feature =~ /^-(.*)$/
|
||||||
options = options.dup
|
want_feature = false
|
||||||
options[:features] ||= {}
|
feature = $1
|
||||||
options[:env] = self
|
end
|
||||||
builder.produces?(options)
|
builder_has_feature = builder_features.include?(feature)
|
||||||
|
want_feature ? builder_has_feature : !builder_has_feature
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -334,6 +334,28 @@ module Rscons
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "#features_met?" do
|
||||||
|
it "returns true when the builder provides all requested features" do
|
||||||
|
builder = Struct.new(:features).new(%w[shared other])
|
||||||
|
expect(subject.__send__(:features_met?, builder, %w[shared])).to be_truthy
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns true when no features are requested" do
|
||||||
|
builder = Struct.new(:features).new([])
|
||||||
|
expect(subject.__send__(:features_met?, builder, [])).to be_truthy
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns false when a builder does not provide a requested feature" do
|
||||||
|
builder = Struct.new(:features).new(%w[shared other])
|
||||||
|
expect(subject.__send__(:features_met?, builder, %w[other2])).to be_falsey
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns false when a builder provides a feature that is not desired" do
|
||||||
|
builder = Struct.new(:features).new(%w[shared other])
|
||||||
|
expect(subject.__send__(:features_met?, builder, %w[-shared])).to be_falsey
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe ".parse_makefile_deps" do
|
describe ".parse_makefile_deps" do
|
||||||
it 'handles dependencies on one line' do
|
it 'handles dependencies on one line' do
|
||||||
expect(File).to receive(:read).with('makefile').and_return(<<EOS)
|
expect(File).to receive(:read).with('makefile').and_return(<<EOS)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user