build object files for sources

This commit is contained in:
Josh Holtrop 2013-06-17 21:57:34 -04:00
parent 0752765c8d
commit 488b754f4d
5 changed files with 46 additions and 2 deletions

View File

@ -1,5 +1,6 @@
it 'builds a C program with one source file' do it 'builds a C program with one source file' do
env = Rscons::Environment.new env = Rscons::Environment.new
env.Program('simple', 'simple.c') env.Program('simple', 'simple.c')
File.exist?('simple.o').should be_true
`./simple`.should =~ /This is a simple C program/ `./simple`.should =~ /This is a simple C program/
end end

View File

@ -1,4 +1,7 @@
module Rscons module Rscons
class Builder class Builder
def self.makes_object_file?(env, fname)
false
end
end end
end end

View File

@ -2,12 +2,30 @@ module Rscons
class CC < Builder class CC < Builder
VARIABLE_DEFAULTS = { VARIABLE_DEFAULTS = {
'CC' => 'gcc', 'CC' => 'gcc',
'CFLAGS' => [], 'CFLAGS' => ['-c'],
'CPPFLAGS' => [], 'CPPFLAGS' => [],
'OBJSUFFIX' => '.o', 'OBJSUFFIX' => '.o',
'CEXTS' => ['.c'],
} }
def run(env, target, sources) def self.makes_object_file?(env, fname)
env['CEXTS'].find do |cext|
fname =~ /#{cext}$/
end
end
def run(env, target, source)
raise "String expected, not #{source.inspect}" unless source.is_a?(String)
o_file = "#{env.stem(source)}#{env['OBJSUFFIX']}"
command = [
env['CC'],
*env['CPPFLAGS'],
*env['CFLAGS'],
'-o', o_file,
source
]
env.execute("CC #{o_file}", command)
o_file
end end
end end
end end

View File

@ -10,6 +10,20 @@ module Rscons
} }
def run(env, target, sources) def run(env, target, sources)
sources = [sources] if sources.is_a?(String)
sources = sources.map do |source|
if source =~ /#{env['OBJSUFFIX']}$/ or source =~ /#{env['LIBSUFFIX']}$/
source
else
builder_class = env.builders.values.find { |klass| klass.makes_object_file?(env, source) }
if builder_class
builder = builder_class.new
builder.run(env, env.stem(source) + env['OBJSUFFIX'], source)
else
raise "No builder found to convert input source #{source.inspect} to an object file."
end
end
end
command = [ command = [
env['LD'] || env['CC'], env['LD'] || env['CC'],
'-o', target, '-o', target,
@ -19,6 +33,7 @@ module Rscons
*env['LIBS'].map {|lib| "-l#{lib}"} *env['LIBS'].map {|lib| "-l#{lib}"}
] ]
env.execute("LINK #{target}", command) env.execute("LINK #{target}", command)
target
end end
end end
end end

View File

@ -7,6 +7,9 @@ module Rscons
# :command (default) - print the full command being executed # :command (default) - print the full command being executed
attr_accessor :echo attr_accessor :echo
# Hash of Builder Name => Builder Class
attr_reader :builders
def initialize(options = {}) def initialize(options = {})
@echo = :command @echo = :command
@variables = options.reject { |key, val| not key[0] =~ /[A-Z]/ } @variables = options.reject { |key, val| not key[0] =~ /[A-Z]/ }
@ -53,6 +56,10 @@ module Rscons
system(*command) system(*command)
end end
def stem(fname)
fname.sub(/\.[^.]*$/, '')
end
def method_missing(method, *args) def method_missing(method, *args)
if @builders.has_key?(method.to_s) if @builders.has_key?(method.to_s)
# TODO: build sources if necessary # TODO: build sources if necessary