summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.travis.yml4
-rw-r--r--build_config.rb3
-rw-r--r--include/mruby.h4
-rwxr-xr-xminirake129
-rw-r--r--mrbgems/mruby-bin-mirb/tools/mirb/mirb.c6
-rw-r--r--mrbgems/mruby-bin-mruby-config/mrbgem.rake5
-rw-r--r--mrbgems/mruby-compiler/mrbgem.rake4
-rw-r--r--mrbgems/mruby-io/mrbgem.rake3
-rw-r--r--mrbgems/mruby-test/mrbgem.rake18
-rw-r--r--tasks/libmruby.rake1
-rw-r--r--tasks/mrbgems.rake1
11 files changed, 147 insertions, 31 deletions
diff --git a/.travis.yml b/.travis.yml
index 56c54914a..d8c22c046 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,7 +5,7 @@ sudo: false
matrix:
include:
- os: linux
- sudo: 9000
+ sudo: false
- os: osx
osx_image: xcode7.1
@@ -17,4 +17,4 @@ addons:
env:
MRUBY_CONFIG=travis_config.rb
env: MRUBY_CONFIG=travis_config.rb
-script: "./minirake all test"
+script: "./minirake -j4 all test"
diff --git a/build_config.rb b/build_config.rb
index 1429837be..7f52b5ee9 100644
--- a/build_config.rb
+++ b/build_config.rb
@@ -8,7 +8,8 @@ MRuby::Build.new do |conf|
toolchain :gcc
end
- enable_debug
+ # Turn on `enable_debug` for better debugging
+ # enable_debug
# Use mrbgems
# conf.gem 'examples/mrbgems/ruby_extension_example'
diff --git a/include/mruby.h b/include/mruby.h
index 8c4f9280b..b0bfe78b5 100644
--- a/include/mruby.h
+++ b/include/mruby.h
@@ -994,8 +994,8 @@ MRB_API mrb_value mrb_str_new_static(mrb_state *mrb, const char *p, size_t len);
#define mrb_str_new_lit(mrb, lit) mrb_str_new_static(mrb, (lit), mrb_strlen_lit(lit))
#ifdef _WIN32
-char* mrb_utf8_from_locale(const char *p, int len);
-char* mrb_locale_from_utf8(const char *p, int len);
+MRB_API char* mrb_utf8_from_locale(const char *p, int len);
+MRB_API char* mrb_locale_from_utf8(const char *p, int len);
#define mrb_locale_free(p) free(p)
#define mrb_utf8_free(p) free(p)
#else
diff --git a/minirake b/minirake
index 542c37a79..ae3d53ca0 100755
--- a/minirake
+++ b/minirake
@@ -6,6 +6,12 @@
require 'getoptlong'
require 'fileutils'
+require 'fiber'
+
+$rake_fiber_table = {}
+$rake_jobs = 1
+$rake_failed = []
+$rake_root_fiber = Fiber.current
class String
def ext(newext='')
@@ -86,14 +92,31 @@ module MiniRake
@name.to_s
end
+ def done?; @done end
+ def running?; @running end
+
# Invoke the task if it is needed. Prerequites are invoked first.
def invoke
puts "Invoke #{name} (already=[#{@already_invoked}], needed=[#{needed?}])" if $trace
return if @already_invoked
- @already_invoked = true
prerequisites = @prerequisites.collect{ |n| n.is_a?(Proc) ? n.call(name) : n }.flatten
- prerequisites.each { |n| Task[n].invoke }
- execute if needed?
+ prerequisites.each do |n|
+ t = Task[n]
+ unless t.done?
+ return prerequisites.select{|v| v = Task[v]; v && (!v.done? || !v.running?) }
+ end
+ end
+
+ @already_invoked = true
+
+ if needed?
+ @running = true
+ return Fiber.new do
+ self.execute
+ end
+ end
+
+ @done = true
end
# Execute the actions associated with this task.
@@ -103,6 +126,8 @@ module MiniRake
unless $dryrun
@actions.each { |act| act.call(self) }
end
+ @done = true
+ @running = false
end
# Is this task needed?
@@ -281,7 +306,19 @@ module MiniRake
# Run the system command +cmd+.
def sh(cmd)
puts cmd if $verbose
- system(cmd) or fail "Command Failed: [#{cmd}]"
+
+ if $rake_jobs == 1 || Fiber.current == $rake_root_fiber
+ system(cmd) or fail "Command Failed: [#{cmd}]"
+ return
+ end
+
+ pid = Process.spawn(cmd)
+ $rake_fiber_table[pid] = {
+ fiber: Fiber.current,
+ command: cmd,
+ process_waiter: Process.detach(pid)
+ }
+ Fiber.yield
end
def desc(text)
@@ -329,7 +366,9 @@ class RakeApp
['--verbose', '-v', GetoptLong::NO_ARGUMENT,
"Log message to standard output."],
['--directory', '-C', GetoptLong::REQUIRED_ARGUMENT,
- "Change executing directory of rakefiles."]
+ "Change executing directory of rakefiles."],
+ ['--jobs', '-j', GetoptLong::REQUIRED_ARGUMENT,
+ 'Execute rake with parallel jobs.']
]
# Create a RakeApp object.
@@ -422,6 +461,8 @@ class RakeApp
exit
when '--directory'
Dir.chdir value
+ when '--jobs'
+ $rake_jobs = [value.to_i, 1].max
else
fail "Unknown option: #{opt}"
end
@@ -447,12 +488,12 @@ class RakeApp
end
here = Dir.pwd
end
- tasks = []
+ root_tasks = []
ARGV.each do |task_name|
if /^(\w+)=(.*)/.match(task_name)
ENV[$1] = $2
else
- tasks << task_name
+ root_tasks << task_name
end
end
puts "(in #{Dir.pwd})"
@@ -461,20 +502,82 @@ class RakeApp
if $show_tasks
display_tasks
else
- tasks.push("default") if tasks.size == 0
- tasks.each do |task_name|
- MiniRake::Task[task_name].invoke
+ root_tasks.push("default") if root_tasks.empty?
+ # revese tasks for popping
+ root_tasks.reverse!
+
+ tasks = []
+ until root_tasks.empty?
+ root_name = root_tasks.pop
+ tasks << root_name
+ until tasks.empty?
+ task_name = tasks.pop
+ t = MiniRake::Task[task_name]
+ f = t.invoke
+
+ # append additional tasks to task queue
+ if f.kind_of?(Array)
+ tasks.push(*f)
+ tasks.uniq!
+ end
+
+ unless f.kind_of? Fiber
+ tasks.insert 0, task_name unless t.done?
+ if root_name == task_name
+ wait_process
+ end
+ next
+ end
+
+ f.resume
+ end
end
+
+ wait_process until $rake_fiber_table.empty?
+ end
+ rescue Exception => e
+ begin
+ $rake_failed << e
+ wait_process until $rake_fiber_table.empty?
+ rescue Exception => next_e
+ e = next_e
+ retry
end
- rescue Exception => ex
- puts "rake aborted!"
+ end
+
+ return if $rake_failed.empty?
+
+ puts "rake aborted!"
+ $rake_failed.each do |ex|
puts ex.message
if $trace
puts ex.backtrace.join("\n")
else
puts ex.backtrace.find {|str| str =~ /#{@rakefile}/ } || ""
end
- exit 1
+ end
+ exit 1
+ end
+
+ def wait_process
+ sleep 0.1
+
+ exited = []
+ $rake_fiber_table.each do |pid, v|
+ exited << pid unless v[:process_waiter].alive?
+ end
+
+ exited.each do |pid|
+ ent = $rake_fiber_table.delete pid
+ st = ent[:process_waiter].value
+
+ # ignore process that isn't created by `sh` method
+ return if ent.nil?
+
+ if st.exitstatus != 0
+ raise "Command Failed: [#{ent[:command]}]"
+ end
+ ent[:fiber].resume
end
end
end
diff --git a/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c b/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c
index 5b77f5bac..5c2b58da5 100644
--- a/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c
+++ b/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c
@@ -661,6 +661,12 @@ done:
if (args.rfp) fclose(args.rfp);
mrb_free(mrb, args.argv);
+ if (args.libv) {
+ for (i = 0; i < args.libc; ++i) {
+ mrb_free(mrb, args.libv[i]);
+ }
+ mrb_free(mrb, args.libv);
+ }
mrbc_context_free(mrb, cxt);
mrb_close(mrb);
diff --git a/mrbgems/mruby-bin-mruby-config/mrbgem.rake b/mrbgems/mruby-bin-mruby-config/mrbgem.rake
index 66d6ef80b..32ae2164b 100644
--- a/mrbgems/mruby-bin-mruby-config/mrbgem.rake
+++ b/mrbgems/mruby-bin-mruby-config/mrbgem.rake
@@ -19,9 +19,10 @@ MRuby.each_target do
mruby_config_path = "#{build_dir}/bin/#{mruby_config}"
@bins << mruby_config
- file mruby_config_path => libfile("#{build_dir}/lib/libmruby") do |t|
+ make_cfg = "#{build_dir}/lib/libmruby.flags.mak"
+ file mruby_config_path => [libfile("#{build_dir}/lib/libmruby"), make_cfg] do |t|
FileUtils.copy "#{File.dirname(__FILE__)}/#{mruby_config}", t.name
- config = Hash[open("#{build_dir}/lib/libmruby.flags.mak").read.split("\n").map {|x| a = x.split(/\s*=\s*/, 2); [a[0], a[1].gsub('\\"', '"') ]}]
+ config = Hash[open(make_cfg).read.split("\n").map {|x| a = x.split(/\s*=\s*/, 2); [a[0], a[1].gsub('\\"', '"') ]}]
IO.write(t.name, File.open(t.name) {|f|
f.read.gsub (/echo (MRUBY_CFLAGS|MRUBY_LIBS|MRUBY_LDFLAGS_BEFORE_LIBS|MRUBY_LDFLAGS|MRUBY_LIBMRUBY_PATH)/) {|x| config[$1].empty? ? '' : "echo #{config[$1]}"}
})
diff --git a/mrbgems/mruby-compiler/mrbgem.rake b/mrbgems/mruby-compiler/mrbgem.rake
index 3bf6d6ae3..e9e0cc2c7 100644
--- a/mrbgems/mruby-compiler/mrbgem.rake
+++ b/mrbgems/mruby-compiler/mrbgem.rake
@@ -23,10 +23,10 @@ MRuby::Gem::Specification.new 'mruby-compiler' do |spec|
cc.run t.name, t.prerequisites.first, [], ["#{current_dir}/core"]
end
end
- file objfile("#{current_build_dir}/core/y.tab") => lex_def
# Parser
- file "#{current_build_dir}/core/y.tab.c" => ["#{current_dir}/core/parse.y"] do |t|
+ file "#{current_build_dir}/core/y.tab.c" => ["#{current_dir}/core/parse.y", lex_def] do |t|
+ FileUtils.mkdir_p File.dirname t.name
yacc.run t.name, t.prerequisites.first
end
diff --git a/mrbgems/mruby-io/mrbgem.rake b/mrbgems/mruby-io/mrbgem.rake
index 50fa49678..d79964590 100644
--- a/mrbgems/mruby-io/mrbgem.rake
+++ b/mrbgems/mruby-io/mrbgem.rake
@@ -4,7 +4,7 @@ MRuby::Gem::Specification.new('mruby-io') do |spec|
spec.summary = 'IO and File class'
spec.cc.include_paths << "#{build.root}/src"
-
+
case RUBY_PLATFORM
when /mingw|mswin/
spec.linker.libraries += ['Ws2_32']
@@ -14,4 +14,5 @@ MRuby::Gem::Specification.new('mruby-io') do |spec|
if build.kind_of?(MRuby::CrossBuild) && %w(x86_64-w64-mingw32 i686-w64-mingw32).include?(build.host_target)
spec.linker.libraries += ['ws2_32']
end
+ spec.add_test_dependency 'mruby-time', core: 'mruby-time'
end
diff --git a/mrbgems/mruby-test/mrbgem.rake b/mrbgems/mruby-test/mrbgem.rake
index 27c635a5d..11d780f75 100644
--- a/mrbgems/mruby-test/mrbgem.rake
+++ b/mrbgems/mruby-test/mrbgem.rake
@@ -23,7 +23,7 @@ MRuby::Gem::Specification.new('mruby-test') do |spec|
mrbtest_objs = []
driver_obj = objfile("#{build_dir}/driver")
- driver = "#{spec.dir}/driver.c"
+ # driver = "#{spec.dir}/driver.c"
assert_c = "#{build_dir}/assert.c"
assert_rb = "#{MRUBY_ROOT}/test/assert.rb"
@@ -31,7 +31,7 @@ MRuby::Gem::Specification.new('mruby-test') do |spec|
mrbtest_objs << assert_lib
file assert_lib => assert_c
- file assert_c => assert_rb do |t|
+ file assert_c => [assert_rb, build.mrbcfile] do |t|
open(t.name, 'w') do |f|
mrbc.run f, assert_rb, 'mrbtest_assert_irep'
end
@@ -45,7 +45,7 @@ MRuby::Gem::Specification.new('mruby-test') do |spec|
dep_list = build.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 do |t|
+ file g.test_rbireps => [g.test_rbfiles, build.mrbcfile].flatten do |t|
FileUtils.mkdir_p File.dirname(t.name)
open(t.name, 'w') do |f|
g.print_gem_test_header(f)
@@ -146,7 +146,8 @@ MRuby::Gem::Specification.new('mruby-test') do |spec|
gem_flags_after_libraries = build.gems.map { |g| g.linker.flags_after_libraries }
gem_libraries = build.gems.map { |g| g.linker.libraries }
gem_library_paths = build.gems.map { |g| g.linker.library_paths }
- build.linker.run t.name, t.prerequisites, gem_libraries, gem_library_paths, gem_flags, gem_flags_before_libraries
+ build.linker.run t.name, t.prerequisites, gem_libraries, gem_library_paths, gem_flags,
+ gem_flags_before_libraries, gem_flags_after_libraries
end
end
@@ -163,13 +164,14 @@ MRuby::Gem::Specification.new('mruby-test') do |spec|
nil
end
current_gem_list = build.gems.map(&:name).join("\n")
- if active_gem_list != current_gem_list
- File.write active_gems_path, current_gem_list
+ task active_gems_path do |t|
+ FileUtils.mkdir_p File.dirname t.name
+ File.write t.name, current_gem_list
end
- file clib => active_gems_path
+ file clib => active_gems_path if active_gem_list != current_gem_list
file mlib => clib
- file clib => init do |t|
+ file clib => [init, build.mrbcfile] do |_t|
_pp "GEN", "*.rb", "#{clib.relative_path}"
FileUtils.mkdir_p File.dirname(clib)
open(clib, 'w') do |f|
diff --git a/tasks/libmruby.rake b/tasks/libmruby.rake
index 540aa3eb5..b6ef29986 100644
--- a/tasks/libmruby.rake
+++ b/tasks/libmruby.rake
@@ -4,6 +4,7 @@ MRuby.each_target do
end
file "#{build_dir}/lib/libmruby.flags.mak" => [__FILE__, libfile("#{build_dir}/lib/libmruby")] do |t|
+ FileUtils.mkdir_p File.dirname t.name
open(t.name, 'w') do |f|
f.puts "MRUBY_CFLAGS = #{cc.all_flags}"
diff --git a/tasks/mrbgems.rake b/tasks/mrbgems.rake
index 1b964524c..64e5b0353 100644
--- a/tasks/mrbgems.rake
+++ b/tasks/mrbgems.rake
@@ -53,6 +53,7 @@ MRuby.each_target do
# legal documents
file "#{build_dir}/LEGAL" => [MRUBY_CONFIG, __FILE__] do |t|
+ FileUtils.mkdir_p File.dirname t.name
open(t.name, 'w+') do |f|
f.puts <<LEGAL
Copyright (c) #{Time.now.year} mruby developers