add CFile builder to create C/C++ sources from lex/yacc input files

This commit is contained in:
Josh Holtrop 2014-03-18 21:57:53 -04:00
parent 831b9bf2c7
commit 533ee9c16c
3 changed files with 65 additions and 0 deletions

View File

@ -5,6 +5,7 @@ require_relative "rscons/varset"
require_relative "rscons/version" require_relative "rscons/version"
# default builders # default builders
require_relative "rscons/builders/cfile"
require_relative "rscons/builders/library" require_relative "rscons/builders/library"
require_relative "rscons/builders/object" require_relative "rscons/builders/object"
require_relative "rscons/builders/program" require_relative "rscons/builders/program"
@ -12,6 +13,7 @@ require_relative "rscons/builders/program"
# Namespace module for rscons classes # Namespace module for rscons classes
module Rscons module Rscons
DEFAULT_BUILDERS = [ DEFAULT_BUILDERS = [
:CFile,
:Library, :Library,
:Object, :Object,
:Program, :Program,

View File

@ -0,0 +1,40 @@
module Rscons
module Builders
# Build a C or C++ source file given a lex (.l, .ll) or yacc (.y, .yy)
# input file.
#
# Examples::
# env.CFile("parser.tab.cc", "parser.yy")
# env.CFile("lex.yy.cc", "parser.ll")
class CFile < Builder
def default_variables(env)
{
"YACC" => "bison",
"YACC_FLAGS" => ["-d"],
"YACC_CMD" => ["${YACC}", "${YACC_FLAGS}", "-o", "${_TARGET}", "${_SOURCES}"],
"LEX" => "flex",
"LEX_FLAGS" => [],
"LEX_CMD" => ["${LEX}", "${LEX_FLAGS}", "-o", "${_TARGET}", "${_SOURCES}"],
}
end
def run(target, sources, cache, env, vars)
vars = vars.merge({
"_TARGET" => target,
"_SOURCES" => sources,
})
cmd =
case
when sources.first.end_with?(".l", ".ll")
"LEX"
when sources.first.end_with?(".y", ".yy")
"YACC"
else
raise "Unknown source file #{sources.first.inspect} for CFile builder"
end
command = env.build_command(env["#{cmd}_CMD"], vars)
standard_build("#{cmd} #{target}", target, command, sources, env, cache)
end
end
end
end

View File

@ -0,0 +1,23 @@
module Rscons
module Builders
describe CFile do
let(:env) {Environment.new}
subject {CFile.new}
it "invokes bison to create a .c file from a .y file" do
subject.should_receive(:standard_build).with("YACC parser.c", "parser.c", ["bison", "-d", "-o", "parser.c", "parser.y"], ["parser.y"], env, :cache)
subject.run("parser.c", ["parser.y"], :cache, env, {})
end
it "invokes a custom lexer to create a .cc file from a .ll file" do
env["LEX"] = "custom_lex"
subject.should_receive(:standard_build).with("LEX lexer.cc", "lexer.cc", ["custom_lex", "-o", "lexer.cc", "parser.ll"], ["parser.ll"], env, :cache)
subject.run("lexer.cc", ["parser.ll"], :cache, env, {})
end
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/
end
end
end
end