Replace CFile builder with Yacc and Lex builders - close #166
This commit is contained in:
parent
d4ec07dd7a
commit
ed7408367f
@ -1,4 +0,0 @@
|
||||
env do |env|
|
||||
env.CFile("lexer.c", "lexer.l")
|
||||
env.CFile("parser.c", "parser.y")
|
||||
end
|
||||
@ -1,3 +0,0 @@
|
||||
env do |env|
|
||||
env.CFile("file.c", "foo.bar")
|
||||
end
|
||||
4
build_tests/lex_yacc/Rsconscript
Normal file
4
build_tests/lex_yacc/Rsconscript
Normal file
@ -0,0 +1,4 @@
|
||||
env do |env|
|
||||
env.Lex("lexer.c", "lexer.l")
|
||||
env.Yacc("parser.c", "parser.y")
|
||||
end
|
||||
@ -925,11 +925,11 @@ There are several default builders that are built-in to Rscons:
|
||||
|
||||
* `Command`, which executes a user-defined command to produce the target.
|
||||
* `Copy`, which copies files or directories to a specified destination.
|
||||
* `CFile`, which builds a C or C++ source file from a lex or yacc input file.
|
||||
* `Directory`, which creates a directory.
|
||||
* `Disassemble`, which disassembles an object file to a disassembly listing.
|
||||
* `Install`, which installs files or directories to a specified destination.
|
||||
* `InstallDirectory`, which creates a directory in an install destination.
|
||||
* `Lex`, which builds a source file from a lex input file.
|
||||
* `Library`, which collects object files into a static library archive file.
|
||||
* `Object`, which compiles source files to produce an object file.
|
||||
* `Preprocess`, which invokes the C/C++ preprocessor on a source file.
|
||||
@ -939,6 +939,7 @@ There are several default builders that are built-in to Rscons:
|
||||
* `SharedObject`, which compiles source files to produce an object file, in a
|
||||
way that is able to be used to create a shared library.
|
||||
* `Size`, which runs the 'size' utility on an executable file.
|
||||
* `Yacc`, which builds a source file from a yacc input file.
|
||||
|
||||
####> The Command Builder
|
||||
|
||||
@ -965,17 +966,6 @@ The `Command` builder supports the following construction variables:
|
||||
`CMD_STDOUT` is expanded for variable references, so the token `${_TARGET}`
|
||||
can be used, for example.
|
||||
|
||||
####> The CFile Builder
|
||||
|
||||
```ruby
|
||||
env.CFile(target, source)
|
||||
# Example
|
||||
env.CFile("^/parser/parser.c", "parser.y")
|
||||
```
|
||||
|
||||
The `CFile` builder will generate a C or C++ source file from a lex (.l, .ll)
|
||||
or yacc (.y, .yy) input file.
|
||||
|
||||
####> The Copy Builder
|
||||
|
||||
```ruby
|
||||
@ -1048,6 +1038,17 @@ the `InstallDirectory` builder.
|
||||
The `uninstall` task removes targets created by the `InstallDirectory` builder
|
||||
but not by the `Directory` builder.
|
||||
|
||||
####> The Lex Builder
|
||||
|
||||
```ruby
|
||||
env.Lex(target, source)
|
||||
# Example
|
||||
env.Lex("^/lexer.c", "lexer.l")
|
||||
```
|
||||
|
||||
The `Lex` builder will generate a source file from a lex (.l, .ll)
|
||||
input file.
|
||||
|
||||
####> The Library Builder
|
||||
|
||||
```ruby
|
||||
@ -1178,6 +1179,17 @@ stores its output in the target file.
|
||||
The size executable can be specified with the `SIZE` construction variable,
|
||||
and flags can be specified with `SIZEFLAGS`.
|
||||
|
||||
####> The Yacc Builder
|
||||
|
||||
```ruby
|
||||
env.Yacc(target, source)
|
||||
# Example
|
||||
env.Yacc("^/parser.c", "parser.y")
|
||||
```
|
||||
|
||||
The `Yacc` builder will generate a source file from a yacc (.y, .yy)
|
||||
input file.
|
||||
|
||||
###> Phony Targets
|
||||
|
||||
Rscons supports phony build targets.
|
||||
@ -1959,7 +1971,7 @@ end
|
||||
|
||||
```ruby
|
||||
env do |env|
|
||||
env.CFile("^/parser.tab.cc", "parser.yy")
|
||||
env.Yacc("^/parser.tab.cc", "parser.yy")
|
||||
end
|
||||
```
|
||||
|
||||
|
||||
@ -23,13 +23,13 @@ module Rscons
|
||||
# Names of the default builders which will be added to all newly created
|
||||
# {Environment} objects.
|
||||
DEFAULT_BUILDERS = [
|
||||
:CFile,
|
||||
:Command,
|
||||
:Copy,
|
||||
:Directory,
|
||||
:Disassemble,
|
||||
:Install,
|
||||
:InstallDirectory,
|
||||
:Lex,
|
||||
:Library,
|
||||
:Object,
|
||||
:Preprocess,
|
||||
@ -37,6 +37,7 @@ module Rscons
|
||||
:SharedLibrary,
|
||||
:SharedObject,
|
||||
:Size,
|
||||
:Yacc,
|
||||
]
|
||||
|
||||
# Class to represent a fatal error during an Rscons operation.
|
||||
@ -135,11 +136,11 @@ require_relative "rscons/builders/mixins/object_deps"
|
||||
require_relative "rscons/builders/mixins/program"
|
||||
|
||||
# default builders
|
||||
require_relative "rscons/builders/cfile"
|
||||
require_relative "rscons/builders/command"
|
||||
require_relative "rscons/builders/copy"
|
||||
require_relative "rscons/builders/directory"
|
||||
require_relative "rscons/builders/disassemble"
|
||||
require_relative "rscons/builders/lex"
|
||||
require_relative "rscons/builders/library"
|
||||
require_relative "rscons/builders/object"
|
||||
require_relative "rscons/builders/preprocess"
|
||||
@ -148,6 +149,7 @@ require_relative "rscons/builders/shared_library"
|
||||
require_relative "rscons/builders/shared_object"
|
||||
require_relative "rscons/builders/simple_builder"
|
||||
require_relative "rscons/builders/size"
|
||||
require_relative "rscons/builders/yacc"
|
||||
|
||||
# language support
|
||||
require_relative "rscons/builders/lang/asm"
|
||||
|
||||
@ -1,35 +0,0 @@
|
||||
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
|
||||
|
||||
# Run the builder to produce a build target.
|
||||
def run(options)
|
||||
if @command
|
||||
finalize_command
|
||||
else
|
||||
@vars["_TARGET"] = @target
|
||||
@vars["_SOURCES"] = @sources
|
||||
case
|
||||
when @sources.first.end_with?(*@env.expand_varref("${LEXSUFFIX}"))
|
||||
cmd = "LEX"
|
||||
message = "Generating lexer"
|
||||
when @sources.first.end_with?(*@env.expand_varref("${YACCSUFFIX}"))
|
||||
cmd = "YACC"
|
||||
message = "Generating parser"
|
||||
else
|
||||
raise "Unknown source file #{@sources.first.inspect} for CFile builder"
|
||||
end
|
||||
command = @env.build_command("${#{cmd}_CMD}", @vars)
|
||||
standard_command("#{message} from <source>#{Util.short_format_paths(@sources)}<reset> => <target>#{@target}<reset>", command)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
24
lib/rscons/builders/lex.rb
Normal file
24
lib/rscons/builders/lex.rb
Normal file
@ -0,0 +1,24 @@
|
||||
module Rscons
|
||||
module Builders
|
||||
# Build a source file given a lex input file.
|
||||
#
|
||||
# Examples::
|
||||
# env.Lex("lex.c", "parser.l")
|
||||
# env.Lex("lex.cc", "parser.ll")
|
||||
class Lex < Builder
|
||||
|
||||
# Run the builder to produce a build target.
|
||||
def run(options)
|
||||
if @command
|
||||
finalize_command
|
||||
else
|
||||
@vars["_TARGET"] = @target
|
||||
@vars["_SOURCES"] = @sources
|
||||
command = @env.build_command("${LEX_CMD}", @vars)
|
||||
standard_command("Generating lexer source from <source>#{Util.short_format_paths(@sources)}<reset> => <target>#{@target}<reset>", command)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
24
lib/rscons/builders/yacc.rb
Normal file
24
lib/rscons/builders/yacc.rb
Normal file
@ -0,0 +1,24 @@
|
||||
module Rscons
|
||||
module Builders
|
||||
# Build a source file given a yacc input file.
|
||||
#
|
||||
# Examples::
|
||||
# env.Yacc("parser.c", "parser.y")
|
||||
# env.Yacc("parser.cc", "parser.yy")
|
||||
class Yacc < Builder
|
||||
|
||||
# Run the builder to produce a build target.
|
||||
def run(options)
|
||||
if @command
|
||||
finalize_command
|
||||
else
|
||||
@vars["_TARGET"] = @target
|
||||
@vars["_SOURCES"] = @sources
|
||||
command = @env.build_command("${YACC_CMD}", @vars)
|
||||
standard_command("Generating parser source from <source>#{Util.short_format_paths(@sources)}<reset> => <target>#{@target}<reset>", command)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -49,7 +49,6 @@ module Rscons
|
||||
"LDCMD" => %w[${LD} -o ${_TARGET} ${LDFLAGS} ${_SOURCES} ${LIBDIRPREFIX}${LIBPATH} ${LIBLINKPREFIX}${LIBS}],
|
||||
"LDFLAGS" => [],
|
||||
"LEX" => "flex",
|
||||
"LEXSUFFIX" => %w[.l .ll],
|
||||
"LEX_CMD" => %w[${LEX} ${LEX_FLAGS} -o ${_TARGET} ${_SOURCES}],
|
||||
"LEX_FLAGS" => [],
|
||||
"LIBDIRPREFIX" => "-L",
|
||||
@ -84,7 +83,6 @@ module Rscons
|
||||
"SIZECMD" => %w[${SIZE} ${SIZEFLAGS} ${_SOURCES}],
|
||||
"SIZEFLAGS" => [],
|
||||
"YACC" => "bison",
|
||||
"YACCSUFFIX" => %w[.y .yy],
|
||||
"YACC_CMD" => %w[${YACC} ${YACC_FLAGS} -o ${_TARGET} ${_SOURCES}],
|
||||
"YACC_FLAGS" => %w[-d],
|
||||
}
|
||||
|
||||
@ -1163,28 +1163,21 @@ EOF
|
||||
end
|
||||
end
|
||||
|
||||
context "CFile builder" do
|
||||
it "builds a .c file using flex and bison" do
|
||||
test_dir("cfile")
|
||||
context "Lex and Yacc builders" do
|
||||
it "builds C files using flex and bison" do
|
||||
test_dir("lex_yacc")
|
||||
|
||||
result = run_rscons
|
||||
expect(result.stderr).to eq ""
|
||||
verify_lines(lines(result.stdout), [
|
||||
%r{Generating lexer from lexer.l => lexer.c},
|
||||
%r{Generating parser from parser.y => parser.c},
|
||||
%r{Generating lexer source from lexer.l => lexer.c},
|
||||
%r{Generating parser source from parser.y => parser.c},
|
||||
])
|
||||
|
||||
result = run_rscons
|
||||
expect(result.stderr).to eq ""
|
||||
expect(result.stdout).to eq ""
|
||||
end
|
||||
|
||||
it "raises an error when an unknown source file is specified" do
|
||||
test_dir("cfile")
|
||||
result = run_rscons(args: %w[-f error_unknown_extension.rb])
|
||||
expect(result.stderr).to match /Unknown source file .foo.bar. for CFile builder/
|
||||
expect(result.status).to_not eq 0
|
||||
end
|
||||
end
|
||||
|
||||
context "Command builder" do
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user