fill in CC, Program, Environment.process() to get simple builds working
This commit is contained in:
parent
5634b8856d
commit
760f698963
@ -4,6 +4,7 @@ require "rscons/environment"
|
|||||||
require "rscons/version"
|
require "rscons/version"
|
||||||
|
|
||||||
require "rscons/monkey/module"
|
require "rscons/monkey/module"
|
||||||
|
require "rscons/monkey/string"
|
||||||
|
|
||||||
# default builders
|
# default builders
|
||||||
require "rscons/builders/cc"
|
require "rscons/builders/cc"
|
||||||
|
@ -3,5 +3,8 @@ module Rscons
|
|||||||
def initialize(env)
|
def initialize(env)
|
||||||
@env = env
|
@env = env
|
||||||
end
|
end
|
||||||
|
def default_variables(env)
|
||||||
|
{}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,4 +1,37 @@
|
|||||||
module Rscons
|
module Rscons
|
||||||
class CC < Builder
|
class CC < Builder
|
||||||
|
def default_variables(env)
|
||||||
|
{
|
||||||
|
'CC' => 'gcc',
|
||||||
|
'CFLAGS' => [],
|
||||||
|
'CPPFLAGS' => [],
|
||||||
|
'OBJSUFFIX' => '.o',
|
||||||
|
'CSUFFIX' => '.c',
|
||||||
|
'CCDEPGEN' => ['-MMD', '-MF', '$DEPFILE'],
|
||||||
|
'CCCOM' => ['$CC', '-c', '-o', '$TARGET', '$CCDEPGEN', '$CPPFLAGS', '$CFLAGS', '$SOURCES']
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def produces?(target, source)
|
||||||
|
target.has_suffix?(@env['OBJSUFFIX']) and source.has_suffix?(@env['CSUFFIX'])
|
||||||
|
end
|
||||||
|
|
||||||
|
def run(target, sources, cache)
|
||||||
|
unless cache.up_to_date?(target, sources)
|
||||||
|
vars = {
|
||||||
|
'TARGET' => target,
|
||||||
|
'SOURCES' => sources,
|
||||||
|
'DEPFILE' => target.set_suffix('.mf'),
|
||||||
|
}
|
||||||
|
@env.execute("CC #{target}", @env['CCCOM'], vars)
|
||||||
|
deps = sources
|
||||||
|
if File.exists?(vars['DEPFILE'])
|
||||||
|
deps += @env.parse_makefile_deps(vars['DEPFILE'], target)
|
||||||
|
FileUtils.rm_f(vars['DEPFILE'])
|
||||||
|
end
|
||||||
|
cache.register_build(target, deps.uniq)
|
||||||
|
end
|
||||||
|
target
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,19 +1,38 @@
|
|||||||
module Rscons
|
module Rscons
|
||||||
class Program < Builder
|
class Program < Builder
|
||||||
def default_variables
|
def default_variables(env)
|
||||||
{
|
{
|
||||||
'CC' => 'gcc',
|
'LD' => nil,
|
||||||
'CFLAGS' => [],
|
|
||||||
'CPPFLAGS' => [],
|
|
||||||
'OBJSUFFIX' => '.o',
|
'OBJSUFFIX' => '.o',
|
||||||
'CSUFFIX' => '.c',
|
'LIBSUFFIX' => '.a',
|
||||||
'CCDEPGEN' => ['-MMD', '-MF', '$DEPFILE'],
|
'LDFLAGS' => [],
|
||||||
'CCCOM' => ['$CC', '-c', '-o', '$TARGET', '$CCDEPGEN', '$CPPFLAGS', '$CFLAGS', '$SOURCES']
|
'LIBPATHS' => [],
|
||||||
|
'LIBS' => [],
|
||||||
|
'LDCOM' => ['$LD', '-o', '$TARGET', '$LDFLAGS', '$SOURCES', '-L$[LIBPATHS]', '-l$[LIBS]']
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def produces?(target, source)
|
def run(target, sources, cache)
|
||||||
target.has_suffix?(@env['OBJSUFFIX']) and source.has_suffix?(@env['CSUFFIX'])
|
# convert sources to object file names
|
||||||
|
sources = sources.map do |source|
|
||||||
|
if source.has_suffix?([@env['OBJSUFFIX'], @env['LIBSUFFIX']])
|
||||||
|
source
|
||||||
|
else
|
||||||
|
o_file = source.set_suffix(@env['OBJSUFFIX', :string])
|
||||||
|
builder = @env.builders.values.find { |b| b.produces?(o_file, source) }
|
||||||
|
builder or raise "No builder found to convert input source #{source.inspect} to an object file."
|
||||||
|
builder.run(o_file, [source], cache)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
unless cache.up_to_date?(target, sources)
|
||||||
|
vars = {
|
||||||
|
'TARGET' => target,
|
||||||
|
'SOURCES' => sources,
|
||||||
|
'LD' => @env['LD'] || @env['CC'], # TODO: figure out whether to use CC or CXX
|
||||||
|
}
|
||||||
|
@env.execute("LD #{target}", @env['LDCOM'], vars)
|
||||||
|
end
|
||||||
|
target
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -25,6 +25,7 @@ module Rscons
|
|||||||
|
|
||||||
def up_to_date?(file, deps = nil)
|
def up_to_date?(file, deps = nil)
|
||||||
# TODO
|
# TODO
|
||||||
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
def register_build(target, deps)
|
def register_build(target, deps)
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
|
require 'set'
|
||||||
|
|
||||||
module Rscons
|
module Rscons
|
||||||
class Environment
|
class Environment
|
||||||
|
attr_reader :builders
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
alias_method :orig_new, :new
|
alias_method :orig_new, :new
|
||||||
end
|
end
|
||||||
@ -39,6 +43,12 @@ module Rscons
|
|||||||
|
|
||||||
def add_builder(builder)
|
def add_builder(builder)
|
||||||
@builders[builder.class.short_name] = builder
|
@builders[builder.class.short_name] = builder
|
||||||
|
var_defs = builder.default_variables(self)
|
||||||
|
if var_defs
|
||||||
|
var_defs.each_pair do |var, val|
|
||||||
|
@variables[var] ||= val
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def [](key, type = nil)
|
def [](key, type = nil)
|
||||||
@ -58,15 +68,70 @@ module Rscons
|
|||||||
|
|
||||||
def process
|
def process
|
||||||
cache = Cache.new
|
cache = Cache.new
|
||||||
|
targets_processed = Set.new
|
||||||
|
process_target = proc do |target|
|
||||||
|
sources_built = @targets[target][:source].map do |src|
|
||||||
|
targets_processed.include?(src) or not @targets.include?(src) or process_target.call(src)
|
||||||
|
end.all?
|
||||||
|
if sources_built
|
||||||
|
@targets[target][:builder].run(target,
|
||||||
|
@targets[target][:source],
|
||||||
|
cache,
|
||||||
|
*@targets[target][:args])
|
||||||
|
else
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@targets.each do |target, info|
|
||||||
|
next if targets_processed.include?(target)
|
||||||
|
break unless process_target.call(target)
|
||||||
|
end
|
||||||
cache.write
|
cache.write
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def execute(short_desc, command, extra_vars)
|
||||||
|
merged_variables = @variables.merge(extra_vars)
|
||||||
|
expand_varref = proc do |varref|
|
||||||
|
if varref.is_a?(Array)
|
||||||
|
varref.map do |ent|
|
||||||
|
expand_varref.call(ent)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if varref =~ /^(.*)\$\[(\w+)\](.*)$/
|
||||||
|
# expand array with given prefix, suffix
|
||||||
|
prefix, varname, suffix = $1, $2, $3
|
||||||
|
varval = merged_variables[varname]
|
||||||
|
unless varval.is_a?(Array)
|
||||||
|
raise "Array expected for $#{varname}"
|
||||||
|
end
|
||||||
|
varval.map {|e| "#{prefix}#{e}#{suffix}"}
|
||||||
|
elsif varref =~ /^\$(.*)$/
|
||||||
|
# expand a single variable reference
|
||||||
|
varname = $1
|
||||||
|
varval = merged_variables[varname]
|
||||||
|
varval or raise "Could not find variable #{varname.inspect}"
|
||||||
|
expand_varref.call(varval)
|
||||||
|
else
|
||||||
|
varref
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
command = expand_varref.call(command.flatten).flatten
|
||||||
|
if @echo == :command
|
||||||
|
puts command.map { |c| c =~ /\s/ ? "'#{c}'" : c }.join(' ')
|
||||||
|
elsif @echo == :short
|
||||||
|
puts short_desc
|
||||||
|
end
|
||||||
|
system(*command)
|
||||||
|
end
|
||||||
|
|
||||||
alias_method :orig_method_missing, :method_missing
|
alias_method :orig_method_missing, :method_missing
|
||||||
def method_missing(method, *args)
|
def method_missing(method, *args)
|
||||||
if @builders.has_key?(method.to_s)
|
if @builders.has_key?(method.to_s)
|
||||||
target, source, *rest = args
|
target, source, *rest = args
|
||||||
|
source = [source] unless source.is_a?(Array)
|
||||||
@targets[target] = {
|
@targets[target] = {
|
||||||
builder: method.to_s,
|
builder: @builders[method.to_s],
|
||||||
source: source,
|
source: source,
|
||||||
args: rest,
|
args: rest,
|
||||||
}
|
}
|
||||||
@ -74,5 +139,24 @@ module Rscons
|
|||||||
orig_method_missing(method, *args)
|
orig_method_missing(method, *args)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def parse_makefile_deps(mf_fname, target)
|
||||||
|
deps = []
|
||||||
|
buildup = ''
|
||||||
|
File.read(mf_fname).each_line do |line|
|
||||||
|
if line =~ /^(.*)\\\s*$/
|
||||||
|
buildup += ' ' + $1
|
||||||
|
else
|
||||||
|
if line =~ /^(.*): (.*)$/
|
||||||
|
target, tdeps = $1.strip, $2
|
||||||
|
if target == target
|
||||||
|
deps += tdeps.split(' ').map(&:strip)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
buildup = ''
|
||||||
|
end
|
||||||
|
end
|
||||||
|
deps
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user