summaryrefslogtreecommitdiffhomepage
path: root/tasks/mrbgem_spec.rake
diff options
context:
space:
mode:
authorYuichiro MASUI <[email protected]>2013-01-20 22:48:42 +0900
committerYuichiro MASUI <[email protected]>2013-01-20 22:48:42 +0900
commitced80d2b4b1ed4ef0752a8bbaf0dbfe7aa6c6a95 (patch)
treed49c0d0f0b6139ad4c79c3e4b417d65941e97a4f /tasks/mrbgem_spec.rake
parent583983385b81c21f82704b116eab52d606a609f4 (diff)
downloadmruby-ced80d2b4b1ed4ef0752a8bbaf0dbfe7aa6c6a95.tar.gz
mruby-ced80d2b4b1ed4ef0752a8bbaf0dbfe7aa6c6a95.zip
Improved build scripts and config files
Diffstat (limited to 'tasks/mrbgem_spec.rake')
-rw-r--r--tasks/mrbgem_spec.rake139
1 files changed, 139 insertions, 0 deletions
diff --git a/tasks/mrbgem_spec.rake b/tasks/mrbgem_spec.rake
new file mode 100644
index 000000000..e21e0b670
--- /dev/null
+++ b/tasks/mrbgem_spec.rake
@@ -0,0 +1,139 @@
+require 'pathname'
+require 'forwardable'
+
+module MRuby
+ module Gem
+ class << self
+ attr_accessor :current
+ end
+ LinkerConfig = Struct.new(:libraries, :library_paths, :flags)
+
+ class Specification
+ include Rake::DSL
+ extend Forwardable
+ def_delegators :@build, :filename, :objfile, :libfile, :exefile
+
+ attr_accessor :name, :dir, :build
+ alias mruby build
+ attr_accessor :build_config_initializer
+
+ attr_accessor :licenses, :authors
+ alias :license= :licenses=
+ alias :author= :authors=
+
+ attr_accessor :rbfiles, :objs
+ attr_accessor :test_objs, :test_rbfiles
+ attr_accessor :test_preload
+
+ attr_block MRuby::Build::COMMANDS
+
+ def initialize(name, &block)
+ @name = name
+ @initializer = block
+ MRuby::Gem.current = self
+ end
+
+ def setup
+ MRuby::Gem.current = self
+ MRuby::Build::COMMANDS.each do |command|
+ instance_variable_set("@#{command}", @build.send(command).clone)
+ end
+ @linker = LinkerConfig.new([], [], [])
+
+ compilers.each do |compiler|
+ compiler.defines -= %w(DISABLE_GEMS)
+ compiler.include_paths << "#{dir}/include"
+ end
+
+ @rbfiles = Dir.glob("#{dir}/mrblib/*.rb")
+ @objs = Dir.glob("#{dir}/src/*.{c,cpp,m,asm,S}").map { |f| objfile(f.relative_path_from(@dir).to_s.pathmap("#{build_dir}/%X")) }
+ @objs << objfile("#{build_dir}/gem_init")
+
+ @test_rbfiles = Dir.glob("#{dir}/test/*.rb")
+ @test_objs = Dir.glob("#{dir}/test/*.{c,cpp,m,asm,S}").map { |f| objfile(f.relative_path_from(dir).to_s.pathmap("#{build_dir}/%X")) }
+ @test_preload = 'test/assert.rb'
+
+ instance_eval(&@initializer)
+
+ if !name || !licenses || !authors
+ fail "#{name || dir} required to set name, license(s) and author(s)"
+ end
+
+ build.libmruby << @objs
+
+ instance_eval(&@build_config_initializer) if @build_config_initializer
+
+ compilers.each do |compiler|
+ compiler.define_rules build_dir, "#{dir}/"
+ end
+
+ define_gem_init_builder
+ end
+
+ def build_dir
+ "#{build.build_dir}/mrbgems/#{name}"
+ end
+
+ def testlib
+ libfile("#{build_dir}/libmrb-#{name}-gem-test")
+ end
+
+ def funcname
+ @funcname ||= @name.gsub('-', '_')
+ end
+
+ def compilers
+ MRuby::Build::COMPILERS.map do |c|
+ instance_variable_get("@#{c}")
+ end
+ end
+
+ def define_gem_init_builder
+ file objfile("#{build_dir}/gem_init") => "#{build_dir}/gem_init.c"
+ file "#{build_dir}/gem_init.c" => [build.mrbcfile] + rbfiles do |t|
+ FileUtils.mkdir_p build_dir
+ generate_gem_init("#{build_dir}/gem_init.c")
+ end
+ end
+
+ def generate_gem_init(fname)
+ open(fname, 'w') do |f|
+ 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 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")]
+ unless rbfiles.empty?
+ f.puts %Q[ mrb_load_irep(mrb, gem_mrblib_irep_#{funcname});]
+ f.puts %Q[ if (mrb->exc) {]
+ f.puts %Q[ mrb_p(mrb, mrb_obj_value(mrb->exc));]
+ f.puts %Q[ exit(0);]
+ f.puts %Q[ }]
+ end
+ f.puts %Q[ mrb_gc_arena_restore(mrb, ai);]
+ f.puts %Q[}]
+ end
+ end # generate_gem_init
+
+ def print_gem_init_header(f)
+ f.puts %Q[/*]
+ f.puts %Q[ * This file is loading the irep]
+ f.puts %Q[ * Ruby GEM code.]
+ f.puts %Q[ *]
+ f.puts %Q[ * IMPORTANT:]
+ f.puts %Q[ * This file was generated!]
+ f.puts %Q[ * All manual changes will get lost.]
+ f.puts %Q[ */]
+ f.puts %Q[#include "mruby.h"]
+ f.puts %Q[#include "mruby/irep.h"]
+ f.puts %Q[#include "mruby/dump.h"]
+ f.puts %Q[#include "mruby/string.h"]
+ f.puts %Q[#include "mruby/proc.h"]
+ f.puts %Q[#include "mruby/variable.h"]
+ f.puts %Q[#include "mruby/array.h"]
+ end
+
+ end # Specification
+ end # Gem
+end # MRuby