mruby_tools 0.0.2.1 → 0.0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
[](https://travis-ci.org/rickhull/mruby_tools)
|
2
|
+
[](https://badge.fury.io/rb/mruby_tools)
|
3
|
+
[](https://gemnasium.com/rickhull/mruby_tools)
|
4
|
+
[](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:
|