From 3ff09978f49a819d5e419f6027a4d2042287e7de Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Sat, 16 Mar 2019 21:54:20 -0400 Subject: [PATCH] remove Builder.features and Builder.produces? --- build_tests/library/library_from_object.rb | 7 ++ .../shared_library_from_object.rb | 7 ++ lib/rscons/builder.rb | 25 ----- lib/rscons/builders/library.rb | 9 +- lib/rscons/builders/object.rb | 22 ---- lib/rscons/builders/program.rb | 9 +- lib/rscons/builders/shared_library.rb | 20 ++-- lib/rscons/builders/shared_object.rb | 30 ------ lib/rscons/environment.rb | 102 ++++-------------- spec/build_tests_spec.rb | 15 +++ spec/rscons/environment_spec.rb | 22 ---- 11 files changed, 69 insertions(+), 199 deletions(-) create mode 100644 build_tests/library/library_from_object.rb create mode 100644 build_tests/shared_library/shared_library_from_object.rb diff --git a/build_tests/library/library_from_object.rb b/build_tests/library/library_from_object.rb new file mode 100644 index 0000000..367203d --- /dev/null +++ b/build_tests/library/library_from_object.rb @@ -0,0 +1,7 @@ +build do + Environment.new do |env| + env.Program("library.exe", ["lib.a", "three.c"]) + env.Object("two.o", "two.c") + env.Library("lib.a", ["one.c", "two.o"], 'CPPFLAGS' => ['-Dmake_lib']) + end +end diff --git a/build_tests/shared_library/shared_library_from_object.rb b/build_tests/shared_library/shared_library_from_object.rb new file mode 100644 index 0000000..1322b96 --- /dev/null +++ b/build_tests/shared_library/shared_library_from_object.rb @@ -0,0 +1,7 @@ +build do + Environment.new do |env| + env["CPPPATH"] << "src/lib" + env.SharedObject("one.o", "src/lib/one.c") + libmine = env.SharedLibrary("mine", ["one.o", "src/lib/two.c"]) + end +end diff --git a/lib/rscons/builder.rb b/lib/rscons/builder.rb index 7ea4ea1..b82f918 100644 --- a/lib/rscons/builder.rb +++ b/lib/rscons/builder.rb @@ -16,31 +16,6 @@ module Rscons def name super.split(":").last end - - # Return a set of build features that this builder provides. - # - # @return [Array] - # 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 [String, Symbol] diff --git a/lib/rscons/builders/library.rb b/lib/rscons/builders/library.rb index 4c3e350..57a15de 100644 --- a/lib/rscons/builders/library.rb +++ b/lib/rscons/builders/library.rb @@ -7,8 +7,13 @@ module Rscons def initialize(options) super(options) suffixes = @env.expand_varref(["${OBJSUFFIX}", "${LIBSUFFIX}"], @vars) - # Register builders to build each source to an object file or library. - @objects = @env.register_builds(@target, @sources, suffixes, @vars) + @objects = @sources.map do |source| + if source.end_with?(*suffixes) + source + else + @env.register_dependency_build(@target, source, suffixes.first, @vars, Object) + end + end end # Run the builder to produce a build target. diff --git a/lib/rscons/builders/object.rb b/lib/rscons/builders/object.rb index 971b343..4a41b69 100644 --- a/lib/rscons/builders/object.rb +++ b/lib/rscons/builders/object.rb @@ -12,28 +12,6 @@ module Rscons "DC" => "DSUFFIX", } - 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. def run(options) if @command diff --git a/lib/rscons/builders/program.rb b/lib/rscons/builders/program.rb index f977182..3d84434 100644 --- a/lib/rscons/builders/program.rb +++ b/lib/rscons/builders/program.rb @@ -22,8 +22,13 @@ module Rscons @target += @env.expand_varref("${PROGSUFFIX}", @vars) end suffixes = @env.expand_varref(["${OBJSUFFIX}", "${LIBSUFFIX}"], @vars) - # Register builders to build each source to an object file or library. - @objects = @env.register_builds(@target, @sources, suffixes, @vars) + @objects = @sources.map do |source| + if source.end_with?(*suffixes) + source + else + @env.register_dependency_build(@target, source, suffixes.first, @vars, Object) + end + end end # Run the builder to produce a build target. diff --git a/lib/rscons/builders/shared_library.rb b/lib/rscons/builders/shared_library.rb index a953568..5721b19 100644 --- a/lib/rscons/builders/shared_library.rb +++ b/lib/rscons/builders/shared_library.rb @@ -4,16 +4,6 @@ module Rscons # shared library. class SharedLibrary < Builder - class << self - # Return a set of build features that this builder provides. - # - # @return [Array] - # Set of build features that this builder provides. - def features - %w[shared] - end - end - # Create an instance of the Builder to build a target. def initialize(options) super(options) @@ -25,9 +15,13 @@ module Rscons @target += @env.expand_varref("${SHLIBSUFFIX}", @vars) end suffixes = @env.expand_varref(["${OBJSUFFIX}", "${LIBSUFFIX}"], @vars) - # Register builders to build each source to an object file or library. - @objects = @env.register_builds(@target, @sources, suffixes, @vars, - features: %w[shared]) + @objects = @sources.map do |source| + if source.end_with?(*suffixes) + source + else + @env.register_dependency_build(@target, source, suffixes.first, @vars, SharedObject) + end + end end # Run the builder to produce a build target. diff --git a/lib/rscons/builders/shared_object.rb b/lib/rscons/builders/shared_object.rb index 2129541..656efab 100644 --- a/lib/rscons/builders/shared_object.rb +++ b/lib/rscons/builders/shared_object.rb @@ -13,36 +13,6 @@ module Rscons "SHDC" => "DSUFFIX", } - class << self - # Return a set of build features that this builder provides. - # - # @return [Array] - # 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 - end - end - # Run the builder to produce a build target. def run(options) if @command diff --git a/lib/rscons/environment.rb b/lib/rscons/environment.rb index 6328a85..006852d 100644 --- a/lib/rscons/environment.rb +++ b/lib/rscons/environment.rb @@ -238,16 +238,13 @@ module Rscons # Source file name. # @param suffix [String] # Suffix, including "." if desired. - # @param options [Hash] - # Extra options. - # @option options [Array] :features - # Builder features to be used for this build. See {#register_builds}. + # @param builder_class [Class] + # The builder in use. # # @return [String] # The file name to be built from +source_fname+ with suffix +suffix+. - def get_build_fname(source_fname, suffix, options = {}) - options[:features] ||= [] - extra_path = options[:features].include?("shared") ? "/_shared" : "" + def get_build_fname(source_fname, suffix, builder_class) + extra_path = builder_class == Builders::SharedObject ? "/_shared" : "" "#{@build_root}#{extra_path}/#{Util.make_relative_path(Rscons.set_suffix(source_fname, suffix))}".gsub("\\", "/") end @@ -421,52 +418,31 @@ module Rscons @user_deps[target] end - # Find and register builders to build source files into files containing - # one of the suffixes given by suffixes. + # Register a builder to build a source file into an output with the given + # suffix. # # This method is used internally by Rscons builders. It can be called # from the builder's #initialize method. # - # @since 1.10.0 - # # @param target [String] # The target that depends on these builds. - # @param sources [Array] - # List of source file(s) to build. - # @param suffixes [Array] - # List of suffixes to try to convert source files into. + # @param source [String] + # Source file to build. + # @param suffix [String] + # Suffix to try to convert source files into. # @param vars [Hash] # Extra variables to pass to the builders. - # @param options [Hash] - # Extra options. - # @option options [Array] :features - # Set of features the builder must provide. Each feature can be proceeded - # by a "-" character to indicate that the builder must /not/ provide the - # given feature. - # * shared - builder builds a shared object/library + # @param builder_class [Class] + # The builder class to use. # - # @return [Array] - # List of the output file name(s). - def register_builds(target, sources, suffixes, vars, options = {}) - options[:features] ||= [] + # @return [String] + # Output file name. + def register_dependency_build(target, source, suffix, vars, builder_class) + output_fname = get_build_fname(source, suffix, builder_class) + self.__send__(builder_class.name, output_fname, source, vars) @registered_build_dependencies[target] ||= Set.new - sources.map do |source| - if source.end_with?(*suffixes) - source - else - output_fname = nil - suffixes.each do |suffix| - attempt_output_fname = get_build_fname(source, suffix, features: options[:features]) - if builder = find_builder_for(attempt_output_fname, source, options[:features]) - output_fname = attempt_output_fname - self.__send__(builder.name, output_fname, source, vars) - @registered_build_dependencies[target] << output_fname - break - end - end - output_fname or raise "Could not find a builder for #{source.inspect}." - end - end + @registered_build_dependencies[target] << output_fname + output_fname end # Expand a path to be relative to the Environment's build root. @@ -706,46 +682,6 @@ module Rscons end end - # Find a builder that meets the requested features and produces a target - # of the requested name. - # - # @param target [String] - # Target file name. - # @param source [String] - # Source file name. - # @param features [Array] - # See {#register_builds}. - # - # @return [Builder, nil] - # The builder found, if any. - def find_builder_for(target, source, features) - @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_class [Class] - # The builder. - # @param features [Array] - # See {#register_builds}. - # - # @return [Boolean] - # Whether the builder meets the requested features. - def features_met?(builder_class, features) - builder_features = builder_class.features - features.all? do |feature| - want_feature = true - if feature =~ /^-(.*)$/ - want_feature = false - feature = $1 - end - builder_has_feature = builder_features.include?(feature) - want_feature ? builder_has_feature : !builder_has_feature - end - end - end Environment.class_init diff --git a/spec/build_tests_spec.rb b/spec/build_tests_spec.rb index ed5184b..fc492c9 100644 --- a/spec/build_tests_spec.rb +++ b/spec/build_tests_spec.rb @@ -1410,6 +1410,14 @@ EOF expect(result.stderr).to eq "" expect(lines(result.stdout)).to include "ar rcf lib.a build/e.1/one.o build/e.1/three.o build/e.1/two.o" end + + it "allows passing object files as sources" do + test_dir("library") + result = run_rscons(rsconscript: "library_from_object.rb") + expect(result.stderr).to eq "" + expect(File.exists?("two.o")).to be_truthy + expect(lines(result.stdout)).to include "Building static library archive => lib.a" + end end context "SharedLibrary builder" do @@ -1425,6 +1433,13 @@ EOF expect(slines).to include("Linking => libmine.so") end end + + it "allows passing object files as sources" do + test_dir "shared_library" + result = run_rscons(rsconscript: "shared_library_from_object.rb") + expect(result.stderr).to eq "" + expect(File.exists?("one.o")) + end end context "multi-threading" do diff --git a/spec/rscons/environment_spec.rb b/spec/rscons/environment_spec.rb index 34cefd1..cf37a7b 100644 --- a/spec/rscons/environment_spec.rb +++ b/spec/rscons/environment_spec.rb @@ -233,27 +233,5 @@ module Rscons expect {env.__send__(:find_finished_thread, false)}.to raise_error /No threads to wait for/ 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 end end