From 5362f761e6b7c40f6e199c47edca4c390c1d830c Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Tue, 31 Dec 2013 13:31:17 -0500 Subject: [PATCH] move default builder classes into Rscons::Builders namespace module --- lib/rscons.rb | 6 +- lib/rscons/builder.rb | 3 + lib/rscons/builders/library.rb | 44 +++++----- lib/rscons/builders/object.rb | 140 ++++++++++++++++---------------- lib/rscons/builders/program.rb | 70 ++++++++-------- lib/rscons/environment.rb | 4 +- spec/rscons/environment_spec.rb | 2 +- 7 files changed, 139 insertions(+), 130 deletions(-) diff --git a/lib/rscons.rb b/lib/rscons.rb index cd66050..809f6ea 100644 --- a/lib/rscons.rb +++ b/lib/rscons.rb @@ -14,9 +14,9 @@ require "rscons/builders/program" # Namespace module for rscons classes module Rscons DEFAULT_BUILDERS = [ - Library, - Object, - Program, + :Library, + :Object, + :Program, ] class BuildError < RuntimeError; end diff --git a/lib/rscons/builder.rb b/lib/rscons/builder.rb index de0de33..b652d65 100644 --- a/lib/rscons/builder.rb +++ b/lib/rscons/builder.rb @@ -1,6 +1,9 @@ require "fileutils" module Rscons + # Namespace module in which to store builders for convenient grouping + module Builders; end + # Class to hold an object that knows how to build a certain type of file. class Builder # Return the name of the builder. diff --git a/lib/rscons/builders/library.rb b/lib/rscons/builders/library.rb index 8d91370..8edba0c 100644 --- a/lib/rscons/builders/library.rb +++ b/lib/rscons/builders/library.rb @@ -1,27 +1,27 @@ -require 'fileutils' - module Rscons - # A default RScons builder that produces a static library archive. - class Library < Builder - def default_variables(env) - { - 'AR' => 'ar', - 'LIBSUFFIX' => '.a', - 'ARFLAGS' => [], - 'ARCMD' => ['${AR}', 'rcs', '${ARFLAGS}', '${_TARGET}', '${_SOURCES}'] - } - end + module Builders + # A default RScons builder that produces a static library archive. + class Rscons::Builders::Library < Rscons::Builder + def default_variables(env) + { + 'AR' => 'ar', + 'LIBSUFFIX' => '.a', + 'ARFLAGS' => [], + 'ARCMD' => ['${AR}', 'rcs', '${ARFLAGS}', '${_TARGET}', '${_SOURCES}'] + } + end - def run(target, sources, cache, env, vars) - # build sources to linkable objects - objects = env.build_sources(sources, [env['OBJSUFFIX'], env['LIBSUFFIX']].flatten, cache, vars) - if objects - vars = vars.merge({ - '_TARGET' => target, - '_SOURCES' => objects, - }) - command = env.build_command(env['ARCMD'], vars) - standard_build("AR #{target}", target, command, objects, env, cache) + def run(target, sources, cache, env, vars) + # build sources to linkable objects + objects = env.build_sources(sources, [env['OBJSUFFIX'], env['LIBSUFFIX']].flatten, cache, vars) + if objects + vars = vars.merge({ + '_TARGET' => target, + '_SOURCES' => objects, + }) + command = env.build_command(env['ARCMD'], vars) + standard_build("AR #{target}", target, command, objects, env, cache) + end end end end diff --git a/lib/rscons/builders/object.rb b/lib/rscons/builders/object.rb index 20322ef..9549311 100644 --- a/lib/rscons/builders/object.rb +++ b/lib/rscons/builders/object.rb @@ -1,79 +1,81 @@ module Rscons - # A default RScons builder which knows how to produce an object file from - # various types of source files. - class Object < Builder - KNOWN_SUFFIXES = { - "AS" => "ASSUFFIX", - "CC" => "CSUFFIX", - "CXX" => "CXXSUFFIX", - "DC" => "DSUFFIX", - } - - def default_variables(env) - { - 'OBJSUFFIX' => '.o', - - 'AS' => '${CC}', - 'ASFLAGS' => [], - 'ASSUFFIX' => '.S', - 'ASPPPATH' => '${CPPPATH}', - 'ASPPFLAGS' => '${CPPFLAGS}', - 'ASDEPGEN' => ['-MMD', '-MF', '${_DEPFILE}'], - 'ASCMD' => ['${AS}', '-c', '-o', '${_TARGET}', '${ASDEPGEN}', '-I${ASPPPATH}', '${ASPPFLAGS}', '${ASFLAGS}', '${_SOURCES}'], - - 'CPPFLAGS' => [], - 'CPPPATH' => [], - - 'CC' => 'gcc', - 'CFLAGS' => [], - 'CSUFFIX' => '.c', - 'CCDEPGEN' => ['-MMD', '-MF', '${_DEPFILE}'], - 'CCCMD' => ['${CC}', '-c', '-o', '${_TARGET}', '${CCDEPGEN}', '-I${CPPPATH}', '${CPPFLAGS}', '${CFLAGS}', '${_SOURCES}'], - - 'CXX' => 'g++', - 'CXXFLAGS' => [], - 'CXXSUFFIX' => '.cc', - 'CXXDEPGEN' => ['-MMD', '-MF', '${_DEPFILE}'], - 'CXXCMD' =>['${CXX}', '-c', '-o', '${_TARGET}', '${CXXDEPGEN}', '-I${CPPPATH}', '${CPPFLAGS}', '${CXXFLAGS}', '${_SOURCES}'], - - 'DC' => 'gdc', - 'DFLAGS' => [], - 'DSUFFIX' => '.d', - 'D_IMPORT_PATH' => [], - 'DCCMD' => ['${DC}', '-c', '-o', '${_TARGET}', '-I${D_IMPORT_PATH}', '${DFLAGS}', '${_SOURCES}'], + module Builders + # A default RScons builder which knows how to produce an object file from + # various types of source files. + class Object < Builder + KNOWN_SUFFIXES = { + "AS" => "ASSUFFIX", + "CC" => "CSUFFIX", + "CXX" => "CXXSUFFIX", + "DC" => "DSUFFIX", } - end - def produces?(target, source, env) - target.has_suffix?(env['OBJSUFFIX']) and KNOWN_SUFFIXES.find do |compiler, suffix_var| - source.has_suffix?(env[suffix_var]) + def default_variables(env) + { + 'OBJSUFFIX' => '.o', + + 'AS' => '${CC}', + 'ASFLAGS' => [], + 'ASSUFFIX' => '.S', + 'ASPPPATH' => '${CPPPATH}', + 'ASPPFLAGS' => '${CPPFLAGS}', + 'ASDEPGEN' => ['-MMD', '-MF', '${_DEPFILE}'], + 'ASCMD' => ['${AS}', '-c', '-o', '${_TARGET}', '${ASDEPGEN}', '-I${ASPPPATH}', '${ASPPFLAGS}', '${ASFLAGS}', '${_SOURCES}'], + + 'CPPFLAGS' => [], + 'CPPPATH' => [], + + 'CC' => 'gcc', + 'CFLAGS' => [], + 'CSUFFIX' => '.c', + 'CCDEPGEN' => ['-MMD', '-MF', '${_DEPFILE}'], + 'CCCMD' => ['${CC}', '-c', '-o', '${_TARGET}', '${CCDEPGEN}', '-I${CPPPATH}', '${CPPFLAGS}', '${CFLAGS}', '${_SOURCES}'], + + 'CXX' => 'g++', + 'CXXFLAGS' => [], + 'CXXSUFFIX' => '.cc', + 'CXXDEPGEN' => ['-MMD', '-MF', '${_DEPFILE}'], + 'CXXCMD' =>['${CXX}', '-c', '-o', '${_TARGET}', '${CXXDEPGEN}', '-I${CPPPATH}', '${CPPFLAGS}', '${CXXFLAGS}', '${_SOURCES}'], + + 'DC' => 'gdc', + 'DFLAGS' => [], + 'DSUFFIX' => '.d', + 'D_IMPORT_PATH' => [], + 'DCCMD' => ['${DC}', '-c', '-o', '${_TARGET}', '-I${D_IMPORT_PATH}', '${DFLAGS}', '${_SOURCES}'], + } end - end - def run(target, sources, cache, env, vars) - vars = vars.merge({ - '_TARGET' => target, - '_SOURCES' => sources, - '_DEPFILE' => target.set_suffix('.mf'), - }) - com_prefix = KNOWN_SUFFIXES.find do |compiler, suffix_var| - sources.first.has_suffix?(env[suffix_var]) - end.tap do |v| - v.nil? and raise "Error: unknown input file type: #{sources.first.inspect}" - end.first - command = env.build_command(env["#{com_prefix}CMD"], vars) - unless cache.up_to_date?(target, command, sources, env) - cache.mkdir_p(File.dirname(target)) - FileUtils.rm_f(target) - return false unless env.execute("#{com_prefix} #{target}", command) - deps = sources - if File.exists?(vars['_DEPFILE']) - deps += Environment.parse_makefile_deps(vars['_DEPFILE'], target) - FileUtils.rm_f(vars['_DEPFILE']) + def produces?(target, source, env) + target.has_suffix?(env['OBJSUFFIX']) and KNOWN_SUFFIXES.find do |compiler, suffix_var| + source.has_suffix?(env[suffix_var]) end - cache.register_build(target, command, deps.uniq, env) end - target + + def run(target, sources, cache, env, vars) + vars = vars.merge({ + '_TARGET' => target, + '_SOURCES' => sources, + '_DEPFILE' => target.set_suffix('.mf'), + }) + com_prefix = KNOWN_SUFFIXES.find do |compiler, suffix_var| + sources.first.has_suffix?(env[suffix_var]) + end.tap do |v| + v.nil? and raise "Error: unknown input file type: #{sources.first.inspect}" + end.first + command = env.build_command(env["#{com_prefix}CMD"], vars) + unless cache.up_to_date?(target, command, sources, env) + cache.mkdir_p(File.dirname(target)) + FileUtils.rm_f(target) + return false unless env.execute("#{com_prefix} #{target}", command) + deps = sources + if File.exists?(vars['_DEPFILE']) + deps += Environment.parse_makefile_deps(vars['_DEPFILE'], target) + FileUtils.rm_f(vars['_DEPFILE']) + end + cache.register_build(target, command, deps.uniq, env) + end + target + end end end end diff --git a/lib/rscons/builders/program.rb b/lib/rscons/builders/program.rb index 850c80e..9ed50c3 100644 --- a/lib/rscons/builders/program.rb +++ b/lib/rscons/builders/program.rb @@ -1,39 +1,41 @@ module Rscons - # A default RScons builder that knows how to link object files into an - # executable program. - class Program < Builder - def default_variables(env) - { - 'LD' => nil, - 'OBJSUFFIX' => '.o', - 'LIBSUFFIX' => '.a', - 'LDFLAGS' => [], - 'LIBPATH' => [], - 'LIBS' => [], - 'LDCMD' => ['${LD}', '-o', '${_TARGET}', '${LDFLAGS}', '${_SOURCES}', '-L${LIBPATH}', '-l${LIBS}'] - } - end + module Builders + # A default RScons builder that knows how to link object files into an + # executable program. + class Rscons::Builders::Program < Rscons::Builder + def default_variables(env) + { + 'LD' => nil, + 'OBJSUFFIX' => '.o', + 'LIBSUFFIX' => '.a', + 'LDFLAGS' => [], + 'LIBPATH' => [], + 'LIBS' => [], + 'LDCMD' => ['${LD}', '-o', '${_TARGET}', '${LDFLAGS}', '${_SOURCES}', '-L${LIBPATH}', '-l${LIBS}'] + } + end - def run(target, sources, cache, env, vars) - # build sources to linkable objects - objects = env.build_sources(sources, [env['OBJSUFFIX'], env['LIBSUFFIX']].flatten, cache, vars) - return false unless objects - ld = if env["LD"] - env["LD"] - elsif sources.find {|s| s.has_suffix?(env["DSUFFIX"])} - env["DC"] - elsif sources.find {|s| s.has_suffix?(env["CXXSUFFIX"])} - env["CXX"] - else - env["CC"] - end - vars = vars.merge({ - '_TARGET' => target, - '_SOURCES' => objects, - 'LD' => ld, - }) - command = env.build_command(env['LDCMD'], vars) - standard_build("LD #{target}", target, command, objects, env, cache) + def run(target, sources, cache, env, vars) + # build sources to linkable objects + objects = env.build_sources(sources, [env['OBJSUFFIX'], env['LIBSUFFIX']].flatten, cache, vars) + return false unless objects + ld = if env["LD"] + env["LD"] + elsif sources.find {|s| s.has_suffix?(env["DSUFFIX"])} + env["DC"] + elsif sources.find {|s| s.has_suffix?(env["CXXSUFFIX"])} + env["CXX"] + else + env["CC"] + end + vars = vars.merge({ + '_TARGET' => target, + '_SOURCES' => objects, + 'LD' => ld, + }) + command = env.build_command(env['LDCMD'], vars) + standard_build("LD #{target}", target, command, objects, env, cache) + end end end end diff --git a/lib/rscons/environment.rb b/lib/rscons/environment.rb index 92e2d2e..871e1ea 100644 --- a/lib/rscons/environment.rb +++ b/lib/rscons/environment.rb @@ -34,7 +34,9 @@ module Rscons @build_dirs = [] @build_hooks = [] unless options[:exclude_builders] - DEFAULT_BUILDERS.each do |builder_class| + DEFAULT_BUILDERS.each do |builder_class_name| + builder_class = Builders.const_get(builder_class_name) + builder_class or raise "Could not find builder class #{builder_class_name}" add_builder(builder_class.new) end end diff --git a/spec/rscons/environment_spec.rb b/spec/rscons/environment_spec.rb index 3ca170a..03ad1d3 100644 --- a/spec/rscons/environment_spec.rb +++ b/spec/rscons/environment_spec.rb @@ -48,7 +48,7 @@ module Rscons it "adds the builder to the list of builders" do env = Environment.new(exclude_builders: true) env.builders.keys.should == [] - env.add_builder(Rscons::Object.new) + env.add_builder(Rscons::Builders::Object.new) env.builders.keys.should == ["Object"] end end