diff options
Diffstat (limited to 'tasks')
| -rw-r--r-- | tasks/benchmark.rake | 91 | ||||
| -rw-r--r-- | tasks/mrbgem_spec.rake | 13 | ||||
| -rw-r--r-- | tasks/mrbgems.rake | 21 | ||||
| -rw-r--r-- | tasks/mrbgems_test.rake | 9 | ||||
| -rw-r--r-- | tasks/mruby_build.rake | 51 | ||||
| -rw-r--r-- | tasks/mruby_build_gem.rake | 2 | ||||
| -rw-r--r-- | tasks/ruby_ext.rake | 11 | ||||
| -rw-r--r-- | tasks/toolchains/gcc.rake | 2 | ||||
| -rw-r--r-- | tasks/toolchains/visualcpp.rake | 2 |
9 files changed, 182 insertions, 20 deletions
diff --git a/tasks/benchmark.rake b/tasks/benchmark.rake new file mode 100644 index 000000000..84e69ebee --- /dev/null +++ b/tasks/benchmark.rake @@ -0,0 +1,91 @@ +module MRuby + BENCHMARK_REPEAT = 4 +end + +$dat_files = [] + +def bm_files + Dir.glob("#{MRUBY_ROOT}/benchmark/bm_*.rb") +end + +def build_config_name + if ENV['MRUBY_CONFIG'] + File.basename(ENV['MRUBY_CONFIG'], '.rb').gsub('build_config_', '') + else + "build" + end +end + +def plot_file + File.join(MRUBY_ROOT, 'benchmark', "#{build_config_name}.png") +end + +def plot + opts_file = "#{MRUBY_ROOT}/benchmark/plot.gpl" + opts = File.read(opts_file).each_line.to_a.map(&:strip).join(';') + + dat_files = $dat_files.group_by {|f| File.dirname(f).split(File::SEPARATOR)[-1]} + + opts += ";set output '#{plot_file}'" + + opts += ';plot ' + + opts += dat_files.keys.map do |data_file| + %Q['-' u 2:3:4:xtic(1) w hist title columnheader(1)] + end.join(',') + opts += ';' + + cmd = %Q{gnuplot -p -e "#{opts}"} + + IO.popen(cmd, 'w') do |p| + dat_files.each do |target_name, bm_files| + p.puts target_name.gsub('_', '-') + bm_files.each do |bm_file| + p.write File.read(bm_file) + end + p.puts "e" + end + end +end + + +MRuby.each_target do |target| + next if target.name == 'host' + mruby_bin = "#{target.build_dir}/bin/mruby" + + bm_files.each do |bm_file| + bm_name = File.basename bm_file, ".rb" + + dat_dir = File.join('benchmark', build_config_name, target.name) + dat_file = File.join(dat_dir, "#{bm_name}.dat") + $dat_files << dat_file + + directory dat_dir + + file dat_file => [bm_file, dat_dir, mruby_bin] do |task| + print bm_name + puts "..." + + data = (0...MRuby::BENCHMARK_REPEAT).map do |n| + str = %x{(time -f "%e %S %U" #{mruby_bin} #{bm_file}) 2>&1 >/dev/null} + str.split(' ').map(&:to_f) + end + + File.open(task.name, "w") do |f| + data = data.map {|_,r,s| (r + s) / 2.0} + min = data.min + max = data.max + avg = data.inject(&:+) / data.size + f.puts "#{bm_name.gsub('_', '-')} #{avg} #{min} #{max}" + end + end + end +end + +file plot_file => $dat_files do + plot +end + +task :benchmark => plot_file do + plot +end diff --git a/tasks/mrbgem_spec.rake b/tasks/mrbgem_spec.rake index 745b2f29d..e6e17e182 100644 --- a/tasks/mrbgem_spec.rake +++ b/tasks/mrbgem_spec.rake @@ -36,6 +36,8 @@ module MRuby attr_accessor :export_include_paths + attr_reader :generate_functions + attr_block MRuby::Build::COMMANDS def initialize(name, &block) @@ -56,7 +58,9 @@ module MRuby @objs = Dir.glob("#{dir}/src/*.{c,cpp,cxx,cc,m,asm,s,S}").map do |f| objfile(f.relative_path_from(@dir).to_s.pathmap("#{build_dir}/%X")) end - @objs << objfile("#{build_dir}/gem_init") + + @generate_functions = !(@rbfiles.empty? && @objs.empty?) + @objs << objfile("#{build_dir}/gem_init") if @generate_functions @test_rbfiles = Dir.glob("#{dir}/test/*.rb") @test_objs = Dir.glob("#{dir}/test/*.{c,cpp,cxx,cc,m,asm,s,S}").map do |f| @@ -89,7 +93,7 @@ module MRuby compiler.include_paths << "#{dir}/include" if File.directory? "#{dir}/include" end - define_gem_init_builder + define_gem_init_builder if @generate_functions end def add_dependency(name, *requirements) @@ -179,6 +183,7 @@ module MRuby def print_gem_test_header(f) print_gem_comment(f) + f.puts %Q[#include <stdio.h>] f.puts %Q[#include <stdlib.h>] f.puts %Q[#include "mruby.h"] f.puts %Q[#include "mruby/irep.h"] @@ -293,7 +298,7 @@ module MRuby @ary.empty? end - def generate_gem_table + def generate_gem_table build gem_table = @ary.reduce({}) { |res,v| res[v.name] = v; res } default_gems = [] @@ -376,7 +381,7 @@ module MRuby end def check(build) - gem_table = generate_gem_table + gem_table = generate_gem_table build @ary = tsort_dependencies gem_table.keys, gem_table, true diff --git a/tasks/mrbgems.rake b/tasks/mrbgems.rake index 2d17be931..1cf05ee4e 100644 --- a/tasks/mrbgems.rake +++ b/tasks/mrbgems.rake @@ -10,6 +10,17 @@ MRuby.each_target do file "#{build_dir}/mrbgems/gem_init.c" => [MRUBY_CONFIG, __FILE__] do |t| FileUtils.mkdir_p "#{build_dir}/mrbgems" open(t.name, 'w') do |f| + gem_func_gems = gems.select { |g| g.generate_functions } + gem_func_decls = gem_func_gems.each_with_object('') do |g, s| + s << "void GENERATED_TMP_mrb_#{g.funcname}_gem_init(mrb_state*);\n" \ + "void GENERATED_TMP_mrb_#{g.funcname}_gem_final(mrb_state*);\n" + end + gem_init_calls = gem_func_gems.each_with_object('') do |g, s| + s << " GENERATED_TMP_mrb_#{g.funcname}_gem_init(mrb);\n" + end + gem_final_calls = gem_func_gems.each_with_object('') do |g, s| + s << " GENERATED_TMP_mrb_#{g.funcname}_gem_final(mrb);\n" + end f.puts %Q[/*] f.puts %Q[ * This file contains a list of all] f.puts %Q[ * initializing methods which are] @@ -22,19 +33,17 @@ MRuby.each_target do f.puts %Q[] 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.write gem_func_decls f.puts %Q[] f.puts %Q[static 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.write gem_final_calls f.puts %Q[}] 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[mrb_state_atexit(mrb, mrb_final_mrbgems);] + f.write gem_init_calls + f.puts %Q[ mrb_state_atexit(mrb, mrb_final_mrbgems);] unless gem_final_calls.empty? f.puts %Q[}] end end diff --git a/tasks/mrbgems_test.rake b/tasks/mrbgems_test.rake index b732fa772..0ee508360 100644 --- a/tasks/mrbgems_test.rake +++ b/tasks/mrbgems_test.rake @@ -1,13 +1,14 @@ MRuby.each_target do - gem_table = gems.generate_gem_table + gem_table = gems.generate_gem_table self gems.each do |g| test_rbobj = g.test_rbireps.ext(exts.object) g.test_objs << test_rbobj - dep_list = gems.tsort_dependencies g.test_dependencies, gem_table + dep_list = gems.tsort_dependencies(g.test_dependencies, gem_table).select(&:generate_functions) file test_rbobj => g.test_rbireps file g.test_rbireps => [g.test_rbfiles].flatten + [File.join(g.dir, 'mrbgem.rake'), g.build.mrbcfile, __FILE__, "#{MRUBY_ROOT}/tasks/mrbgem_spec.rake"] do |t| + FileUtils.mkdir_p File.dirname(t.name) open(t.name, 'w') do |f| g.print_gem_test_header(f) test_preload = g.test_preload and [g.dir, MRUBY_ROOT].map {|dir| @@ -46,6 +47,10 @@ MRuby.each_target do g.test_rbfiles.count.times do |i| f.puts %Q[ ai = mrb_gc_arena_save(mrb);] f.puts %Q[ mrb2 = mrb_open_core(mrb_default_allocf, NULL);] + f.puts %Q[ if (mrb2 == NULL) {] + f.puts %Q[ fprintf(stderr, "Invalid mrb_state, exiting \%s", __FUNCTION__);] + f.puts %Q[ exit(EXIT_FAILURE);] + f.puts %Q[ }] dep_list.each do |d| f.puts %Q[ GENERATED_TMP_mrb_#{d.funcname}_gem_init(mrb2);] f.puts %Q[ mrb_state_atexit(mrb2, GENERATED_TMP_mrb_#{d.funcname}_gem_final);] diff --git a/tasks/mruby_build.rake b/tasks/mruby_build.rake index 06bb2a4e6..50bed0fbe 100644 --- a/tasks/mruby_build.rake +++ b/tasks/mruby_build.rake @@ -8,6 +8,7 @@ module MRuby end def each_target(&block) + return to_enum(:each_target) if block.nil? @targets.each do |key, target| target.instance_eval(&block) end @@ -79,7 +80,7 @@ module MRuby @git = Command::Git.new(self) @mrbc = Command::Mrbc.new(self) - @bins = %w(mrbc) + @bins = [] @gems, @libmruby = MRuby::Gem::List.new, [] @build_mrbtest_lib_only = false @cxx_abi_enabled = false @@ -91,10 +92,17 @@ module MRuby MRuby::Build.current = MRuby.targets[@name] MRuby.targets[@name].instance_eval(&block) + + build_mrbc_exec if name == 'host' end def enable_debug - compilers.each { |c| c.defines += %w(MRB_DEBUG) } + compilers.each do |c| + c.defines += %w(MRB_DEBUG) + if toolchains.any? { |toolchain| toolchain == "gcc" } + c.flags += %w(-g3 -O0) + end + end @mrbc.compile_options += ' -g' end @@ -109,10 +117,37 @@ module MRuby def enable_cxx_abi return if @cxx_exception_disabled or @cxx_abi_enabled compilers.each { |c| c.defines += %w(MRB_ENABLE_CXX_EXCEPTION) } - linker.command = cxx.command + linker.command = cxx.command if toolchains.find { |v| v == 'gcc' } @cxx_abi_enabled = true end + def compile_as_cxx src, cxx_src, obj = nil, includes = [] + src = File.absolute_path src + cxx_src = File.absolute_path cxx_src + obj = objfile(cxx_src) if obj.nil? + + file cxx_src => [src, __FILE__] do |t| + File.open(t.name, 'w') do |f| + f.write <<EOS +#define __STDC_CONSTANT_MACROS +#define __STDC_LIMIT_MACROS + +extern "C" { +#include "#{src}" +} + +#{File.basename(src) == 'error.c'? 'mrb_int mrb_jmpbuf::jmpbuf_id = 0;' : ''} +EOS + end + end + + file obj => cxx_src do |t| + cxx.run t.name, t.prerequisites.first, [], ["#{MRUBY_ROOT}/src"] + includes + end + + obj + end + def enable_bintest @enable_bintest = true end @@ -136,8 +171,16 @@ module MRuby MRUBY_ROOT end + def build_mrbc_exec + gem :core => 'mruby-bin-mrbc' + end + def mrbcfile - MRuby.targets[@name].exefile("#{MRuby.targets[@name].build_dir}/bin/mrbc") + return @mrbcfile if @mrbcfile + + mrbc_build = MRuby.targets['host'] + gems.each { |v| mrbc_build = self if v.name == 'mruby-bin-mrbc' } + @mrbcfile = mrbc_build.exefile("#{mrbc_build.build_dir}/bin/mrbc") end def compilers diff --git a/tasks/mruby_build_gem.rake b/tasks/mruby_build_gem.rake index 5d2dc030c..dbbade487 100644 --- a/tasks/mruby_build_gem.rake +++ b/tasks/mruby_build_gem.rake @@ -31,7 +31,7 @@ module MRuby return nil unless Gem.current Gem.current.dir = gemdir - Gem.current.build = MRuby::Build.current + Gem.current.build = self.is_a?(MRuby::Build) ? self : MRuby::Build.current Gem.current.build_config_initializer = block gems << Gem.current diff --git a/tasks/ruby_ext.rake b/tasks/ruby_ext.rake index 38dfff0a3..4c6d3ca76 100644 --- a/tasks/ruby_ext.rake +++ b/tasks/ruby_ext.rake @@ -22,7 +22,7 @@ class String if params.is_a?(Hash) str = self.clone params.each do |k, v| - str.gsub!("%{#{k}}", v) + str.gsub!("%{#{k}}") { v } end str else @@ -42,6 +42,15 @@ class Symbol end end +module Enumerable + # Compatible with 1.9 on 1.8 + def each_with_object(memo) + return to_enum :each_with_object, memo unless block_given? + each { |obj| yield obj, memo } + memo + end +end + $pp_show = true if $verbose.nil? diff --git a/tasks/toolchains/gcc.rake b/tasks/toolchains/gcc.rake index 7edf93642..fb1455812 100644 --- a/tasks/toolchains/gcc.rake +++ b/tasks/toolchains/gcc.rake @@ -1,7 +1,7 @@ MRuby::Toolchain.new(:gcc) do |conf| [conf.cc, conf.objc, conf.asm].each do |cc| cc.command = ENV['CC'] || 'gcc' - cc.flags = [ENV['CFLAGS'] || %w(-g -std=gnu99 -O3 -Wall -Werror-implicit-function-declaration -Wdeclaration-after-statement)] + cc.flags = [ENV['CFLAGS'] || %w(-g -std=gnu99 -O3 -Wall -Werror-implicit-function-declaration -Wdeclaration-after-statement -Wwrite-strings)] cc.defines = %w(DISABLE_GEMS) cc.option_include_path = '-I%s' cc.option_define = '-D%s' diff --git a/tasks/toolchains/visualcpp.rake b/tasks/toolchains/visualcpp.rake index 8838f8a41..eaf013068 100644 --- a/tasks/toolchains/visualcpp.rake +++ b/tasks/toolchains/visualcpp.rake @@ -11,7 +11,7 @@ MRuby::Toolchain.new(:visualcpp) do |conf| [conf.cxx].each do |cxx| cxx.command = ENV['CXX'] || 'cl.exe' - cxx.flags = [ENV['CXXFLAGS'] || ENV['CFLAGS'] || %w(/c /nologo /W3 /Zi /MD /O2 /EHsc /D_CRT_SECURE_NO_WARNINGS)] + cxx.flags = [ENV['CXXFLAGS'] || ENV['CFLAGS'] || %w(/c /nologo /W3 /Zi /MD /O2 /EHs /D_CRT_SECURE_NO_WARNINGS)] cxx.defines = %w(DISABLE_GEMS MRB_STACK_EXTEND_DOUBLING) cxx.option_include_path = '/I%s' cxx.option_define = '/D%s' |
