diff options
| author | Yuichiro MASUI <[email protected]> | 2013-01-20 22:48:42 +0900 |
|---|---|---|
| committer | Yuichiro MASUI <[email protected]> | 2013-01-20 22:48:42 +0900 |
| commit | ced80d2b4b1ed4ef0752a8bbaf0dbfe7aa6c6a95 (patch) | |
| tree | d49c0d0f0b6139ad4c79c3e4b417d65941e97a4f /tasks/mrbgem_spec.rake | |
| parent | 583983385b81c21f82704b116eab52d606a609f4 (diff) | |
| download | mruby-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.rake | 139 |
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 |
