Object builder cleanup - #94

This commit is contained in:
Josh Holtrop 2019-04-09 18:28:42 -04:00
parent 1efee50b2c
commit 5534878f68
11 changed files with 108 additions and 73 deletions

View File

@ -0,0 +1,7 @@
build do
Environment.new do |env|
env["CPPPATH"] << "src/lib"
env.Object("file.S", "src/lib/one.c", "CFLAGS" => env["CFLAGS"] + ["-S"])
libmine = env.SharedLibrary("mine", "file.S")
end
end

View File

@ -166,6 +166,7 @@ module Rscons
end
# builder mixins
require_relative "rscons/builders/mixins/object"
require_relative "rscons/builders/mixins/object_deps"
# default builders
@ -182,5 +183,11 @@ require_relative "rscons/builders/shared_library"
require_relative "rscons/builders/shared_object"
require_relative "rscons/builders/simple_builder"
# language support
require_relative "rscons/builders/lang/asm"
require_relative "rscons/builders/lang/c"
require_relative "rscons/builders/lang/cxx"
require_relative "rscons/builders/lang/d"
# Unbuffer $stdout
$stdout.sync = true

View File

@ -0,0 +1,2 @@
Rscons::Builders::Object.register(command: "${ASCMD}", suffix: "${ASSUFFIX}", short_description: "Assembling")
Rscons::Builders::SharedObject.register(command: "${ASCMD}", suffix: "${ASSUFFIX}", short_description: "Assembling")

View File

@ -0,0 +1,2 @@
Rscons::Builders::Object.register(command: "${CCCMD}", suffix: "${CSUFFIX}")
Rscons::Builders::SharedObject.register(command: "${SHCCCMD}", suffix: "${CSUFFIX}")

View File

@ -0,0 +1,2 @@
Rscons::Builders::Object.register(command: "${CXXCMD}", suffix: "${CXXSUFFIX}")
Rscons::Builders::SharedObject.register(command: "${SHCXXCMD}", suffix: "${CXXSUFFIX}")

View File

@ -0,0 +1,2 @@
Rscons::Builders::Object.register(command: "${DCCMD}", suffix: "${DSUFFIX}")
Rscons::Builders::SharedObject.register(command: "${SHDCCMD}", suffix: "${DSUFFIX}")

View File

@ -0,0 +1,73 @@
module Rscons
module Builders
module Mixins
module Object
class << self
# Hook called by Ruby when this module is included by a class (klass).
def included(klass)
klass.__send__(:extend, ClassMethods)
end
end
# Object mixin class methods.
module ClassMethods
# @return [Array<Hash>]
# Parameters used to build.
def providers
@providers ||= []
end
# Register a set of parameters that can be used to build an Object.
#
# @param params [Hash]
# Build parameters.
# @option params [Array, String] :command
# Command or construction variable reference thereto.
# @option params [Array, String] :suffix
# Suffix(es) or construction variable reference thereto.
# @option params [String] :short_description
# Short description to be printed when the builder runs (default:
# "Compiling")
def register(params)
providers << params
end
end
# Construct a builder conforming to the Object interface.
def initialize(params)
super
build_params = self.class.providers.find do |build_params|
@sources.first.end_with?(*@env.expand_varref(build_params[:suffix], @vars))
end
unless build_params
raise "Unknown input file type: #{@sources.first.inspect}"
end
@command_template = build_params[:command]
@short_description = build_params[:short_description] || "Compiling"
end
# Run the builder to produce a build target.
def run(params)
if @command
deps = @sources
if File.exists?(@vars["_DEPFILE"])
deps += Util.parse_makefile_deps(@vars["_DEPFILE"])
end
@cache.register_build(@target, @command, deps.uniq, @env)
true
else
@vars["_TARGET"] = @target
@vars["_SOURCES"] = @sources
@vars["_DEPFILE"] = Rscons.set_suffix(target, env.expand_varref("${DEPFILESUFFIX}", vars))
command = @env.build_command(@command_template, @vars)
@env.produces(@target, @vars["_DEPFILE"])
message = "#{@short_description} #{Util.short_format_paths(@sources)}"
standard_command(message, command)
end
end
end
end
end
end

View File

@ -1,6 +1,6 @@
module Rscons
module Builders
# Rscons::Buidlers::Mixins namespacing module.
# Rscons::Builders::Mixins namespacing module.
module Mixins
# Functionality for builders which desire object or static library files
# as inputs.

