summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--doc/mrbgems/README.md160
-rw-r--r--doc/mrbgems/c_and_ruby_extension_example/src/example.c5
-rw-r--r--doc/mrbgems/c_extension_example/src/example.c5
-rw-r--r--mrblib/mrblib.rake2
-rw-r--r--src/init.c9
-rw-r--r--src/load.c2
-rw-r--r--src/state.c3
-rw-r--r--tasks/libmruby.rake6
-rw-r--r--tasks/mrbgem_spec.rake6
-rw-r--r--tasks/mrbgems.rake8
-rw-r--r--tasks/mruby_build.rake8
-rw-r--r--tasks/mruby_build_commands.rake14
-rw-r--r--tasks/mruby_build_gem.rake6
-rw-r--r--tasks/ruby_ext.rake8
-rw-r--r--tasks/toolchains/clang.rake4
-rw-r--r--tasks/toolchains/gcc.rake2
-rw-r--r--tasks/toolchains/vs2012.rake2
-rw-r--r--test/mrbtest.rake2
-rw-r--r--tools/mrbc/mrbc.c5
19 files changed, 151 insertions, 106 deletions
diff --git a/doc/mrbgems/README.md b/doc/mrbgems/README.md
index 9e930d8b2..0af3192f4 100644
--- a/doc/mrbgems/README.md
+++ b/doc/mrbgems/README.md
@@ -11,44 +11,34 @@ extension integrated.
To add a GEM into the build_config.rb add the following line for example:
-```
-conf.gem '/path/to/your/gem/dir'
-```
+ conf.gem '/path/to/your/gem/dir'
You can also use a relative path which would be relative from the mruby root:
-```
-conf.gem 'doc/mrbgems/ruby_extension_example'
-```
+ conf.gem 'doc/mrbgems/ruby_extension_example'
A remote GIT repository location for a GEM is also supported:
-```
-conf.gem :git => 'https://github.com/masuidrive/mrbgems-example.git', :branch => 'master'
-```
+ conf.gem :git => 'https://github.com/masuidrive/mrbgems-example.git', :branch => 'master'
-```
-conf.gem :github => 'masuidrive/mrbgems-example', :branch => 'master'
-```
+ conf.gem :github => 'masuidrive/mrbgems-example', :branch => 'master'
## GEM Structure
The maximal GEM structure looks like this:
-```
-+- GEM_NAME <- Name of GEM
- |
- +- mrblib/ <- Source for Ruby extension
- |
- +- src/ <- Source for C extension
- |
- +- test/ <- Test code (Ruby)
- |
- +- mrbgem.rake <- GEM Specification
- |
- +- README.md <- Readme for GEM
-```
+ +- GEM_NAME <- Name of GEM
+ |
+ +- mrblib/ <- Source for Ruby extension
+ |
+ +- src/ <- Source for C extension
+ |
+ +- test/ <- Test code (Ruby)
+ |
+ +- mrbgem.rake <- GEM Specification
+ |
+ +- README.md <- Readme for GEM
The folder *mrblib* contains pure Ruby files to extend mruby. The folder *src*
contains C files to extend mruby. The folder *test* contains C and pure Ruby files
@@ -61,12 +51,10 @@ of your GEM.
mrbgems expects a specifcation file called *mrbgem.rake* inside of your
GEM direcotry. A typical GEM specification could look like this for example:
-```
-MRuby::Gem::Specification.new('c_and_ruby_extension_example') do |spec|
- spec.license = 'MIT'
- spec.authors = 'mruby developers'
-end
-```
+ MRuby::Gem::Specification.new('c_and_ruby_extension_example') do |spec|
+ spec.license = 'MIT'
+ spec.authors = 'mruby developers'
+ end
The mrbgems build process will use this specification to compile Object and Ruby
files. The compilation results will be add to *lib/libmruby.a*. This file is used
@@ -98,31 +86,42 @@ mrbgems expects that you have implemented a C method called
by the name of your GEM. If you call your GEM *c_extension_example*, your
initialisation method could look like this:
+ void
+ mrb_c_extension_example_gem_init(mrb_state* mrb) {
+ struct RClass *class_cextension = mrb_define_module(mrb, "CExtension");
+ mrb_define_class_method(mrb, class_cextension, "c_method", mrb_c_method, ARGS_NONE());
+ }
+
+### Finalize
+
+mrbgems expects that you have implemented a C method called
+```mrb_YOURGEMNAME_gem_final(mrb_state)```. ```YOURGEMNAME``` will be replaced
+by the name of your GEM. If you call your GEM *c_extension_example*, your
+finalizer method could look like this:
+
```
void
-mrb_c_extension_example_gem_init(mrb_state* mrb) {
- struct RClass *class_cextension = mrb_define_module(mrb, "CExtension");
- mrb_define_class_method(mrb, class_cextension, "c_method", mrb_c_method, ARGS_NONE());
+mrb_c_extension_example_gem_final(mrb_state* mrb) {
+ free(someone);
}
```
+
### Example
-```
-+- c_extension_example/
- |
- +- src/
- | |
- | +- example.c <- C extension source
- |
- +- test/
- | |
- | +- example.rb <- Test code for C extension
- |
- +- mrbgem.rake <- GEM specification
- |
- +- README.md
-```
+ +- c_extension_example/
+ |
+ +- src/
+ | |
+ | +- example.c <- C extension source
+ |
+ +- test/
+ | |
+ | +- example.rb <- Test code for C extension
+ |
+ +- mrbgem.rake <- GEM specification
+ |
+ +- README.md
## Ruby Extension
@@ -136,21 +135,19 @@ none
### Example
-```
-+- ruby_extension_example/
- |
- +- mrblib/
- | |
- | +- example.rb <- Ruby extension source
- |
- +- test/
- | |
- | +- example.rb <- Test code for Ruby extension
- |
- +- mrbgem.rake <- GEM specification
- |
- +- README.md
-```
+ +- ruby_extension_example/
+ |
+ +- mrblib/
+ | |
+ | +- example.rb <- Ruby extension source
+ |
+ +- test/
+ | |
+ | +- example.rb <- Test code for Ruby extension
+ |
+ +- mrbgem.rake <- GEM specification
+ |
+ +- README.md
## C and Ruby Extension
@@ -164,21 +161,20 @@ See C and Ruby example.
### Example
-```
-+- c_and_ruby_extension_example/
- |
- +- mrblib/
- | |
- | +- example.rb <- Ruby extension source
- |
- +- src/
- | |
- | +- example.c <- C extension source
- |
- +- test/
- | |
- | +- example.rb <- Test code for C and Ruby extension
- |
- +- mrbgem.rake <- GEM specification
- |
- +- README.md
+ +- c_and_ruby_extension_example/
+ |
+ +- mrblib/
+ | |
+ | +- example.rb <- Ruby extension source
+ |
+ +- src/
+ | |
+ | +- example.c <- C extension source
+ |
+ +- test/
+ | |
+ | +- example.rb <- Test code for C and Ruby extension
+ |
+ +- mrbgem.rake <- GEM specification
+ |
+ +- README.md
diff --git a/doc/mrbgems/c_and_ruby_extension_example/src/example.c b/doc/mrbgems/c_and_ruby_extension_example/src/example.c
index 3d3cb20c9..7651ae5c0 100644
--- a/doc/mrbgems/c_and_ruby_extension_example/src/example.c
+++ b/doc/mrbgems/c_and_ruby_extension_example/src/example.c
@@ -13,3 +13,8 @@ mrb_c_and_ruby_extension_example_gem_init(mrb_state* mrb) {
struct RClass *class_cextension = mrb_define_module(mrb, "CRubyExtension");
mrb_define_class_method(mrb, class_cextension, "c_method", mrb_c_method, ARGS_NONE());
}
+
+void
+mrb_c_and_ruby_extension_example_gem_final(mrb_state* mrb) {
+ // finalizer
+}
diff --git a/doc/mrbgems/c_extension_example/src/example.c b/doc/mrbgems/c_extension_example/src/example.c
index 11f54e6d2..fa166186d 100644
--- a/doc/mrbgems/c_extension_example/src/example.c
+++ b/doc/mrbgems/c_extension_example/src/example.c
@@ -13,3 +13,8 @@ mrb_c_extension_example_gem_init(mrb_state* mrb) {
struct RClass *class_cextension = mrb_define_module(mrb, "CExtension");
mrb_define_class_method(mrb, class_cextension, "c_method", mrb_c_method, ARGS_NONE());
}
+
+void
+mrb_c_extension_example_gem_final(mrb_state* mrb) {
+ // finalizer
+}
diff --git a/mrblib/mrblib.rake b/mrblib/mrblib.rake
index 46d8c5a79..5b4070745 100644
--- a/mrblib/mrblib.rake
+++ b/mrblib/mrblib.rake
@@ -7,7 +7,7 @@ MRuby.each_target do
mrbc_, *rbfiles = t.prerequisites
FileUtils.mkdir_p File.dirname(t.name)
open(t.name, 'w') do |f|
- _pp "GEN *.rb > #{t.name}"
+ _pp "GEN", "*.rb", "#{t.name}"
f.puts File.read("#{dir}/init_mrblib.c")
mrbc.run f, rbfiles, 'mrblib_irep'
end
diff --git a/src/init.c b/src/init.c
index 48008b150..73ff8fce2 100644
--- a/src/init.c
+++ b/src/init.c
@@ -28,6 +28,7 @@ void mrb_init_time(mrb_state*);
void mrb_init_math(mrb_state*);
void mrb_init_mrblib(mrb_state*);
void mrb_init_mrbgems(mrb_state*);
+void mrb_final_mrbgems(mrb_state*);
#define DONE mrb_gc_arena_restore(mrb, 0);
void
@@ -70,3 +71,11 @@ mrb_init_core(mrb_state *mrb)
mrb_init_mrbgems(mrb); DONE;
#endif
}
+
+void
+mrb_final_core(mrb_state *mrb)
+{
+#ifndef DISABLE_GEMS
+ mrb_final_mrbgems(mrb); DONE;
+#endif
+} \ No newline at end of file
diff --git a/src/load.c b/src/load.c
index 504246799..78ece114f 100644
--- a/src/load.c
+++ b/src/load.c
@@ -138,7 +138,7 @@ load_rite_irep_record(mrb_state *mrb, RiteFILE* rfp, unsigned char* dst, uint32_
int i;
uint32_t blocklen;
uint16_t offset, pdl, snl, clen;
- unsigned char hex2[2], hex4[4], hex8[8], hcrc[4];
+ unsigned char hex2[2] = {0}, hex4[4] = {0}, hex8[8] = {0}, hcrc[4] = {0};
unsigned char *pStart;
char *char_buf;
uint16_t buf_size =0;
diff --git a/src/state.c b/src/state.c
index 60631b02d..e30b0cea3 100644
--- a/src/state.c
+++ b/src/state.c
@@ -11,6 +11,7 @@
void mrb_init_heap(mrb_state*);
void mrb_init_core(mrb_state*);
+void mrb_final_core(mrb_state*);
mrb_state*
mrb_open_allocf(mrb_allocf f, void *ud)
@@ -86,6 +87,8 @@ mrb_close(mrb_state *mrb)
{
int i;
+ mrb_final_core(mrb);
+
/* free */
mrb_gc_free_gv(mrb);
mrb_free(mrb, mrb->stbase);
diff --git a/tasks/libmruby.rake b/tasks/libmruby.rake
index 108f42f59..6f84937fd 100644
--- a/tasks/libmruby.rake
+++ b/tasks/libmruby.rake
@@ -2,14 +2,14 @@ MRuby.each_target do
file libfile("#{build_dir}/lib/libmruby") => libmruby.flatten do |t|
archiver.run t.name, t.prerequisites
open("#{build_dir}/lib/libmruby.flags.mak", 'w') do |f|
- f.puts 'CFLAGS = "%s"' % cc.all_flags.gsub('"', '\\"')
+ f.puts 'MRUBY_CFLAGS = "%s"' % cc.all_flags.gsub('"', '\\"')
gem_flags = gems.map { |g| g.linker.flags }
gem_library_paths = gems.map { |g| g.linker.library_paths }
- f.puts 'LDFLAGS = "%s"' % linker.all_flags(gem_library_paths, gem_flags).gsub('"', '\\"')
+ f.puts 'MRUBY_LDFLAGS = "%s"' % linker.all_flags(gem_library_paths, gem_flags).gsub('"', '\\"')
gem_libraries = gems.map { |g| g.linker.libraries }
- f.puts 'LIBS = "%s"' % linker.library_flags(gem_libraries).gsub('"', '\\"')
+ f.puts 'MRUBY_LIBS = "%s"' % linker.library_flags(gem_libraries).gsub('"', '\\"')
end
end
end
diff --git a/tasks/mrbgem_spec.rake b/tasks/mrbgem_spec.rake
index 906f47ad0..5af721b0d 100644
--- a/tasks/mrbgem_spec.rake
+++ b/tasks/mrbgem_spec.rake
@@ -105,6 +105,8 @@ module MRuby
print_gem_init_header f
build.mrbc.run f, rbfiles, "gem_mrblib_irep_#{funcname}" unless rbfiles.empty?
f.puts %Q[void mrb_#{funcname}_gem_init(mrb_state *mrb);]
+ f.puts %Q[void mrb_#{funcname}_gem_final(mrb_state *mrb);]
+ f.puts %Q[]
f.puts %Q[void GENERATED_TMP_mrb_#{funcname}_gem_init(mrb_state *mrb) {]
f.puts %Q[ int ai = mrb_gc_arena_save(mrb);]
f.puts %Q[ mrb_#{funcname}_gem_init(mrb);] if objs != [objfile("#{build_dir}/gem_init")]
@@ -117,6 +119,10 @@ module MRuby
end
f.puts %Q[ mrb_gc_arena_restore(mrb, ai);]
f.puts %Q[}]
+ f.puts %Q[]
+ f.puts %Q[void GENERATED_TMP_mrb_#{funcname}_gem_final(mrb_state *mrb) {]
+ f.puts %Q[ mrb_#{funcname}_gem_final(mrb);] if objs != [objfile("#{build_dir}/gem_init")]
+ f.puts %Q[}]
end
end # generate_gem_init
diff --git a/tasks/mrbgems.rake b/tasks/mrbgems.rake
index dc5e67eef..9d8798ef3 100644
--- a/tasks/mrbgems.rake
+++ b/tasks/mrbgems.rake
@@ -24,10 +24,18 @@ MRuby.each_target do
f.puts %Q[#include "mruby.h"]
f.puts %Q[]
f.puts %Q[#{gems.map{|g| "void GENERATED_TMP_mrb_%s_gem_init(mrb_state* mrb);" % g.funcname}.join("\n")}]
+ f.puts %Q[]
+ f.puts %Q[#{gems.map{|g| "void GENERATED_TMP_mrb_%s_gem_final(mrb_state* mrb);" % g.funcname}.join("\n")}]
+ f.puts %Q[]
f.puts %Q[void]
f.puts %Q[mrb_init_mrbgems(mrb_state *mrb) {]
f.puts %Q[#{gems.map{|g| "GENERATED_TMP_mrb_%s_gem_init(mrb);" % g.funcname}.join("\n")}]
f.puts %Q[}]
+ f.puts %Q[]
+ f.puts %Q[void]
+ f.puts %Q[mrb_final_mrbgems(mrb_state *mrb) {]
+ f.puts %Q[#{gems.map{|g| "GENERATED_TMP_mrb_%s_gem_final(mrb);" % g.funcname}.join("\n")}]
+ f.puts %Q[}]
end
end
end
diff --git a/tasks/mruby_build.rake b/tasks/mruby_build.rake
index b9e0d2749..711f7f024 100644
--- a/tasks/mruby_build.rake
+++ b/tasks/mruby_build.rake
@@ -29,10 +29,6 @@ module MRuby
conf.instance_eval(&@initializer)
end
- def toolchain(name)
- @@toolchains[name.to_s].setup(self)
- end
-
def self.load
Dir.glob("#{File.dirname(__FILE__)}/toolchains/*.rake").each do |file|
Kernel.load file
@@ -93,7 +89,9 @@ module MRuby
end
def toolchain(name)
- Toolchain.toolchains[name.to_s].setup(self)
+ tc = Toolchain.toolchains[name.to_s]
+ fail "Unknown #{name} toolchain" unless tc
+ tc.setup(self)
end
def build_dir
diff --git a/tasks/mruby_build_commands.rake b/tasks/mruby_build_commands.rake
index 8ffafe9b0..533f0fe62 100644
--- a/tasks/mruby_build_commands.rake
+++ b/tasks/mruby_build_commands.rake
@@ -58,7 +58,7 @@ module MRuby
include_path_flags = [include_paths, _include_paths, File.dirname(infile)].flatten.map do |f|
option_include_path % filename(f)
end
- _pp "CC #{filename(infile)} > #{filename(outfile)}"
+ _pp "CC", "#{filename(infile)}", "#{filename(outfile)}"
_run compile_options, { :flags => (flags + define_flags + include_path_flags + _flags).join(' '),
:infile => filename(infile), :outfile => filename(outfile) }
end
@@ -131,7 +131,7 @@ module MRuby
FileUtils.mkdir_p File.dirname(outfile)
library_flags = [libraries, _libraries].flatten.reverse.map{ |d| option_library % d }
library_path_flags = [library_paths, _library_paths].flatten.map{ |f| option_library_path % filename(f) }
- _pp "LD #{filename(outfile)}"
+ _pp "LD", "#{filename(outfile)}"
_run link_options, { :flags => (flags + library_path_flags + _flags).join(' '),
:outfile => filename(outfile) , :objs => filename(objfiles).join(' '),
:libs => library_flags.join(' ') }
@@ -149,7 +149,7 @@ module MRuby
def run(outfile, objfiles)
FileUtils.mkdir_p File.dirname(outfile)
- _pp "AR #{filename(outfile)}"
+ _pp "AR", "#{filename(outfile)}"
_run archive_options, { :outfile => filename(outfile), :objs => filename(objfiles).join(' ') }
end
end
@@ -165,7 +165,7 @@ module MRuby
def run(outfile, infile)
FileUtils.mkdir_p File.dirname(outfile)
- _pp "YACC #{filename(infile)} > #{filename(outfile)}"
+ _pp "YACC", "#{filename(infile)}", "#{filename(outfile)}"
_run compile_options, { :outfile => filename(outfile) , :infile => filename(infile) }
end
end
@@ -181,7 +181,7 @@ module MRuby
def run(outfile, infile)
FileUtils.mkdir_p File.dirname(outfile)
- _pp "GPERF #{filename(infile)} > #{filename(outfile)}"
+ _pp "GPERF", "#{filename(infile)}", "#{filename(outfile)}"
_run compile_options, { :outfile => filename(outfile) , :infile => filename(infile) }
end
end
@@ -198,7 +198,7 @@ module MRuby
end
def run_clone(dir, url, _flags = [])
- _pp "GIT #{url} > #{filename(dir)}"
+ _pp "GIT", "#{url}", "#{filename(dir)}"
_run clone_options, { :flags => [flags, _flags].flatten.join(' '), :url => url, :dir => filename(dir) }
end
end
@@ -214,7 +214,7 @@ module MRuby
@command ||= @build.mrbcfile
IO.popen("#{filename @command} #{@compile_options % {:funcname => funcname}}", 'r+') do |io|
[infiles].flatten.each do |f|
- _pp " MRBC #{f}"
+ _pp "MRBC", "#{f}", nil, :indent => 2
io.write IO.read(f)
end
io.close_write
diff --git a/tasks/mruby_build_gem.rake b/tasks/mruby_build_gem.rake
index ae0a79447..80990773d 100644
--- a/tasks/mruby_build_gem.rake
+++ b/tasks/mruby_build_gem.rake
@@ -2,7 +2,11 @@ module MRuby
module LoadGems
def gem(gemdir, &block)
gemdir = load_external_gem(gemdir) if gemdir.is_a?(Hash)
- load File.join(gemdir, "mrbgem.rake")
+ gemrake = File.join(gemdir, "mrbgem.rake")
+
+ fail "Can't find #{gemrake}" unless File.exists?(gemrake)
+ load gemrake
+
Gem.current.dir = gemdir
Gem.current.build = MRuby::Build.current
Gem.current.build_config_initializer = block
diff --git a/tasks/ruby_ext.rake b/tasks/ruby_ext.rake
index 2536a2e4b..6817f6018 100644
--- a/tasks/ruby_ext.rake
+++ b/tasks/ruby_ext.rake
@@ -57,6 +57,10 @@ else
$pp_show = false if $verbose
end
-def _pp(msg)
- puts msg if $pp_show
+def _pp(cmd, src, tgt=nil, options={})
+ return unless $pp_show
+
+ width = 5
+ template = options[:indent] ? "%#{width*options[:indent]}s %s %s" : "%-#{width}s %s %s"
+ puts template % [cmd, src, tgt ? "-> #{tgt}" : nil]
end
diff --git a/tasks/toolchains/clang.rake b/tasks/toolchains/clang.rake
index 01dd5f234..1785c4c79 100644
--- a/tasks/toolchains/clang.rake
+++ b/tasks/toolchains/clang.rake
@@ -1,6 +1,8 @@
MRuby::Toolchain.new(:clang) do |conf|
toolchain :gcc
- conf.cc.command = ENV['CC'] || 'clang'
+ [conf.cc, conf.cxx, conf.objc].each do |cc|
+ cc.command = ENV['CC'] || 'clang'
+ end
conf.linker.command = ENV['LD'] || 'clang'
end
diff --git a/tasks/toolchains/gcc.rake b/tasks/toolchains/gcc.rake
index c624c8fc9..54fd3ecd8 100644
--- a/tasks/toolchains/gcc.rake
+++ b/tasks/toolchains/gcc.rake
@@ -1,5 +1,5 @@
MRuby::Toolchain.new(:gcc) do |conf|
- conf.cc do |cc|
+ [conf.cc, conf.cxx, conf.objc].each do |cc|
cc.command = ENV['CC'] || 'gcc'
cc.flags = [ENV['CFLAGS'] || %w(-g -O3 -Wall -Werror-implicit-function-declaration)]
cc.include_paths = ["#{root}/include"]
diff --git a/tasks/toolchains/vs2012.rake b/tasks/toolchains/vs2012.rake
index c3599a59b..b5d2298c2 100644
--- a/tasks/toolchains/vs2012.rake
+++ b/tasks/toolchains/vs2012.rake
@@ -1,5 +1,5 @@
MRuby::Toolchain.new(:vs2012) do |conf|
- conf.cc do |cc|
+ [conf.cc, conf.cxx].each do |cc|
cc.command = ENV['CC'] || 'cl.exe'
cc.flags = [ENV['CFLAGS'] || %w(/c /nologo /W3 /D_DEBUG /MDd /Zi /Od /RTC1 /DDISABLE_GEMS /DHAVE_STRING_H /DNO_GETTIMEOFDAY /D_CRT_SECURE_NO_WARNINGS)]
cc.include_paths = ["#{root}/include"]
diff --git a/test/mrbtest.rake b/test/mrbtest.rake
index 76ddc30f8..10d8eccb6 100644
--- a/test/mrbtest.rake
+++ b/test/mrbtest.rake
@@ -19,7 +19,7 @@ MRuby.each_target do
file mlib => [clib]
file clib => [mrbcfile, init, asslib] + mrbs do |t|
- _pp "GEN *.rb > #{clib}"
+ _pp "GEN", "*.rb", "#{clib}"
open(clib, 'w') do |f|
f.puts IO.read(init)
mrbc.run f, [asslib] + mrbs, 'mrbtest_irep'
diff --git a/tools/mrbc/mrbc.c b/tools/mrbc/mrbc.c
index 4dc9871c7..63762143a 100644
--- a/tools/mrbc/mrbc.c
+++ b/tools/mrbc/mrbc.c
@@ -231,4 +231,9 @@ void
mrb_init_mrbgems(mrb_state *mrb)
{
}
+
+void
+mrb_final_mrbgems(mrb_state *mrb)
+{
+}
#endif