Compare commits

..
6 Commits
16 changed files with 134 additions and 22 deletions

No files matched your search

+1 -1
View File
@@ -1,5 +1,5 @@
class MySource < Rscons::Builder
def run(target, sources, cache, env)
def run(target, sources, cache, env, vars = {})
File.open(target, 'w') do |fh|
fh.puts <<EOF
#define THE_VALUE 5678
+4
View File
@@ -0,0 +1,4 @@
Rscons::Environment.new(echo: :command) do |env|
env.Program('library', ['lib.a', 'three.c'])
env.Library("lib.a", ['one.c', 'two.c'], 'CPPFLAGS' => ['-Dmake_lib'])
end
+8
View File
@@ -0,0 +1,8 @@
#include <stdio.h>
#ifdef make_lib
int main(int argc, char *argv[])
{
printf("Library\n");
}
#endif
View File
Whitespace-only changes.
View File
Whitespace-only changes.
+4
View File
@@ -0,0 +1,4 @@
Rscons::Environment.new(echo: :command) do |env|
env.Object("one.o", "one.c", 'CPPFLAGS' => ['-DONE'])
env.Program('two_sources', ['one.o', 'two.c'])
end
+8
View File
@@ -0,0 +1,8 @@
#include <stdio.h>
#ifdef ONE
int main(int argc, char *argv[])
{
printf("This is a C program with two sources.\n");
}
#endif
+3
View File
@@ -0,0 +1,3 @@
#ifdef ONE
#error ONE should not be defined
#endif
+2
View File
@@ -8,12 +8,14 @@ require "rscons/monkey/module"
require "rscons/monkey/string"
# default builders
require "rscons/builders/library"
require "rscons/builders/object"
require "rscons/builders/program"
# Namespace module for rscons classes
module Rscons
DEFAULT_BUILDERS = [
Library,
Object,
Program,
]
+33
View File
@@ -0,0 +1,33 @@
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' => [],
'ARCOM' => ['$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['ARCOM'], vars)
unless cache.up_to_date?(target, command, objects)
FileUtils.rm_f(target)
return false unless env.execute("AR #{target}", command)
cache.register_build(target, command, objects)
end
target
end
end
end
end
+3 -3
View File
@@ -38,12 +38,12 @@ module Rscons
source.has_suffix?(env['CXXSUFFIX']))
end
def run(target, sources, cache, env)
vars = {
def run(target, sources, cache, env, vars = {})
vars = vars.merge({
'TARGET' => target,
'SOURCES' => sources,
'DEPFILE' => target.set_suffix('.mf'),
}
})
com_prefix = if sources.first.has_suffix?(env['ASSUFFIX'])
'AS'
elsif sources.first.has_suffix?(env['CSUFFIX'])
+5 -14
View File
@@ -14,28 +14,19 @@ module Rscons
}
end
def run(target, sources, cache, env)
# convert sources to object file names
objects = sources.map do |source|
if source.has_suffix?([env['OBJSUFFIX'], env['LIBSUFFIX']])
source
else
o_file = env.get_build_fname(source, env['OBJSUFFIX', :string])
builder = env.builders.values.find { |b| b.produces?(o_file, source, env) }
builder or raise "No builder found to convert input source #{source.inspect} to an object file."
builder.run(o_file, [source], cache, env) or break
end
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
use_cxx = sources.map do |s|
s.has_suffix?(env['CXXSUFFIX'])
end.any?
ld_alt = use_cxx ? env['CXX'] : env['CC']
vars = {
vars = vars.merge({
'TARGET' => target,
'SOURCES' => objects,
'LD' => env['LD'] || ld_alt,
}
})
command = env.build_command(env['LDCOM'], vars)
unless cache.up_to_date?(target, command, objects)
return false unless env.execute("LD #{target}", command)
+34 -2
View File
@@ -141,7 +141,7 @@ module Rscons
@targets[target][:source],
cache,
self,
*@targets[target][:args])
@targets[target][:vars] || {})
else
false
end
@@ -149,6 +149,7 @@ module Rscons
@targets.each do |target, info|
next if targets_processed.include?(target)
unless process_target.call(target)
cache.write
raise BuildError.new("Failed to build #{target}")
end
end
@@ -192,11 +193,15 @@ module Rscons
alias_method :orig_method_missing, :method_missing
def method_missing(method, *args)
if @builders.has_key?(method.to_s)
target, source, *rest = args
target, source, vars, *rest = args
unless vars.nil? or vars.is_a?(Hash) or vars.is_a?(VarSet)
raise "Unexpected construction variable set: #{vars.inspect}"
end
source = [source] unless source.is_a?(Array)
@targets[target] = {
builder: @builders[method.to_s],
source: source,
vars: vars,
args: rest,
}
else
@@ -227,5 +232,32 @@ module Rscons
end
deps
end
# Build a list of source files into files containing one of the suffixes
# given by suffixes.
# This method is used internally by RScons builders.
# @param sources [Array] List of source files to build.
# @param suffixes [Array] List of suffixes to try to convert source files into.
# @param cache [Cache] The Cache.
# Return a list of the converted file names.
def build_sources(sources, suffixes, cache, vars = {})
sources.map do |source|
if source.has_suffix?(suffixes)
source
else
converted = nil
suffixes.each do |suffix|
converted_fname = get_build_fname(source, suffix)
builder = @builders.values.find { |b| b.produces?(converted_fname, source, self) }
if builder
converted = builder.run(converted_fname, [source], cache, self, vars)
return nil unless converted
break
end
end
converted or raise "Could not find a builder to handle #{source.inspect}."
end
end
end
end
end
+5 -1
View File
@@ -8,7 +8,11 @@ module Rscons
# Create a VarSet
# @param vars [Hash] Optional initial variables.
def initialize(vars = {})
@vars = vars
if vars.is_a?(VarSet)
@vars = vars.clone.vars
else
@vars = vars
end
end
# Access the value of variable as a particular type
+1 -1
View File
@@ -1,4 +1,4 @@
module Rscons
# gem version
VERSION = "0.0.4"
VERSION = "0.0.6"
end
+23
View File
@@ -143,4 +143,27 @@ describe Rscons do
`./simple`.should == "This is a simple C++ program\n"
end
it 'allows overriding construction variables for individual builder calls' do
lines = test_dir('two_sources')
lines.should == [
'gcc -c -o one.o -MMD -MF one.mf -DONE one.c',
'gcc -c -o two.o -MMD -MF two.mf two.c',
'gcc -o two_sources one.o two.o',
]
File.exists?('two_sources').should be_true
`./two_sources`.should == "This is a C program with two sources.\n"
end
it 'builds a static library archive' do
lines = test_dir('library')
lines.should == [
'gcc -c -o one.o -MMD -MF one.mf -Dmake_lib one.c',
'gcc -c -o two.o -MMD -MF two.mf -Dmake_lib two.c',
'ar rcs lib.a one.o two.o',
'gcc -c -o three.o -MMD -MF three.mf three.c',
'gcc -o library lib.a three.o',
]
File.exists?('library').should be_true
`ar t lib.a`.should == "one.o\ntwo.o\n"
end
end