View File

@ -3,41 +3,7 @@ module Rscons
# A default Rscons builder which knows how to produce an object file from
# various types of source files.
class Object < Builder
# Mapping of known sources from which to build object files.
KNOWN_SUFFIXES = {
"AS" => "ASSUFFIX",
"CC" => "CSUFFIX",
"CXX" => "CXXSUFFIX",
"DC" => "DSUFFIX",
}
# Run the builder to produce a build target.
def run(options)
if @command
deps = @sources
if File.exists?(@vars["_DEPFILE"])
deps += Util.parse_makefile_deps(@vars["_DEPFILE"])
end
@cache.register_build(@target, @command, deps.uniq, @env)
true
else
@vars["_TARGET"] = @target
@vars["_SOURCES"] = @sources
@vars["_DEPFILE"] = Rscons.set_suffix(target, env.expand_varref("${DEPFILESUFFIX}", vars))
com_prefix = KNOWN_SUFFIXES.find do |compiler, suffix_var|
@sources.first.end_with?(*@env.expand_varref("${#{suffix_var}}", @vars))
end.tap do |v|
v.nil? and raise "Error: unknown input file type: #{@sources.first.inspect}"
end.first
command = @env.build_command("${#{com_prefix}CMD}", @vars)
@env.produces(@target, @vars["_DEPFILE"])
verb = com_prefix == "AS" ? "Assembling" : "Compiling"
message = "#{verb} #{Util.short_format_paths(@sources)}"
standard_command(message, command)
end
end
include Mixins::Object
end
end
end

View File

@ -4,41 +4,7 @@ module Rscons
# is capable of being linked into a shared library from various types of
# source files.
class SharedObject < Builder
# Mapping of known sources from which to build object files.
KNOWN_SUFFIXES = {
"AS" => "ASSUFFIX",
"SHCC" => "CSUFFIX",
"SHCXX" => "CXXSUFFIX",
"SHDC" => "DSUFFIX",
}
# Run the builder to produce a build target.
def run(options)
if @command
deps = @sources
if File.exists?(@vars["_DEPFILE"])
deps += Util.parse_makefile_deps(@vars["_DEPFILE"])
end
@cache.register_build(@target, @command, deps.uniq, @env)
true
else
@vars["_TARGET"] = @target
@vars["_SOURCES"] = @sources
@vars["_DEPFILE"] = Rscons.set_suffix(target, env.expand_varref("${DEPFILESUFFIX}", vars))
com_prefix = KNOWN_SUFFIXES.find do |compiler, suffix_var|
@sources.first.end_with?(*@env.expand_varref("${#{suffix_var}}", @vars))
end.tap do |v|
v.nil? and raise "Error: unknown input file type: #{@sources.first.inspect}"
end.first
command = @env.build_command("${#{com_prefix}CMD}", @vars)
@env.produces(@target, @vars["_DEPFILE"])
verb = com_prefix == "AS" ? "Assembling" : "Compiling"
message = "#{verb} #{Util.short_format_paths(@sources)}"
standard_command(message, command)
end
end
include Mixins::Object
end
end
end

View File

@ -779,6 +779,14 @@ EOF
expect(`./test-static.exe`).to match /Hi from one/
end
it "creates shared libraries using assembly" do
test_dir("shared_library")
result = run_rscons(rsconscript: "shared_library_as.rb")
expect(result.stderr).to eq ""
expect(File.exists?("file.S")).to be_truthy
end
it "creates shared libraries using C++" do
test_dir("shared_library")
@ -1391,7 +1399,7 @@ EOF
it "raises an error when given a source file with an unknown suffix" do
test_dir("simple")
result = run_rscons(rsconscript: "error_unknown_suffix.rb")
expect(result.stderr).to match /unknown input file type: "foo.xyz"/
expect(result.stderr).to match /Unknown input file type: "foo.xyz"/
end
end
@ -1399,7 +1407,7 @@ EOF
it "raises an error when given a source file with an unknown suffix" do
test_dir("shared_library")
result = run_rscons(rsconscript: "error_unknown_suffix.rb")
expect(result.stderr).to match /unknown input file type: "foo.xyz"/
expect(result.stderr).to match /Unknown input file type: "foo.xyz"/
end
end