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.
|
* `Command`, which executes a user-defined command to produce the target.
|
||||||
* `Copy`, which copies files or directories to a specified destination.
|
* `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.
|
* `Directory`, which creates a directory.
|
||||||
* `Disassemble`, which disassembles an object file to a disassembly listing.
|
* `Disassemble`, which disassembles an object file to a disassembly listing.
|
||||||
* `Install`, which installs files or directories to a specified destination.
|
* `Install`, which installs files or directories to a specified destination.
|
||||||
* `InstallDirectory`, which creates a directory in an install 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.
|
* `Library`, which collects object files into a static library archive file.
|
||||||
* `Object`, which compiles source files to produce an object file.
|
* `Object`, which compiles source files to produce an object file.
|
||||||
* `Preprocess`, which invokes the C/C++ preprocessor on a source 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
|
* `SharedObject`, which compiles source files to produce an object file, in a
|
||||||
way that is able to be used to create a shared library.
|
way that is able to be used to create a shared library.
|
||||||
* `Size`, which runs the 'size' utility on an executable file.
|
* `Size`, which runs the 'size' utility on an executable file.
|
||||||
|
* `Yacc`, which builds a source file from a yacc input file.
|
||||||
|
|
||||||
####> The Command Builder
|
####> 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}`
|
`CMD_STDOUT` is expanded for variable references, so the token `${_TARGET}`
|
||||||
can be used, for example.
|
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
|
####> The Copy Builder
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
@ -1048,6 +1038,17 @@ the `InstallDirectory` builder.
|
|||||||
The `uninstall` task removes targets created by the `InstallDirectory` builder
|
The `uninstall` task removes targets created by the `InstallDirectory` builder
|
||||||
but not by the `Directory` 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
|
####> The Library Builder
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
@ -1178,6 +1179,17 @@ stores its output in the target file.
|
|||||||
The size executable can be specified with the `SIZE` construction variable,
|
The size executable can be specified with the `SIZE` construction variable,
|
||||||
and flags can be specified with `SIZEFLAGS`.
|
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
|
###> Phony Targets
|
||||||
|
|
||||||
Rscons supports phony build targets.
|
Rscons supports phony build targets.
|
||||||
@ -1959,7 +1971,7 @@ end
|
|||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
env do |env|
|
env do |env|
|
||||||
env.CFile("^/parser.tab.cc", "parser.yy")
|
env.Yacc("^/parser.tab.cc", "parser.yy")
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@ -23,13 +23,13 @@ module Rscons
|
|||||||
# Names of the default builders which will be added to all newly created
|
# Names of the default builders which will be added to all newly created
|
||||||
# {Environment} objects.
|
# {Environment} objects.
|
||||||
DEFAULT_BUILDERS = [
|
DEFAULT_BUILDERS = [
|
||||||
:CFile,
|
|
||||||
:Command,
|
:Command,
|
||||||
:Copy,
|
:Copy,
|
||||||
:Directory,
|
:Directory,
|
||||||
:Disassemble,
|
:Disassemble,
|
||||||
:Install,
|
:Install,
|
||||||
:InstallDirectory,
|
:InstallDirectory,
|
||||||
|
:Lex,
|
||||||
:Library,
|
:Library,
|
||||||
:Object,
|
:Object,
|
||||||
:Preprocess,
|
:Preprocess,
|
||||||
@ -37,6 +37,7 @@ module Rscons
|
|||||||
:SharedLibrary,
|
:SharedLibrary,
|
||||||
:SharedObject,
|
:SharedObject,
|
||||||
:Size,
|
:Size,
|
||||||
|
:Yacc,
|
||||||
]
|
]
|
||||||
|
|
||||||
# Class to represent a fatal error during an Rscons operation.
|
# 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"
|
require_relative "rscons/builders/mixins/program"
|
||||||
|
|
||||||
# default builders
|
# default builders
|
||||||
require_relative "rscons/builders/cfile"
|
|
||||||
require_relative "rscons/builders/command"
|
require_relative "rscons/builders/command"
|
||||||
require_relative "rscons/builders/copy"
|
require_relative "rscons/builders/copy"
|
||||||
require_relative "rscons/builders/directory"
|
require_relative "rscons/builders/directory"
|
||||||
require_relative "rscons/builders/disassemble"
|
require_relative "rscons/builders/disassemble"
|
||||||
|
require_relative "rscons/builders/lex"
|
||||||
require_relative "rscons/builders/library"
|
require_relative "rscons/builders/library"
|
||||||
require_relative "rscons/builders/object"
|
require_relative "rscons/builders/object"
|
||||||
require_relative "rscons/builders/preprocess"
|
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/shared_object"
|
||||||
require_relative "rscons/builders/simple_builder"
|
require_relative "rscons/builders/simple_builder"
|
||||||
require_relative "rscons/builders/size"
|
require_relative "rscons/builders/size"
|
||||||
|
require_relative "rscons/builders/yacc"
|
||||||
|
|
||||||
# language support
|
# language support
|
||||||
require_relative "rscons/builders/lang/asm"
|
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}],
|
"LDCMD" => %w[${LD} -o ${_TARGET} ${LDFLAGS} ${_SOURCES} ${LIBDIRPREFIX}${LIBPATH} ${LIBLINKPREFIX}${LIBS}],
|
||||||
"LDFLAGS" => [],
|
"LDFLAGS" => [],
|
||||||
"LEX" => "flex",
|
"LEX" => "flex",
|
||||||
"LEXSUFFIX" => %w[.l .ll],
|
|
||||||
"LEX_CMD" => %w[${LEX} ${LEX_FLAGS} -o ${_TARGET} ${_SOURCES}],
|
"LEX_CMD" => %w[${LEX} ${LEX_FLAGS} -o ${_TARGET} ${_SOURCES}],
|
||||||
"LEX_FLAGS" => [],
|
"LEX_FLAGS" => [],
|
||||||
"LIBDIRPREFIX" => "-L",
|
"LIBDIRPREFIX" => "-L",
|
||||||
@ -84,7 +83,6 @@ module Rscons
|
|||||||
"SIZECMD" => %w[${SIZE} ${SIZEFLAGS} ${_SOURCES}],
|
"SIZECMD" => %w[${SIZE} ${SIZEFLAGS} ${_SOURCES}],
|
||||||
"SIZEFLAGS" => [],
|
"SIZEFLAGS" => [],
|
||||||
"YACC" => "bison",
|
"YACC" => "bison",
|
||||||
"YACCSUFFIX" => %w[.y .yy],
|
|
||||||
"YACC_CMD" => %w[${YACC} ${YACC_FLAGS} -o ${_TARGET} ${_SOURCES}],
|
"YACC_CMD" => %w[${YACC} ${YACC_FLAGS} -o ${_TARGET} ${_SOURCES}],
|
||||||
"YACC_FLAGS" => %w[-d],
|
"YACC_FLAGS" => %w[-d],
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1163,28 +1163,21 @@ EOF
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "CFile builder" do
|
context "Lex and Yacc builders" do
|
||||||
it "builds a .c file using flex and bison" do
|
it "builds C files using flex and bison" do
|
||||||
test_dir("cfile")
|
test_dir("lex_yacc")
|
||||||
|
|
||||||
result = run_rscons
|
result = run_rscons
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
verify_lines(lines(result.stdout), [
|
verify_lines(lines(result.stdout), [
|
||||||
%r{Generating lexer from lexer.l => lexer.c},
|
%r{Generating lexer source from lexer.l => lexer.c},
|
||||||
%r{Generating parser from parser.y => parser.c},
|
%r{Generating parser source from parser.y => parser.c},
|
||||||
])
|
])
|
||||||
|
|
||||||
result = run_rscons
|
result = run_rscons
|
||||||
expect(result.stderr).to eq ""
|
expect(result.stderr).to eq ""
|
||||||
expect(result.stdout).to eq ""
|
expect(result.stdout).to eq ""
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
context "Command builder" do
|
context "Command builder" do
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user