begin transitioning builders to using instance variables instead of #run options Hash fields

This commit is contained in:
Josh Holtrop 2019-02-11 22:53:41 -05:00
parent ea25f62f7c
commit 86594c62b6
21 changed files with 149 additions and 164 deletions

View File

@ -1,15 +1,14 @@
class CHGen < Rscons::Builder
def run(options)
target, sources, cache, env, vars = options.values_at(:target, :sources, :cache, :env, :vars)
c_fname = target
h_fname = target.sub(/\.c$/, ".h")
unless cache.up_to_date?([c_fname, h_fname], "", sources, env)
c_fname = @target
h_fname = @target.sub(/\.c$/, ".h")
unless @cache.up_to_date?([c_fname, h_fname], "", @sources, @env)
puts "CHGen #{c_fname}"
File.open(c_fname, "w") {|fh| fh.puts "int THE_VALUE = 42;"}
File.open(h_fname, "w") {|fh| fh.puts "extern int THE_VALUE;"}
cache.register_build([c_fname, h_fname], "", sources, env)
@cache.register_build([c_fname, h_fname], "", @sources, @env)
end
target
@target
end
end

View File

@ -3,15 +3,14 @@ build do
require 'json'
require 'yaml'
env.add_builder(:JsonToYaml) do |params|
target, sources, cache, env, vars = params.values_at(:target, :sources, :cache, :env, :vars)
unless cache.up_to_date?(target, :JsonToYaml, sources, env)
cache.mkdir_p(File.dirname(target))
File.open(target, 'w') do |f|
f.write(YAML.dump(JSON.load(IO.read(sources.first))))
unless @cache.up_to_date?(@target, :JsonToYaml, @sources, @env)
@cache.mkdir_p(File.dirname(@target))
File.open(@target, 'w') do |f|
f.write(YAML.dump(JSON.load(IO.read(@sources.first))))
end
cache.register_build(target, :JsonToYaml, sources, env)
@cache.register_build(@target, :JsonToYaml, @sources, @env)
end
target
@target
end
env.JsonToYaml('foo.yml', 'foo.json')
end

View File

