Compare commits

...
5 Commits
18 changed files with 149 additions and 39 deletions

No files matched your search

+5
View File
@@ -329,6 +329,11 @@ http://rubydoc.info/github/holtrop/rscons/frames.
## Release Notes ## Release Notes
### v1.4.3
- fix builders properly using construction variable overrides
- expand nil construction variables to empty strings
### v1.4.2 ### v1.4.2
- add Environment#expand_path - add Environment#expand_path
+1 -1
View File
@@ -32,7 +32,7 @@ module Rscons
else else
raise "Unknown source file #{sources.first.inspect} for CFile builder" raise "Unknown source file #{sources.first.inspect} for CFile builder"
end end
command = env.build_command(env["#{cmd}_CMD"], vars) command = env.build_command("${#{cmd}_CMD}", vars)
standard_build("#{cmd} #{target}", target, command, sources, env, cache) standard_build("#{cmd} #{target}", target, command, sources, env, cache)
end end
end end
+1 -1
View File
@@ -12,7 +12,7 @@ module Rscons
def run(target, sources, cache, env, vars) def run(target, sources, cache, env, vars)
vars = vars.merge("_SOURCES" => sources) vars = vars.merge("_SOURCES" => sources)
command = env.build_command(env["DISASM_CMD"], vars) command = env.build_command("${DISASM_CMD}", vars)
unless cache.up_to_date?(target, command, sources, env) unless cache.up_to_date?(target, command, sources, env)
cache.mkdir_p(File.dirname(target)) cache.mkdir_p(File.dirname(target))
return false unless env.execute("Disassemble #{target}", command, options: {out: target}) return false unless env.execute("Disassemble #{target}", command, options: {out: target})
+2 -2
View File
@@ -13,13 +13,13 @@ module Rscons
def run(target, sources, cache, env, vars) def run(target, sources, cache, env, vars)
# build sources to linkable objects # build sources to linkable objects
objects = env.build_sources(sources, [env['OBJSUFFIX'], env['LIBSUFFIX']].flatten, cache, vars) objects = env.build_sources(sources, env.expand_varref(["${OBJSUFFIX}", "${LIBSUFFIX}"], vars).flatten, cache, vars)
if objects if objects
vars = vars.merge({ vars = vars.merge({
'_TARGET' => target, '_TARGET' => target,
'_SOURCES' => objects, '_SOURCES' => objects,
}) })
command = env.build_command(env['ARCMD'], vars) command = env.build_command("${ARCMD}", vars)
standard_build("AR #{target}", target, command, objects, env, cache) standard_build("AR #{target}", target, command, objects, env, cache)
end end
end end
+2 -2
View File
@@ -58,11 +58,11 @@ module Rscons
'_DEPFILE' => Rscons.set_suffix(target, '.mf'), '_DEPFILE' => Rscons.set_suffix(target, '.mf'),
}) })
com_prefix = KNOWN_SUFFIXES.find do |compiler, suffix_var| com_prefix = KNOWN_SUFFIXES.find do |compiler, suffix_var|
sources.first.end_with?(*env[suffix_var]) sources.first.end_with?(*env.expand_varref("${#{suffix_var}}"))
end.tap do |v| 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 end.first
command = env.build_command(env["#{com_prefix}CMD"], vars) command = env.build_command("${#{com_prefix}CMD}", vars)
unless cache.up_to_date?(target, command, sources, env) unless cache.up_to_date?(target, command, sources, env)
cache.mkdir_p(File.dirname(target)) cache.mkdir_p(File.dirname(target))
FileUtils.rm_f(target) FileUtils.rm_f(target)
+4 -4
View File
@@ -9,15 +9,15 @@ module Rscons
end end
def run(target, sources, cache, env, vars) def run(target, sources, cache, env, vars)
pp_cc = if sources.find {|s| s.end_with?(*env["CXXSUFFIX"])} pp_cc = if sources.find {|s| s.end_with?(*env.expand_varref("${CXXSUFFIX}", vars))}
env["CXX"] "${CXX}"
else else
env["CC"] "${CC}"
end end
vars = vars.merge("_PREPROCESS_CC" => pp_cc, vars = vars.merge("_PREPROCESS_CC" => pp_cc,
"_TARGET" => target, "_TARGET" => target,
"_SOURCES" => sources) "_SOURCES" => sources)
command = env.build_command(env["CPP_CMD"], vars) command = env.build_command("${CPP_CMD}", vars)
standard_build("Preprocess #{target}", target, command, sources, env, cache) standard_build("Preprocess #{target}", target, command, sources, env, cache)
end end
end end
+10 -9
View File
@@ -17,23 +17,24 @@ module Rscons
def run(target, sources, cache, env, vars) def run(target, sources, cache, env, vars)
# build sources to linkable objects # build sources to linkable objects
objects = env.build_sources(sources, [env['OBJSUFFIX'], env['LIBSUFFIX']].flatten, cache, vars) objects = env.build_sources(sources, env.expand_varref(["${OBJSUFFIX}", "${LIBSUFFIX}"], vars).flatten, cache, vars)
return false unless objects return false unless objects
ld = if env["LD"] ld = env.expand_varref("${LD}", vars)
env["LD"] ld = if ld != ""
elsif sources.find {|s| s.end_with?(*env["DSUFFIX"])} ld
env["DC"] elsif sources.find {|s| s.end_with?(*env.expand_varref("${DSUFFIX}", vars))}
elsif sources.find {|s| s.end_with?(*env["CXXSUFFIX"])} "${DC}"
env["CXX"] elsif sources.find {|s| s.end_with?(*env.expand_varref("${CXXSUFFIX}", vars))}
"${CXX}"
else else
env["CC"] "${CC}"
end end
vars = vars.merge({ vars = vars.merge({
'_TARGET' => target, '_TARGET' => target,
'_SOURCES' => objects, '_SOURCES' => objects,
'LD' => ld, 'LD' => ld,
}) })
command = env.build_command(env['LDCMD'], vars) command = env.build_command("${LDCMD}", vars)
standard_build("LD #{target}", target, command, objects, env, cache) standard_build("LD #{target}", target, command, objects, env, cache)
end end
end end
+15 -15
View File
@@ -209,22 +209,22 @@ module Rscons
@targets = {} @targets = {}
end end
# Build a command line from the given template, resolving references to # Expand a construction variable reference.
# variables using the Environment's construction variables and any extra #
# variables specified. # @param varref [Array, String] Variable reference to expand.
# @param command_template [Array] template for the command with variable # @param extra_vars [Hash, VarSet]
# references # Extra variables to use in addition to (or replace) the Environment's
# @param extra_vars [Hash, VarSet] extra variables to use in addition to # construction variables when expanding the variable reference.
# (or replace) the Environment's construction variables when building #
# the command # @return [Array, String] Expansion of the variable reference.
def build_command(command_template, extra_vars) def expand_varref(varref, extra_vars = nil)
@varset.merge(extra_vars).expand_varref(command_template) if extra_vars.nil?
end @varset
else
# Expand a construction variable reference (String or Array) @varset.merge(extra_vars)
def expand_varref(varref) end.expand_varref(varref)
@varset.expand_varref(varref)
end end
alias_method :build_command, :expand_varref
# Execute a builder command # Execute a builder command
# @param short_desc [String] Message to print if the Environment's echo # @param short_desc [String] Message to print if the Environment's echo
+1 -1
View File
@@ -83,7 +83,7 @@ module Rscons
if varref =~ /^(.*)\$\{([^}]+)\}(.*)$/ if varref =~ /^(.*)\$\{([^}]+)\}(.*)$/
prefix, varname, suffix = $1, $2, $3 prefix, varname, suffix = $1, $2, $3
varval = expand_varref(self[varname]) varval = expand_varref(self[varname])
if varval.is_a?(String) if varval.is_a?(String) or varval.nil?
expand_varref("#{prefix}#{varval}#{suffix}") expand_varref("#{prefix}#{varval}#{suffix}")
elsif varval.is_a?(Array) elsif varval.is_a?(Array)
varval.map {|vv| expand_varref("#{prefix}#{vv}#{suffix}")}.flatten varval.map {|vv| expand_varref("#{prefix}#{vv}#{suffix}")}.flatten
+1 -1
View File
@@ -1,4 +1,4 @@
module Rscons module Rscons
# gem version # gem version
VERSION = "1.4.2" VERSION = "1.4.3"
end end
+5
View File
@@ -15,6 +15,11 @@ module Rscons
subject.run("lexer.cc", ["parser.ll"], :cache, env, {}) subject.run("lexer.cc", ["parser.ll"], :cache, env, {})
end end
it "supports overriding construction variables" do
subject.should_receive(:standard_build).with("LEX lexer.c", "lexer.c", ["hi", "parser.l"], ["parser.l"], env, :cache)
subject.run("lexer.c", ["parser.l"], :cache, env, "LEX_CMD" => ["hi", "${_SOURCES}"])
end
it "raises an error when an unknown source file is specified" do it "raises an error when an unknown source file is specified" do
expect {subject.run("file.c", ["foo.bar"], :cache, env, {})}.to raise_error /Unknown source file .foo.bar. for CFile builder/ expect {subject.run("file.c", ["foo.bar"], :cache, env, {})}.to raise_error /Unknown source file .foo.bar. for CFile builder/
end end
+17
View File
@@ -0,0 +1,17 @@
module Rscons
module Builders
describe Disassemble do
let(:env) {Environment.new}
subject {Disassemble.new}
it "supports overriding DISASM_CMD construction variable" do
cache = "cache"
cache.stub(:up_to_date?) { false }
cache.stub(:mkdir_p) { }
cache.stub(:register_build) { }
env.should_receive(:execute).with("Disassemble a_file.txt", ["my_disasm", "a_file.exe"], anything).and_return(true)
subject.run("a_file.txt", ["a_file.exe"], cache, env, "DISASM_CMD" => ["my_disasm", "${_SOURCES}"])
end
end
end
end
+18
View File
@@ -0,0 +1,18 @@
module Rscons
module Builders
describe Library do
let(:env) {Environment.new}
subject {Library.new}
it "supports overriding AR construction variable" do
subject.should_receive(:standard_build).with("AR prog.a", "prog.a", ["sp-ar", "rcs", "prog.a", "prog.o"], ["prog.o"], env, :cache)
subject.run("prog.a", ["prog.o"], :cache, env, "AR" => "sp-ar")
end
it "supports overriding ARCMD construction variable" do
subject.should_receive(:standard_build).with("AR prog.a", "prog.a", ["special", "AR!", "prog.o"], ["prog.o"], env, :cache)
subject.run("prog.a", ["prog.o"], :cache, env, "ARCMD" => ["special", "AR!", "${_SOURCES}"])
end
end
end
end
+23
View File
@@ -0,0 +1,23 @@
module Rscons
module Builders
describe Object do
let(:env) {Environment.new}
subject {Object.new}
it "supports overriding CCCMD construction variable" do
cache = "cache"
cache.stub(:up_to_date?) { false }
cache.stub(:mkdir_p) { }
cache.stub(:register_build) { }
FileUtils.stub(:rm_f) { }
File.stub(:exists?) { false }
env.should_receive(:execute).with("CC mod.o", ["llc", "mod.c"]).and_return(true)
subject.run("mod.o", ["mod.c"], cache, env, "CCCMD" => ["llc", "${_SOURCES}"])
end
it "raises an error when given a source file with an unknown suffix" do
expect { subject.run("mod.o", ["mod.xyz"], :cache, env, {}) }.to raise_error /unknown input file type: "mod.xyz"/
end
end
end
end
+18
View File
@@ -0,0 +1,18 @@
module Rscons
module Builders
describe Preprocess do
let(:env) {Environment.new}
subject {Preprocess.new}
it "supports overriding CC construction variable" do
subject.should_receive(:standard_build).with("Preprocess module.pp", "module.pp", ["my_cpp", "-E", "-o", "module.pp", "module.c"], ["module.c"], env, :cache)
subject.run("module.pp", ["module.c"], :cache, env, "CC" => "my_cpp")
end
it "supports overriding CPP_CMD construction variable" do
subject.should_receive(:standard_build).with("Preprocess module.pp", "module.pp", ["my_cpp", "module.c"], ["module.c"], env, :cache)
subject.run("module.pp", ["module.c"], :cache, env, "CPP_CMD" => ["my_cpp", "${_SOURCES}"])
end
end
end
end
+18
View File
@@ -0,0 +1,18 @@
module Rscons
module Builders
describe Program do
let(:env) {Environment.new}
subject {Program.new}
it "supports overriding CC construction variable" do
subject.should_receive(:standard_build).with("LD prog", "prog", ["sp-c++", "-o", "prog", "prog.o"], ["prog.o"], env, :cache)
subject.run("prog", ["prog.o"], :cache, env, "CC" => "sp-c++")
end
it "supports overriding LDCMD construction variable" do
subject.should_receive(:standard_build).with("LD prog", "prog", ["special", "LD!", "prog.o"], ["prog.o"], env, :cache)
subject.run("prog", ["prog.o"], :cache, env, "LDCMD" => ["special", "LD!", "${_SOURCES}"])
end
end
end
end
+1
View File
@@ -223,6 +223,7 @@ module Rscons
env["path"] = ["dir1", "dir2"] env["path"] = ["dir1", "dir2"]
env["flags"] = ["-x", "-y", "${specialflag}"] env["flags"] = ["-x", "-y", "${specialflag}"]
env["specialflag"] = "-z" env["specialflag"] = "-z"
env["foo"] = {}
env.expand_varref(["-p${path}", "${flags}"]).should == ["-pdir1", "-pdir2", "-x", "-y", "-z"] env.expand_varref(["-p${path}", "${flags}"]).should == ["-pdir1", "-pdir2", "-x", "-y", "-z"]
env.expand_varref("foo").should == "foo" env.expand_varref("foo").should == "foo"
expect {env.expand_varref("${foo}")}.to raise_error /expand.a.variable.reference/ expect {env.expand_varref("${foo}")}.to raise_error /expand.a.variable.reference/
+7 -3
View File
@@ -125,7 +125,8 @@ module Rscons
"CC" => "gcc", "CC" => "gcc",
"CPPPATH" => ["dir1", "dir2"], "CPPPATH" => ["dir1", "dir2"],
"compiler" => "${CC}", "compiler" => "${CC}",
"cmd" => ["${CC}", "-c", "${CFLAGS}", "-I${CPPPATH}"]) "cmd" => ["${CC}", "-c", "${CFLAGS}", "-I${CPPPATH}"],
"hash" => {})
it "expands to the string itself if the string is not a variable reference" do it "expands to the string itself if the string is not a variable reference" do
v.expand_varref("CC").should == "CC" v.expand_varref("CC").should == "CC"
v.expand_varref("CPPPATH").should == "CPPPATH" v.expand_varref("CPPPATH").should == "CPPPATH"
@@ -151,8 +152,11 @@ module Rscons
"cflag: -O2, cpppath: dir2, compiler: gcc", "cflag: -O2, cpppath: dir2, compiler: gcc",
] ]
end end
it "raises an error when a variable reference refers to a non-existent variable" do it "returns an empty string when a variable reference refers to a non-existent variable" do
expect { v.expand_varref("${not_here}") }.to raise_error /I do not know how to expand a variable reference to a NilClass/ expect(v.expand_varref("${not_here}")).to eq("")
end
it "raises an error when a variable reference refers to an unhandled type" do
expect { v.expand_varref("${hash}") }.to raise_error /I do not know how to expand a variable reference to a Hash/
end end
end end
end end