diff options
| -rw-r--r-- | doc/mrbgems/README.md | 160 | ||||
| -rw-r--r-- | doc/mrbgems/c_and_ruby_extension_example/src/example.c | 5 | ||||
| -rw-r--r-- | doc/mrbgems/c_extension_example/src/example.c | 5 | ||||
| -rw-r--r-- | src/init.c | 9 | ||||
| -rw-r--r-- | src/state.c | 3 | ||||
| -rw-r--r-- | tasks/mrbgem_spec.rake | 6 | ||||
| -rw-r--r-- | tasks/mrbgems.rake | 8 | ||||
| -rw-r--r-- | tasks/toolchains/clang.rake | 4 | ||||
| -rw-r--r-- | tasks/toolchains/gcc.rake | 2 | ||||
| -rw-r--r-- | tasks/toolchains/vs2012.rake | 2 | ||||
| -rw-r--r-- | tools/mrbc/mrbc.c | 5 |
11 files changed, 124 insertions, 85 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/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/state.c b/src/state.c index c1ad4c6ad..c48997a7c 100644 --- a/src/state.c +++ b/src/state.c @@ -12,6 +12,7 @@ void mrb_init_heap(mrb_state*); void mrb_init_core(mrb_state*); void mrb_init_ext(mrb_state*); +void mrb_final_core(mrb_state*); mrb_state* mrb_open_allocf(mrb_allocf f, void *ud) @@ -88,6 +89,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/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/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/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 |
