mruby_tools 0.0.2.1 → 0.0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +226 -1
- data/Rakefile +105 -0
- data/VERSION +1 -1
- data/bin/mrbt +21 -13
- data/lib/mruby_tools.rb +98 -60
- data/mruby_tools.gemspec +1 -1
- data/test/mruby_tools.rb +36 -34
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9d06a51f1ed9667b7b39c12bcb3173f4b064d6ad
|
4
|
+
data.tar.gz: e63a21a002b71f1aef930fb5f91950e90757e7c3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 566ad106b83ae4838f08d0233f485b910e9f86d484e819c72034b4b9fb36422db9e490bcfc9f0d24add9e0f021d244400b4704644afc38bf508c90f7dff4408f
|
7
|
+
data.tar.gz: 32b9ae7a7685e73e17b23fba501c8036ec04065c9ee46afc97f855fbd6fc2b6cfcf2da4c29df9e685760e27cb0024d08cee470dee46be9aaf099949e1a2a4ad5
|
data/README.md
CHANGED
@@ -1 +1,226 @@
|
|
1
|
-
|
1
|
+
[![Build Status](https://travis-ci.org/rickhull/mruby_tools.svg?branch=master)](https://travis-ci.org/rickhull/mruby_tools)
|
2
|
+
[![Gem Version](https://badge.fury.io/rb/mruby_tools.svg)](https://badge.fury.io/rb/mruby_tools)
|
3
|
+
[![Dependency Status](https://gemnasium.com/rickhull/mruby_tools.svg)](https://gemnasium.com/rickhull/mruby_tools)
|
4
|
+
[![Security Status](https://hakiri.io/github/rickhull/mruby_tools/master.svg)](https://hakiri.io/github/rickhull/mruby_tools/master)
|
5
|
+
|
6
|
+
# mruby tools
|
7
|
+
|
8
|
+
This is a small gem that provides one tool at present: `mrbt`. This is a
|
9
|
+
**ruby gem**, not an **mruby mgem**, but it is primarily useful for working
|
10
|
+
with **mruby**.
|
11
|
+
|
12
|
+
`mrbt` accepts any number of .rb files and "compiles" them into a standalone
|
13
|
+
executable using mruby. The .rb files must be
|
14
|
+
[mruby-compatible](https://github.com/mruby/mruby/blob/master/doc/limitations.md) (roughly equivalent to MRI v1.9).
|
15
|
+
|
16
|
+
## Install
|
17
|
+
|
18
|
+
### `git clone`
|
19
|
+
|
20
|
+
By using `git clone` rather than `gem install`, you can make use of rake
|
21
|
+
tasks, particularly for compiling mruby itself, a necessary prerequisite
|
22
|
+
for using `mrbt`. This is the easiest way to get started if you are new
|
23
|
+
to mruby. The mruby source is provided as a git submodule;
|
24
|
+
therefore you must `git clone --recursive` or else update the submodule
|
25
|
+
manually.
|
26
|
+
|
27
|
+
Prerequisites:
|
28
|
+
|
29
|
+
* `git`
|
30
|
+
* `rake`
|
31
|
+
* *build tools:* `gcc` `make` `bison` `ar`
|
32
|
+
|
33
|
+
```shell
|
34
|
+
git clone --recursive https://github.com/rickhull/mruby_tools.git
|
35
|
+
cd mruby_tools
|
36
|
+
rake hello_world
|
37
|
+
```
|
38
|
+
|
39
|
+
This will provide mruby source via a git repo submodule and then build it to
|
40
|
+
provide `libmruby.a`.
|
41
|
+
|
42
|
+
The rake command will proceed to "compiling" `examples/hello_world.rb` to
|
43
|
+
a standalone binary executable `examples/hello_world`, which will then be
|
44
|
+
executed with the customary output shown.
|
45
|
+
|
46
|
+
Once mruby has been built by rake, it will not be built again by rake as long
|
47
|
+
as `libmruby.a` is present. The first run of `rake hello_world` takes up to
|
48
|
+
30 seconds or so, depending on your system. The next run of
|
49
|
+
`rake hello_world` takes about a half-second, including compiling and
|
50
|
+
running the executable.
|
51
|
+
|
52
|
+
### *rubygems*
|
53
|
+
|
54
|
+
Only use this if you have an existing mruby built and installed. `mrbt` will
|
55
|
+
be set up in your PATH, but you will have to specify the path to mruby
|
56
|
+
source via `-m path/to/mruby_dir` or `MRUBY_DIR` environment variable. You
|
57
|
+
will not have (easy) access to rake tasks.
|
58
|
+
|
59
|
+
Prerequisites:
|
60
|
+
|
61
|
+
* *rubygems*
|
62
|
+
* *build tools:* `gcc` `make` `bison` `ar`
|
63
|
+
* *mruby_dir*
|
64
|
+
* *mruby_dir*/build/host/lib/libmruby.a
|
65
|
+
|
66
|
+
```shell
|
67
|
+
gem install mruby_tools
|
68
|
+
```
|
69
|
+
|
70
|
+
Now, `mrbt` may be used. It will need to know where to find the mruby_dir,
|
71
|
+
so specify it with the `-m` flag or `MRUBY_DIR` environment variable.
|
72
|
+
|
73
|
+
```shell
|
74
|
+
export MRUBY_DIR=~/src/mruby-1.3.0 # or wherever
|
75
|
+
mrbt file1.rb file2.rb # etc.
|
76
|
+
```
|
77
|
+
|
78
|
+
## Usage
|
79
|
+
|
80
|
+
With no additional options, `mrbt` will inject the contents of file1.rb and
|
81
|
+
file2.rb into C strings, to be loaded with mrb_load_nstring(), written to a
|
82
|
+
Tempfile. `mrbt` then compiles the generated .c file using GCC and writes
|
83
|
+
a standalone executable (around 1.5 MB for "hello world").
|
84
|
+
|
85
|
+
### With `git clone` and `rake`
|
86
|
+
|
87
|
+
You can use `rake mrbt` to execute `bin/mrbt` with the proper load path, and
|
88
|
+
any arguments will be passed along. Some mrbt options conflict with rake
|
89
|
+
options. You can prevent rake from parsing arguments by placing them
|
90
|
+
after ` -- `.
|
91
|
+
|
92
|
+
```shell
|
93
|
+
rake mrbt -- -h
|
94
|
+
rake mrbt examples/hello_world.rb
|
95
|
+
rake mrbt -- examples/hello_world.rb examples/goodbye_world.rb -o adios
|
96
|
+
```
|
97
|
+
|
98
|
+
Other useful rake tasks:
|
99
|
+
|
100
|
+
* hello world - compiles and runs `examples/hello_world.rb`
|
101
|
+
* timed_simplex - compiles and runs several files that work together
|
102
|
+
* raise_exception - compiles and runs `examples/raise.rb`
|
103
|
+
* examples - runs hello_world and timed_simplex
|
104
|
+
* verbose - add verbose output, e.g. `rake verbose hello_world`
|
105
|
+
|
106
|
+
### With *rubygems*
|
107
|
+
|
108
|
+
```shell
|
109
|
+
mrbt -h
|
110
|
+
```
|
111
|
+
|
112
|
+
```
|
113
|
+
USAGE: mrbt file1.rb file2.rb ...
|
114
|
+
OPTIONS: -o outfile (provide a name for the standalone executable)
|
115
|
+
-c generated.c (leave the specified C file on the filesystem)
|
116
|
+
-m mruby_dir (provide the dir for mruby src)
|
117
|
+
-v (verbose)
|
118
|
+
```
|
119
|
+
|
120
|
+
## Examples
|
121
|
+
|
122
|
+
There are some example .rb files in examples/ that can be used to produce
|
123
|
+
an executable. Use `mrbt` or `rake mrbt` as appropriate:
|
124
|
+
|
125
|
+
```shell
|
126
|
+
mrbt examples/hello_world.rb
|
127
|
+
|
128
|
+
# or
|
129
|
+
rake mrbt examples/hello_world.rb
|
130
|
+
|
131
|
+
# or even
|
132
|
+
rake hello_world
|
133
|
+
```
|
134
|
+
|
135
|
+
```
|
136
|
+
/home/vagrant/.rubies/ruby-2.4.0/bin/ruby -Ilib bin/mrbt examples/hello_world.rb -o examples/hello_world
|
137
|
+
compiling...
|
138
|
+
created binary executable: examples/hello_world
|
139
|
+
examples/hello_world
|
140
|
+
hello_world
|
141
|
+
```
|
142
|
+
|
143
|
+
The first line shows that rake is executing `mrbt` (via `ruby`), passing it
|
144
|
+
`examples/hello_world.rb` and naming the output executable
|
145
|
+
`examples/hello_world`.
|
146
|
+
|
147
|
+
`mrbt` outputs "compiling..." and then "created binary
|
148
|
+
executable: examples/hello_world"
|
149
|
+
|
150
|
+
Then `examples/hello_world` is executed, and it outputs "hello_world".
|
151
|
+
|
152
|
+
### Verbose Hello World
|
153
|
+
|
154
|
+
```shell
|
155
|
+
mrbt examples/hello_world.rb -v
|
156
|
+
|
157
|
+
# or
|
158
|
+
rake mrbt -- -v examples/hello_world.rb
|
159
|
+
|
160
|
+
# or even
|
161
|
+
rake verbose hello_world
|
162
|
+
```
|
163
|
+
|
164
|
+
```
|
165
|
+
/home/vagrant/.rubies/ruby-2.4.0/bin/ruby -Ilib bin/mrbt examples/hello_world.rb -o examples/hello_world -v
|
166
|
+
#include <stdlib.h>
|
167
|
+
#include <mruby.h>
|
168
|
+
#include <mruby/compile.h>
|
169
|
+
#include <mruby/string.h>
|
170
|
+
|
171
|
+
void check_exc(mrb_state *mrb, char *filename) {
|
172
|
+
if (mrb->exc) {
|
173
|
+
mrb_value exc = mrb_obj_value(mrb->exc);
|
174
|
+
mrb_value exc_msg = mrb_funcall(mrb, exc, "to_s", 0);
|
175
|
+
fprintf(stderr, "ERROR in %s - %s: %s\n",
|
176
|
+
filename,
|
177
|
+
mrb_obj_classname(mrb, exc),
|
178
|
+
mrb_str_to_cstr(mrb, exc_msg));
|
179
|
+
/* mrb_print_backtrace(mrb); # empty */
|
180
|
+
exit(1);
|
181
|
+
}
|
182
|
+
}
|
183
|
+
|
184
|
+
int
|
185
|
+
main(void)
|
186
|
+
{
|
187
|
+
mrb_state *mrb = mrb_open();
|
188
|
+
if (!mrb) {
|
189
|
+
printf("mrb problem");
|
190
|
+
exit(1);
|
191
|
+
}
|
192
|
+
|
193
|
+
/* examples/hello_world.rb */
|
194
|
+
mrb_load_nstring(mrb, "puts :hello_world\n", 18);
|
195
|
+
check_exc(mrb, "examples/hello_world.rb");
|
196
|
+
|
197
|
+
mrb_close(mrb);
|
198
|
+
return 0;
|
199
|
+
}
|
200
|
+
|
201
|
+
generated /tmp/mrbt-20171117-24568-no7ee3.c
|
202
|
+
compiling...
|
203
|
+
created binary executable: examples/hello_world
|
204
|
+
|
205
|
+
file examples/hello_world
|
206
|
+
examples/hello_world: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=2114ab60983156c92a5a74b88895f9c43a4bb086, not stripped
|
207
|
+
|
208
|
+
stat examples/hello_world
|
209
|
+
File: ‘examples/hello_world’
|
210
|
+
Size: 1559056 Blocks: 3048 IO Block: 4096 regular file
|
211
|
+
Device: 801h/2049d Inode: 388049 Links: 1
|
212
|
+
Access: (0755/-rwxr-xr-x) Uid: ( 1000/ vagrant) Gid: ( 1000/ vagrant)
|
213
|
+
Access: 2017-11-17 18:48:25.713629203 +0000
|
214
|
+
Modify: 2017-11-17 18:48:25.709629203 +0000
|
215
|
+
Change: 2017-11-17 18:48:25.709629203 +0000
|
216
|
+
Birth: -
|
217
|
+
|
218
|
+
examples/hello_world
|
219
|
+
hello_world
|
220
|
+
```
|
221
|
+
|
222
|
+
This proceeds exactly as before but with additional output:
|
223
|
+
|
224
|
+
* Show the generated C code
|
225
|
+
* Note the temporary file containing the C code
|
226
|
+
* Call `file` and `stat` on the output executable
|
data/Rakefile
CHANGED
@@ -1,4 +1,25 @@
|
|
1
1
|
require 'rake/testtask'
|
2
|
+
require_relative './lib/mruby_tools.rb'
|
3
|
+
|
4
|
+
#
|
5
|
+
# GET / SETUP MRUBY
|
6
|
+
#
|
7
|
+
|
8
|
+
mrb = MRubyTools.new
|
9
|
+
|
10
|
+
file mrb.ar_path do
|
11
|
+
if mrb.src?
|
12
|
+
Dir.chdir MRubyTools.mruby_dir do
|
13
|
+
sh "make"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
mrb.validate!
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
#
|
21
|
+
# lib/mruby_tools tests
|
22
|
+
#
|
2
23
|
|
3
24
|
Rake::TestTask.new :test do |t|
|
4
25
|
t.pattern = "test/*.rb"
|
@@ -6,6 +27,90 @@ Rake::TestTask.new :test do |t|
|
|
6
27
|
end
|
7
28
|
|
8
29
|
|
30
|
+
#
|
31
|
+
# run mrbt via `rake mrbt`
|
32
|
+
#
|
33
|
+
|
34
|
+
@verbose = false
|
35
|
+
|
36
|
+
task :verbose do
|
37
|
+
@verbose = true
|
38
|
+
end
|
39
|
+
|
40
|
+
def mrbt *args
|
41
|
+
args.unshift('-v') if @verbose and !args.include?('-v')
|
42
|
+
ruby '-Ilib', 'bin/mrbt', *args
|
43
|
+
end
|
44
|
+
|
45
|
+
task mrbt: mrb.ar_path do
|
46
|
+
# consume ARGV
|
47
|
+
args = []
|
48
|
+
found_mrbt = false
|
49
|
+
while !ARGV.empty?
|
50
|
+
arg = ARGV.shift
|
51
|
+
# skip all args until we reach 'mrbt'
|
52
|
+
if found_mrbt
|
53
|
+
args << arg
|
54
|
+
next
|
55
|
+
end
|
56
|
+
found_mrbt = true if arg == 'mrbt'
|
57
|
+
end
|
58
|
+
begin
|
59
|
+
mrbt *args
|
60
|
+
rescue RuntimeError
|
61
|
+
exit 1
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
#
|
67
|
+
# mrbt EXAMPLES
|
68
|
+
#
|
69
|
+
|
70
|
+
def run_clean outfile, clean: true
|
71
|
+
begin
|
72
|
+
if @verbose
|
73
|
+
puts
|
74
|
+
sh "file", outfile
|
75
|
+
puts
|
76
|
+
sh "stat", outfile
|
77
|
+
puts
|
78
|
+
end
|
79
|
+
sh outfile
|
80
|
+
ensure
|
81
|
+
if clean
|
82
|
+
File.unlink outfile unless @verbose
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
desc "Run hello_world example"
|
88
|
+
task hello_world: mrb.ar_path do
|
89
|
+
outfile = "examples/hello_world"
|
90
|
+
mrbt "examples/hello_world.rb", "-o", outfile
|
91
|
+
run_clean outfile
|
92
|
+
end
|
93
|
+
|
94
|
+
desc "Run timed_simplex example"
|
95
|
+
task timed_simplex: mrb.ar_path do
|
96
|
+
outfile = "examples/timed_simplex"
|
97
|
+
mrbt "examples/timer.rb", "examples/simplex.rb", "examples/driver.rb",
|
98
|
+
"-o", outfile
|
99
|
+
run_clean outfile
|
100
|
+
end
|
101
|
+
|
102
|
+
desc "Run raise example"
|
103
|
+
task raise_exception: mrb.ar_path do
|
104
|
+
outfile = "examples/raise"
|
105
|
+
mrbt "examples/hello_world.rb", "examples/raise.rb", "-o", outfile
|
106
|
+
run_clean outfile
|
107
|
+
end
|
108
|
+
|
109
|
+
desc "Run examples"
|
110
|
+
task examples: [:hello_world, :timed_simplex]
|
111
|
+
|
112
|
+
task default: [:test, :examples]
|
113
|
+
|
9
114
|
#
|
10
115
|
# METRICS
|
11
116
|
#
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.3.1
|
data/bin/mrbt
CHANGED
@@ -6,25 +6,33 @@ require 'mruby_tools'
|
|
6
6
|
# args like: file1.rb file2.rb -o outfile
|
7
7
|
# possibly: file1.rb -o outfile file2.rb -c generated.c
|
8
8
|
|
9
|
-
opts = MRubyTools.args(ARGV)
|
10
|
-
MRubyTools.usage if opts[:help]
|
9
|
+
opts = MRubyTools::CLI.args(ARGV)
|
10
|
+
MRubyTools::CLI.usage if opts[:help]
|
11
|
+
|
12
|
+
mrb = MRubyTools.new(opts[:mruby_dir]) # nil is fine
|
13
|
+
begin
|
14
|
+
mrb.validate!
|
15
|
+
rescue MRubyTools::MRubyNotFound => e
|
16
|
+
warn "#{e.class}: can't find #{e}"
|
17
|
+
exit 1
|
18
|
+
end
|
11
19
|
|
12
20
|
rb_files = opts.fetch(:rb_files)
|
13
|
-
MRubyTools.usage("no .rb files provided") if rb_files.empty?
|
14
|
-
|
21
|
+
MRubyTools::CLI.usage("no .rb files provided") if rb_files.empty?
|
22
|
+
|
23
|
+
c_code = MRubyTools::C.wrapper(rb_files)
|
15
24
|
puts c_code + "\n" if opts[:verbose]
|
16
25
|
|
17
|
-
out_file = opts.fetch(:out_file)
|
18
26
|
c_file = opts.fetch(:c_file)
|
19
27
|
c_file.write(c_code)
|
20
28
|
c_file.close
|
29
|
+
puts "generated #{c_file.path}" if opts[:verbose]
|
21
30
|
|
22
|
-
|
23
|
-
|
24
|
-
gcc_args = [
|
25
|
-
'-std=c99', "-I", File.join(msd, 'include'), c_file.path, "-o", out_file,
|
26
|
-
File.join(msd, 'build', 'host', 'lib', 'libmruby.a'), '-lm',
|
27
|
-
]
|
28
|
-
|
31
|
+
out_file = opts.fetch(:out_file)
|
29
32
|
puts "compiling..."
|
30
|
-
|
33
|
+
if mrb.compile(c_file.path, out_file)
|
34
|
+
puts "created binary executable: #{out_file}"
|
35
|
+
else
|
36
|
+
warn "FATAL: compile failed"
|
37
|
+
exit 1
|
38
|
+
end
|
data/lib/mruby_tools.rb
CHANGED
@@ -1,8 +1,47 @@
|
|
1
1
|
require 'tempfile'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
class MRubyTools
|
4
|
+
class MRubyNotFound < RuntimeError; end
|
5
|
+
|
6
|
+
MRUBY_DIR = File.expand_path("../mruby", __dir__)
|
7
|
+
|
8
|
+
def self.mruby_dir
|
9
|
+
ENV['MRUBY_DIR'] || MRUBY_DIR
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_accessor :mruby_dir, :inc_path, :ar_path
|
13
|
+
|
14
|
+
def initialize(mruby_dir = nil)
|
15
|
+
@mruby_dir = mruby_dir || self.class.mruby_dir
|
16
|
+
@inc_path = File.join(@mruby_dir, 'include')
|
17
|
+
@ar_path = File.join(@mruby_dir, 'build', 'host', 'lib', 'libmruby.a')
|
18
|
+
end
|
19
|
+
|
20
|
+
def src?
|
21
|
+
File.directory?(@inc_path)
|
22
|
+
end
|
23
|
+
|
24
|
+
def built?
|
25
|
+
File.readable?(@ar_path)
|
26
|
+
end
|
27
|
+
|
28
|
+
def validate!
|
29
|
+
raise(MRubyNotFound, @inc_path) unless File.directory? @inc_path
|
30
|
+
raise(MRubyNotFound, @ar_path) unless File.readable? @ar_path
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
def gcc_args(c_file, out_file)
|
35
|
+
['-std=c99', "-I", @inc_path, c_file, "-o", out_file, @ar_path, '-lm']
|
36
|
+
end
|
37
|
+
|
38
|
+
def compile(c_file, out_file)
|
39
|
+
system('gcc', *self.gcc_args(c_file, out_file))
|
40
|
+
end
|
41
|
+
|
42
|
+
module C
|
43
|
+
def self.wrapper(rb_files)
|
44
|
+
c_code = <<'EOF'
|
6
45
|
#include <stdlib.h>
|
7
46
|
#include <mruby.h>
|
8
47
|
#include <mruby/compile.h>
|
@@ -30,79 +69,78 @@ main(void)
|
|
30
69
|
exit(1);
|
31
70
|
}
|
32
71
|
EOF
|
33
|
-
|
34
|
-
|
35
|
-
|
72
|
+
c_code += rb_files.map { |rbf|
|
73
|
+
"\n" + self.slurp_rb(rbf) + "\n\n"
|
74
|
+
}.join
|
36
75
|
|
37
|
-
|
76
|
+
c_code += <<EOF
|
38
77
|
mrb_close(mrb);
|
39
78
|
return 0;
|
40
79
|
}
|
41
80
|
EOF
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
def self.rb2c(rb_filename, indent: ' ')
|
46
|
-
c_str = File.read(rb_filename)
|
47
|
-
size = c_str.size
|
48
|
-
c_str = c_str.gsub("\n", '\n').gsub('"', '\"')
|
49
|
-
c_str = File.read(rb_filename).gsub("\n", '\n').gsub('"', '\"')
|
50
|
-
[ "/* #{rb_filename} */",
|
51
|
-
'mrb_load_nstring(mrb, "' + c_str + '", ' + "#{size});",
|
52
|
-
"check_exc(mrb, \"#{rb_filename}\");",
|
53
|
-
].map { |s| indent + s }.join("\n")
|
54
|
-
end
|
81
|
+
c_code
|
82
|
+
end
|
55
83
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
84
|
+
def self.slurp_rb(rb_filename, indent: ' ')
|
85
|
+
c_str = File.read(rb_filename)
|
86
|
+
size = c_str.size
|
87
|
+
c_str = c_str.gsub("\n", '\n').gsub('"', '\"')
|
88
|
+
[ "/* #{rb_filename} */",
|
89
|
+
'mrb_load_nstring(mrb, "' + c_str + '", ' + "#{size});",
|
90
|
+
"check_exc(mrb, \"#{rb_filename}\");",
|
91
|
+
].map { |s| indent + s }.join("\n")
|
92
|
+
end
|
63
93
|
end
|
64
94
|
|
65
|
-
|
66
|
-
|
95
|
+
module CLI
|
96
|
+
def self.usage(msg = nil)
|
97
|
+
puts <<EOF
|
67
98
|
USAGE: mrbt file1.rb file2.rb ...
|
68
99
|
OPTIONS: -o outfile (provide a name for the standalone executable)
|
69
100
|
-c generated.c (leave the specified C file on the filesystem)
|
101
|
+
-m mruby_dir (provide the dir for mruby src)
|
70
102
|
-v (verbose)
|
71
103
|
EOF
|
72
|
-
|
73
|
-
|
74
|
-
|
104
|
+
warn " ERROR: #{msg}" if msg
|
105
|
+
exit(msg ? 1 : 0)
|
106
|
+
end
|
75
107
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
108
|
+
def self.args(argv = ARGV)
|
109
|
+
rb_files = []
|
110
|
+
out_file = nil
|
111
|
+
c_file = nil
|
112
|
+
mruby_dir = nil
|
113
|
+
verbose = false
|
114
|
+
help = false
|
115
|
+
|
116
|
+
while !argv.empty?
|
117
|
+
arg = argv.shift
|
118
|
+
if arg == '-o'
|
119
|
+
out_file = argv.shift
|
120
|
+
raise "no out_file provided with -o" unless out_file
|
121
|
+
raise "#{out_file} is misnamed" if File.extname(out_file) == '.rb'
|
122
|
+
elsif arg == '-c'
|
123
|
+
c_file = File.open(argv.shift || 'generated.c', "w")
|
124
|
+
elsif arg == '-v'
|
125
|
+
verbose = true
|
126
|
+
elsif arg == '-h'
|
127
|
+
help = true
|
128
|
+
elsif arg == '-m'
|
129
|
+
mruby_dir = argv.shift
|
130
|
+
raise "no mruby_dir provided with -m" unless mruby_dir
|
131
|
+
else
|
132
|
+
rb_files << arg
|
133
|
+
end
|
97
134
|
end
|
98
|
-
end
|
99
135
|
|
100
|
-
|
136
|
+
c_file ||= Tempfile.new(['mrbt-', '.c'])
|
101
137
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
138
|
+
{ verbose: verbose,
|
139
|
+
help: help,
|
140
|
+
c_file: c_file,
|
141
|
+
out_file: out_file || 'outfile',
|
142
|
+
rb_files: rb_files,
|
143
|
+
mruby_dir: mruby_dir }
|
144
|
+
end
|
107
145
|
end
|
108
146
|
end
|
data/mruby_tools.gemspec
CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
|
|
19
19
|
|
20
20
|
s.add_development_dependency "rake", "~> 0"
|
21
21
|
s.add_development_dependency "buildar", "~> 3.0"
|
22
|
-
|
22
|
+
s.add_development_dependency "minitest", "~> 5.0"
|
23
23
|
# s.add_development_dependency "flog", "~> 0"
|
24
24
|
# s.add_development_dependency "flay", "~> 0"
|
25
25
|
# s.add_development_dependency "roodi", "~> 0"
|
data/test/mruby_tools.rb
CHANGED
@@ -2,24 +2,31 @@ require 'mruby_tools'
|
|
2
2
|
require 'minitest/autorun'
|
3
3
|
|
4
4
|
describe MRubyTools do
|
5
|
-
describe "
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
5
|
+
describe "new instance" do
|
6
|
+
before do
|
7
|
+
@valid = MRubyTools.new
|
8
|
+
@invalid = MRubyTools.new('blah blah')
|
9
|
+
end
|
10
|
+
|
11
|
+
it "must validate!" do
|
12
|
+
@valid.validate! if @valid.built?
|
13
|
+
proc { @invalid.validate! }.must_raise MRubyTools::MRubyNotFound
|
14
|
+
end
|
15
|
+
|
16
|
+
it "must have ivars" do
|
17
|
+
[@valid, @invalid].each { |obj|
|
18
|
+
obj.mruby_dir.must_be_kind_of String
|
19
|
+
obj.inc_path.must_be_kind_of String
|
20
|
+
obj.ar_path.must_be_kind_of String
|
16
21
|
}
|
22
|
+
@valid.inc_path.must_match %r{include}
|
23
|
+
@valid.ar_path.must_match %r{libmruby.a}
|
17
24
|
end
|
18
25
|
end
|
19
26
|
|
20
|
-
describe "
|
27
|
+
describe "C.slurp_rb" do
|
21
28
|
it "must inject the contents of a ruby file into mrb_load_string()" do
|
22
|
-
str = MRubyTools.
|
29
|
+
str = MRubyTools::C.slurp_rb(__FILE__)
|
23
30
|
str.must_be_kind_of String
|
24
31
|
str.wont_be_empty
|
25
32
|
str.must_match(/mrb_load_n?string\(/)
|
@@ -27,33 +34,27 @@ describe MRubyTools do
|
|
27
34
|
end
|
28
35
|
end
|
29
36
|
|
30
|
-
describe "
|
31
|
-
it "must
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
37
|
+
describe "C.wrapper" do
|
38
|
+
it "must return a string of mruby C code" do
|
39
|
+
[[], [__FILE__]].each { |rb_files|
|
40
|
+
str = MRubyTools::C.wrapper(rb_files)
|
41
|
+
str.must_be_kind_of String
|
42
|
+
str.wont_be_empty
|
43
|
+
str.must_match(/main\(void\)/)
|
44
|
+
str.must_match(/return/)
|
45
|
+
str.must_match(/exit/)
|
46
|
+
str.must_match(/mruby/)
|
47
|
+
str.must_match(/mrb/)
|
36
48
|
}
|
37
|
-
unless candidates.empty?
|
38
|
-
latest = File.expand_path('..', candidates.last)
|
39
|
-
key = 'TESTING_MRUBY_SRC_DIR'
|
40
|
-
ENV[key] = latest
|
41
|
-
dir = MRubyTools.mruby_src_dir(key)
|
42
|
-
File.directory?(dir).must_equal true
|
43
|
-
File.directory?(File.join(dir, 'include')).must_equal true
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
it "must accept the dir specification from the environment" do
|
48
|
-
proc { MRubyTools.mruby_src_dir('bad key') }.must_raise Exception
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
-
describe "args" do
|
52
|
+
describe "CLI.args" do
|
53
53
|
it "must provide a hash with expected keys" do
|
54
|
-
h = MRubyTools.args([])
|
54
|
+
h = MRubyTools::CLI.args([])
|
55
55
|
h.must_be_kind_of Hash
|
56
|
-
[:verbose, :help, :c_file,
|
56
|
+
[:verbose, :help, :c_file,
|
57
|
+
:out_file, :rb_files, :mruby_dir].each { |key|
|
57
58
|
h.key?(key).must_equal true
|
58
59
|
}
|
59
60
|
h[:verbose].must_equal false
|
@@ -63,6 +64,7 @@ describe MRubyTools do
|
|
63
64
|
h[:out_file].wont_be_empty
|
64
65
|
h[:rb_files].must_be_kind_of Array
|
65
66
|
h[:rb_files].must_be_empty
|
67
|
+
h[:mruby_dir].must_be_nil
|
66
68
|
end
|
67
69
|
end
|
68
70
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mruby_tools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rick Hull
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-11-
|
11
|
+
date: 2017-11-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '3.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '5.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '5.0'
|
41
55
|
description: TBD
|
42
56
|
email:
|
43
57
|
executables:
|