merge master

This commit is contained in:
Yuichiro MASUI
2013-01-24 11:21:39 +09:00
20 changed files with 172 additions and 126 deletions
+8 -1
View File
@@ -42,7 +42,14 @@ depfiles += MRuby.targets.reject { |n, t| n == 'host' }.map { |n, t|
}.flatten
desc "build all targets, install (locally) in-repo"
task :all => depfiles
task :all => depfiles do
puts
puts "Build summary:"
puts
MRuby.each_target do
print_build_summary
end
end
desc "run all mruby tests"
task :test => MRuby.targets.values.map { |t| t.exefile("#{t.build_dir}/test/mrbtest") } do
+78 -82
View File
@@ -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
@@ -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
}
@@ -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
}
+1 -1
View File
@@ -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
+9
View File
@@ -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
}
-16
View File
@@ -1,16 +0,0 @@
/*
** init_ext.c - initialize extend libraries
**
** See Copyright Notice in mruby.h
*/
#include "mruby.h"
void
mrb_init_ext(mrb_state *mrb)
{
#ifdef INCLUDE_SOCKET
extern void mrb_init_socket(mrb_state *mrb);
mrb_init_socket(mrb);
#endif
}
+1 -1
View File
@@ -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;
+3 -2
View File
@@ -11,7 +11,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)
@@ -27,7 +27,6 @@ mrb_open_allocf(mrb_allocf f, void *ud)
mrb_init_heap(mrb);
mrb_init_core(mrb);
mrb_init_ext(mrb);
return mrb;
}
@@ -88,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);
+6
View File
@@ -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
+8
View File
@@ -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
+13 -5
View File
@@ -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
@@ -148,6 +146,16 @@ module MRuby
sh "#{filename mrbtest}"
puts
end
def print_build_summary
puts "================================================"
puts " Config Name: #{@name}"
puts " Output Directory: #{self.build_dir}"
puts " Binaries: #{@bins.join(', ')}" unless @bins.empty?
puts " Included Gems: #{@gems.map{|g| g.name }.join(', ')}" unless @gems.empty?
puts "================================================"
puts
end
end # Build
class CrossBuild < Build
+13 -11
View File
@@ -56,8 +56,12 @@ module MRuby
def run(outfile, infile, _defineds=[], _include_paths=[], _flags=[])
FileUtils.mkdir_p File.dirname(outfile)
_pp "CC #{filename(infile)} > #{filename(outfile)}"
_run compile_options, { :flags => all_flags(_defineds, [_include_paths, File.dirname(infile)], _flags),
define_flags = [defines, _defineds].flatten.map{ |d| option_define % d }
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)}"
_run compile_options, { :flags => all_flags(_defineds, _include_paths, _flags),
:infile => filename(infile), :outfile => filename(outfile) }
end
@@ -125,14 +129,12 @@ module MRuby
end
def library_flags(_libraries)
[libraries, _libraries].flatten.reverse.map do |d|
option_library % d
end.join(' ')
[libraries, _libraries].flatten.map{ |d| option_library % d }.join(' ')
end
def run(outfile, objfiles, _libraries=[], _library_paths=[], _flags=[], _flags_before_libraries=[])
FileUtils.mkdir_p File.dirname(outfile)
library_flags = [libraries, _libraries].flatten.reverse.map { |d| option_library % d }
library_flags = [libraries, _libraries].flatten.map { |d| option_library % d }
library_path_flags = [library_paths, _library_paths].flatten.map { |f| option_library_path % filename(f) }
_pp "LD #{filename(outfile)}"
_run link_options, { :flags => all_flags(_library_paths, _flags),
@@ -153,7 +155,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
@@ -169,7 +171,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
@@ -185,7 +187,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
@@ -202,7 +204,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
@@ -218,7 +220,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
+5 -1
View File
@@ -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
+6 -2
View File
@@ -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
+3 -1
View File
@@ -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
+1 -1
View File
@@ -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"]
+1 -1
View File
@@ -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"]
+1 -1
View File
@@ -20,7 +20,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'
+5
View File
@@ -231,4 +231,9 @@ void
mrb_init_mrbgems(mrb_state *mrb)
{
}
void
mrb_final_mrbgems(mrb_state *mrb)
{
}
#endif