@ -1,25 +1,24 @@
class DebugBuilder < Rscons::Builder
def run(options)
target, sources, cache, env, vars = options.values_at(:target, :sources, :cache, :env, :vars)
command = %W[gcc -c -o #{target} #{sources.first}]
command = %W[gcc -c -o #{@target} #{@sources.first}]
if Rscons.vars["command_change"]
command += %w[-Wall]
end
if Rscons.vars["new_dep"]
sources += ["extra"]
@sources += ["extra"]
end
if Rscons.vars["strict_deps1"]
sources += ["extra"]
@sources += ["extra"]
strict_deps = true
end
if Rscons.vars["strict_deps2"]
sources = ["extra"] + sources
@sources = ["extra"] + @sources
strict_deps = true
end
if cache.up_to_date?(target, command, sources, env, debug: true, strict_deps: strict_deps)
target
if @cache.up_to_date?(@target, command, @sources, @env, debug: true, strict_deps: strict_deps)
@target
else
ThreadedCommand.new(command, short_description: "#{name} #{target}")
ThreadedCommand.new(command, short_description: "#{name} #{@target}")
end
end

View File

@ -1,16 +1,15 @@
class TestBuilder < Rscons::Builder
def run(options)
target, sources, cache, env = options.values_at(:target, :sources, :cache, :env)
command = Rscons::VarSet.new("A" => "a", "B" => "b")
unless cache.up_to_date?(target, command, sources, env)
File.open(target, "w") do |fh|
unless @cache.up_to_date?(@target, command, @sources, @env)
File.open(@target, "w") do |fh|
fh.puts("hi")
end
msg = "#{name} #{target}"
env.print_builder_run_message(msg, msg)
cache.register_build(target, command, sources, env)
msg = "#{name} #{@target}"
@env.print_builder_run_message(msg, msg)
@cache.register_build(@target, command, @sources, @env)
end
target
@target
end
end

View File

@ -1,12 +1,11 @@
class TestBuilder < Rscons::Builder
def run(options)
target, env, vars, cache = options.values_at(:target, :env, :vars, :cache)
if target == "two"
if @target == "two"
return false unless File.exists?("one")
end
wait_time = env.expand_varref("${wait_time}", vars)
command = ["ruby", "-e", "require 'fileutils'; sleep #{wait_time}; FileUtils.touch('#{target}');"]
standard_threaded_build("TestBuilder", target, command, [], env, cache)
wait_time = @env.expand_varref("${wait_time}", @vars)
command = ["ruby", "-e", "require 'fileutils'; sleep #{wait_time}; FileUtils.touch('#{@target}');"]
standard_threaded_build("TestBuilder", @target, command, [], @env, @cache)
end
def finalize(options)

View File

@ -1,10 +1,9 @@
class Fail < Rscons::Builder
def run(options)
target, cache, env, vars = options.values_at(:target, :cache, :env, :vars)
wait_time = env.expand_varref("${wait_time}", vars)
wait_time = @env.expand_varref("${wait_time}", @vars)
ruby_command = %[sleep #{wait_time}; exit 2]
command = %W[ruby -e #{ruby_command}]
standard_threaded_build("Fail #{target}", target, command, [], env, cache)
standard_threaded_build("Fail #{@target}", @target, command, [], @env, @cache)
end
def finalize(options)
standard_finalize(options)

View File

@ -1,11 +1,10 @@
class StrictBuilder < Rscons::Builder
def run(options)
target, sources, cache, env = options.values_at(:target, :sources, :cache, :env)
command = %W[gcc -o #{target}] + sources.sort
if cache.up_to_date?(target, command, sources, env, strict_deps: true)
target
command = %W[gcc -o #{@target}] + @sources.sort
if @cache.up_to_date?(@target, command, @sources, @env, strict_deps: true)
@target
else
ThreadedCommand.new(command, short_description: "#{name} #{target}")
ThreadedCommand.new(command, short_description: "#{name} #{@target}")
end
end

View File

@ -44,7 +44,23 @@ module Rscons
# @return [String, Symbol]
# Target file name.
attr_reader :target
attr_accessor :target
# @return [Array<String>]
# Source file name(s).
attr_accessor :sources
# @return [Cache]
# Cache instance.
attr_accessor :cache
# @return [Environment]
# The {Environment} performing the build operation.
attr_accessor :env
# @return [Hash, VarSet]
# Construction variables used to perform the build operation.
attr_accessor :vars
# Create an instance of the Builder to build a target.
#
@ -54,6 +70,8 @@ module Rscons
# Target file name.
# @option options [Array<String>] :sources
# Source file name(s).
# @option options [Cache] :cache
# The Cache object.
# @option options [Environment] :env
# The Environment executing the builder.
# @option options [Hash,VarSet] :vars
@ -61,6 +79,7 @@ module Rscons
def initialize(options)
@target = options[:target]
@sources = options[:sources]
@cache = options[:cache]
@env = options[:env]
@vars = options[:vars]
end
@ -88,16 +107,6 @@ module Rscons
#
# @param options [Hash]
# Run options.
# @option options [String] :target
# Target file name.
# @option options [Array<String>] :sources
# Source file name(s).
# @option options [Cache] :cache
# The Cache object.
# @option options [Environment] :env
# The Environment executing the builder.
# @option options [Hash,VarSet] :vars
# Extra construction variables.
#
# @return [ThreadedCommand,String,false]
# Name of the target file on success or false on failure.

View File

@ -21,22 +21,19 @@ module Rscons
# Run the builder to produce a build target.
def run(options)
target, sources, cache, env, vars = options.values_at(:target, :sources, :cache, :env, :vars)
vars = vars.merge({
"_TARGET" => target,
"_SOURCES" => sources,
})
@vars["_TARGET"] = @target
@vars["_SOURCES"] = @sources
cmd =
case
when sources.first.end_with?(*env.expand_varref("${LEXSUFFIX}"))
when @sources.first.end_with?(*@env.expand_varref("${LEXSUFFIX}"))
"LEX"
when sources.first.end_with?(*env.expand_varref("${YACCSUFFIX}"))
when @sources.first.end_with?(*@env.expand_varref("${YACCSUFFIX}"))
"YACC"
else
raise "Unknown source file #{sources.first.inspect} for CFile builder"
raise "Unknown source file #{@sources.first.inspect} for CFile builder"
end
command = env.build_command("${#{cmd}_CMD}", vars)
standard_threaded_build("#{cmd} #{target}", target, command, sources, env, cache)
command = @env.build_command("${#{cmd}_CMD}", @vars)
standard_threaded_build("#{cmd} #{@target}", @target, command, @sources, @env, @cache)
end
# Finalize a build.

View File

@ -18,18 +18,15 @@ module Rscons
# Target file name if target is up to date or a {ThreadedCommand}
# to execute to build the target.
def run(options)
target, sources, cache, env, vars = options.values_at(:target, :sources, :cache, :env, :vars)
vars = vars.merge({
"_TARGET" => target,
"_SOURCES" => sources,
})
command = env.build_command("${CMD}", vars)
cmd_desc = vars["CMD_DESC"] || "Command"
@vars["_TARGET"] = @target
@vars["_SOURCES"] = @sources
command = @env.build_command("${CMD}", @vars)
cmd_desc = @vars["CMD_DESC"] || "Command"
options = {}
if vars["CMD_STDOUT"]
options[:stdout] = env.expand_varref("${CMD_STDOUT}", vars)
if @vars["CMD_STDOUT"]
options[:stdout] = @env.expand_varref("${CMD_STDOUT}", @vars)
end
standard_threaded_build("#{cmd_desc} #{target}", target, command, sources, env, cache, options)
standard_threaded_build("#{cmd_desc} #{@target}", @target, command, @sources, @env, @cache, options)
end
# Finalize a build.

View File

@ -5,16 +5,15 @@ module Rscons
# Run the builder to produce a build target.
def run(options)
target, sources, cache, env, vars = options.values_at(:target, :sources, :cache, :env, :vars)
if File.directory?(target)
target
elsif File.exists?(target)
Ansi.write($stderr, :red, "Error: `#{target}' already exists and is not a directory", :reset, "\n")
if File.directory?(@target)
@target
elsif File.exists?(@target)
Ansi.write($stderr, :red, "Error: `#{@target}' already exists and is not a directory", :reset, "\n")
false
else
env.print_builder_run_message("Directory #{target}", nil)
cache.mkdir_p(target)
target
@env.print_builder_run_message("Directory #{@target}", nil)
@cache.mkdir_p(@target)
@target
end
end

View File

@ -11,17 +11,16 @@ module Rscons
# Run the builder to produce a build target.
def run(options)
target, sources, cache, env, vars = options.values_at(:target, :sources, :cache, :env, :vars)
vars = vars.merge("_SOURCES" => sources)
command = env.build_command("${DISASM_CMD}", vars)
if cache.up_to_date?(target, command, sources, env)
target
@vars["_SOURCES"] = sources
command = @env.build_command("${DISASM_CMD}", @vars)
if @cache.up_to_date?(@target, command, @sources, @env)
@target
else
cache.mkdir_p(File.dirname(target))
@cache.mkdir_p(File.dirname(@target))
ThreadedCommand.new(
command,
short_description: "Disassemble #{target}",
system_options: {out: target})
short_description: "Disassemble #{@target}",
system_options: {out: @target})
end
end

View File

@ -7,15 +7,14 @@ module Rscons
# Run the builder to produce a build target.
def run(options)
target, sources, cache, env, vars = options.values_at(:target, :sources, :cache, :env, :vars)
target_is_dir = (sources.length > 1) ||
Dir.exists?(sources.first) ||
Dir.exists?(target)
outdir = target_is_dir ? target : File.dirname(target)
target_is_dir = (@sources.length > 1) ||
Dir.exists?(@sources.first) ||
Dir.exists?(@target)
outdir = target_is_dir ? @target : File.dirname(@target)
# Collect the list of files to copy over.
file_map = {}
if target_is_dir
sources.each do |src|
@sources.each do |src|
if Dir.exists? src
Dir.glob("#{src}/**/*", File::FNM_DOTMATCH).select do |f|
File.file?(f)
@ -33,20 +32,19 @@ module Rscons
printed_message = false
file_map.each do |src, dest|
# Check the cache and copy if necessary
unless cache.up_to_date?(dest, :Copy, [src], env)
unless @cache.up_to_date?(dest, :Copy, [src], @env)
unless printed_message
env.print_builder_run_message("#{self.class.name} #{target}", nil)
@env.print_builder_run_message("#{name} #{@target}", nil)
printed_message = true
end
cache.mkdir_p(File.dirname(dest))
@cache.mkdir_p(File.dirname(dest))
FileUtils.cp(src, dest, :preserve => true)
end
cache.register_build(dest, :Copy, [src], env)
@cache.register_build(dest, :Copy, [src], @env)
end
target if (target_is_dir ? Dir.exists?(target) : File.exists?(target))
@target if (target_is_dir ? Dir.exists?(@target) : File.exists?(@target))
end
end
# The Copy builder is identical to the Install builder.

View File

@ -36,14 +36,11 @@ module Rscons
# @return [String,false]
# Name of the target file on success or false on failure.
def run(options)
target, sources, cache, env, vars = options.values_at(:target, :sources, :cache, :env, :vars)
vars = vars.merge({
'_TARGET' => target,
'_SOURCES' => @objects,
})
@vars["_TARGET"] = @target
@vars["_SOURCES"] = @objects
options[:sources] = @objects
command = env.build_command("${ARCMD}", vars)
standard_threaded_build("AR #{target}", target, command, @objects, env, cache)
command = @env.build_command("${ARCMD}", @vars)
standard_threaded_build("AR #{@target}", @target, command, @objects, @env, @cache)
end
# Finalize a build.

View File

@ -83,22 +83,19 @@ module Rscons
# Target file name if target is up to date or a {ThreadedCommand}
# to execute to build the target.
def run(options)
target, sources, cache, env, vars = options.values_at(:target, :sources, :cache, :env, :vars)
vars = vars.merge({
'_TARGET' => target,
'_SOURCES' => sources,
'_DEPFILE' => Rscons.set_suffix(target, env.expand_varref("${DEPFILESUFFIX}", vars)),
})
@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))
@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}"
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'])
command = @env.build_command("${#{com_prefix}CMD}", @vars)
@env.produces(@target, @vars["_DEPFILE"])
# Store vars back into options so new keys are accessible in #finalize.
options[:vars] = vars
standard_threaded_build("#{com_prefix} #{target}", target, command, sources, env, cache)
standard_threaded_build("#{com_prefix} #{@target}", @target, command, @sources, @env, @cache)
end
# Finalize the build operation.

View File

@ -19,24 +19,23 @@ module Rscons
# Target file name if target is up to date or a {ThreadedCommand}
# to execute to build the target.
def run(options)
target, sources, cache, env, vars = options.values_at(:target, :sources, :cache, :env, :vars)
if sources.find {|s| s.end_with?(*env.expand_varref("${CXXSUFFIX}", vars))}
if @sources.find {|s| s.end_with?(*@env.expand_varref("${CXXSUFFIX}", @vars))}
pp_cc = "${CXX}"
depgen = "${CXXDEPGEN}"
else
pp_cc = "${CC}"
depgen = "${CCDEPGEN}"
end
vars = vars.merge("_PREPROCESS_CC" => pp_cc,
"_PREPROCESS_DEPGEN" => depgen,
"_TARGET" => target,
"_SOURCES" => sources,
"_DEPFILE" => Rscons.set_suffix(target, env.expand_varref("${DEPFILESUFFIX}", vars)))
command = env.build_command("${CPP_CMD}", vars)
env.produces(target, vars['_DEPFILE'])
@vars["_PREPROCESS_CC"] = pp_cc
@vars["_PREPROCESS_DEPGEN"] = depgen
@vars["_TARGET"] = @target
@vars["_SOURCES"] = @sources
@vars["_DEPFILE"] = Rscons.set_suffix(target, env.expand_varref("${DEPFILESUFFIX}", vars))
command = @env.build_command("${CPP_CMD}", @vars)
@env.produces(@target, @vars["_DEPFILE"])
# Store vars back into options so new keys are accessible in #finalize.
options[:vars] = vars
standard_threaded_build("#{self.class.name} #{target}", target, command, sources, env, cache)
standard_threaded_build("#{name} #{@target}", @target, command, @sources, @env, @cache)
end
# Finalize the build operation.

View File

@ -46,25 +46,22 @@ module Rscons
# @return [String,false]
# Name of the target file on success or false on failure.
def run(options)
target, sources, cache, env, vars = options.values_at(:target, :sources, :cache, :env, :vars)
ld = env.expand_varref("${LD}", vars)
ld = @env.expand_varref("${LD}", @vars)
ld = if ld != ""
ld
elsif sources.find {|s| s.end_with?(*env.expand_varref("${DSUFFIX}", vars))}
elsif @sources.find {|s| s.end_with?(*@env.expand_varref("${DSUFFIX}", @vars))}
"${DC}"
elsif sources.find {|s| s.end_with?(*env.expand_varref("${CXXSUFFIX}", vars))}
elsif @sources.find {|s| s.end_with?(*@env.expand_varref("${CXXSUFFIX}", @vars))}
"${CXX}"
else
"${CC}"
end
vars = vars.merge({
'_TARGET' => target,
'_SOURCES' => @objects,
'LD' => ld,
})
@vars["_TARGET"] = @target
@vars["_SOURCES"] = @objects
@vars["LD"] = ld
options[:sources] = @objects
command = env.build_command("${LDCMD}", vars)
standard_threaded_build("LD #{target}", target, command, @objects, env, cache)
command = @env.build_command("${LDCMD}", @vars)
standard_threaded_build("LD #{@target}", @target, command, @objects, @env, @cache)
end
# Finalize a build.

View File

@ -58,25 +58,22 @@ module Rscons
# @return [String,false]
# Name of the target file on success or false on failure.
def run(options)
target, sources, cache, env, vars = options.values_at(:target, :sources, :cache, :env, :vars)
ld = env.expand_varref("${SHLD}", vars)
ld = @env.expand_varref("${SHLD}", @vars)
ld = if ld != ""
ld
elsif sources.find {|s| s.end_with?(*env.expand_varref("${DSUFFIX}", vars))}
elsif @sources.find {|s| s.end_with?(*@env.expand_varref("${DSUFFIX}", @vars))}
"${SHDC}"
elsif sources.find {|s| s.end_with?(*env.expand_varref("${CXXSUFFIX}", vars))}
elsif @sources.find {|s| s.end_with?(*@env.expand_varref("${CXXSUFFIX}", @vars))}
"${SHCXX}"
else
"${SHCC}"
end
vars = vars.merge({
'_TARGET' => target,
'_SOURCES' => @objects,
'SHLD' => ld,
})
@vars["_TARGET"] = @target
@vars["_SOURCES"] = @objects
@vars["SHLD"] = ld
options[:sources] = @objects
command = env.build_command("${SHLDCMD}", vars)
standard_threaded_build("SHLD #{target}", target, command, @objects, env, cache)
command = @env.build_command("${SHLDCMD}", @vars)
standard_threaded_build("SHLD #{@target}", @target, command, @objects, @env, @cache)
end
# Finalize a build.

View File

@ -68,22 +68,19 @@ module Rscons
# Target file name if target is up to date or a {ThreadedCommand}
# to execute to build the target.
def run(options)
target, sources, cache, env, vars = options.values_at(:target, :sources, :cache, :env, :vars)
vars = vars.merge({
'_TARGET' => target,
'_SOURCES' => sources,
'_DEPFILE' => Rscons.set_suffix(target, env.expand_varref("${DEPFILESUFFIX}", vars)),
})
@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))
@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}"
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'])
command = @env.build_command("${#{com_prefix}CMD}", @vars)
@env.produces(@target, @vars["_DEPFILE"])
# Store vars back into options so new keys are accessible in #finalize.
options[:vars] = vars
standard_threaded_build("#{com_prefix} #{target}", target, command, sources, env, cache)
options[:vars] = @vars
standard_threaded_build("#{com_prefix} #{@target}", @target, command, @sources, @env, @cache)
end
# Finalize the build operation.

View File

@ -29,7 +29,7 @@ module Rscons
#
# Method signature described by {Builder#run}.
def run(*args)
@run_proc.call(*args)
instance_exec(*args, &@run_proc)
end
end

View File

@ -354,7 +354,12 @@ module Rscons
sources = Array(sources).map do |source|
expand_path(expand_varref(source))
end.flatten
builder = @builders[method.to_s].new(env: self, target: target, sources: sources, vars: vars)
builder = @builders[method.to_s].new(
target: target,
sources: sources,
cache: Cache.instance,
env: self,
vars: vars)
add_target(builder.target, builder, sources, vars)
builder
else
@ -535,6 +540,10 @@ module Rscons
# Invoke pre-build hooks.
call_build_hooks[:pre]
# TODO: remove build_operation fields and just pass in the Builder.
builder.sources = build_operation[:sources]
builder.vars = build_operation[:vars]
# Call the builder's #run method.
rv = builder.run(build_operation)