summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYuichiro MASUI <[email protected]>2012-12-16 01:56:03 +0900
committerYuichiro MASUI <[email protected]>2012-12-16 01:56:03 +0900
commit06d242ae430ad37fd88fe6490980121ee26a1283 (patch)
treeb9326ec83c57de85381b73705f5cd55deaecc4f3
parentf2d3c4d2f7361cbd5e246f78630cca919e342673 (diff)
downloadmruby-06d242ae430ad37fd88fe6490980121ee26a1283.tar.gz
mruby-06d242ae430ad37fd88fe6490980121ee26a1283.zip
Moved some building script from GNU make to Ruby script
Added minirake what's Rake subset
-rw-r--r--.gitignore2
-rw-r--r--.travis.yml2
-rw-r--r--Makefile107
-rw-r--r--Rakefile101
-rw-r--r--doc/mrbgems/c_and_ruby_extension_example/.gitignore3
-rw-r--r--doc/mrbgems/c_extension_example/.gitignore3
-rw-r--r--doc/mrbgems/ruby_extension_example/.gitignore3
-rwxr-xr-xminirake409
-rw-r--r--mrbgems/Makefile76
-rw-r--r--mrbgems/build_tasks.rb78
-rw-r--r--test/Makefile4
11 files changed, 603 insertions, 185 deletions
diff --git a/.gitignore b/.gitignore
index ccc701bcf..7b983f988 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,10 +19,12 @@ cscope.out
/bin
/mrblib/mrblib.c
/mrblib/*.*tmp
+/mrblib/mrblib.mrb
/test/mrbtest
/test/mrbtest.c
/test/*.*tmp
/test/mrubytest.*
+tools/mrbc/mrbc.mrb
CMakeFiles
CMakeCache.txt
/mrbgems/generator
diff --git a/.travis.yml b/.travis.yml
index cea38b14d..109013b10 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,3 +1,3 @@
# no installation...
-script: "make all test"
+script: "./minirake all test"
diff --git a/Makefile b/Makefile
deleted file mode 100644
index a70938373..000000000
--- a/Makefile
+++ /dev/null
@@ -1,107 +0,0 @@
-# Makefile description.
-# basic build file for mruby
-
-# compiler, linker (gcc), archiver, parser generator
-export CC = gcc
-export LL = gcc
-export AR = ar
-export YACC = bison
-
-MRUBY_ROOT := $(realpath .)
-
-ifeq ($(strip $(ENABLE_GEMS)),)
- # by default GEMs are deactivated
- ENABLE_GEMS = false
-endif
-
-ifeq ($(strip $(ACTIVE_GEMS)),)
- # the default file which contains the active GEMs
- ACTIVE_GEMS = GEMS.active
-endif
-
-ifeq ($(strip $(COMPILE_MODE)),)
- # default compile option
- COMPILE_MODE = debug
-endif
-
-ifeq ($(COMPILE_MODE),debug)
- CFLAGS = -g -O3
-else ifeq ($(COMPILE_MODE),release)
- CFLAGS = -O3
-else ifeq ($(COMPILE_MODE),small)
- CFLAGS = -Os
-endif
-
-ALL_CFLAGS = -Wall -Werror-implicit-function-declaration $(CFLAGS)
-ifeq ($(OS),Windows_NT)
- MAKE_FLAGS = --no-print-directory CC=$(CC) LL=$(LL) ALL_CFLAGS='$(ALL_CFLAGS)' LDFLAGS='$(LDFLAGS)' ENABLE_GEMS='$(ENABLE_GEMS)' ACTIVE_GEMS='$(ACTIVE_GEMS)' MRUBY_ROOT='$(MRUBY_ROOT)'
-else
- MAKE_FLAGS = --no-print-directory CC='$(CC)' LL='$(LL)' ALL_CFLAGS='$(ALL_CFLAGS)' LDFLAGS='$(LDFLAGS)' ENABLE_GEMS='$(ENABLE_GEMS)' ACTIVE_GEMS='$(ACTIVE_GEMS)' MRUBY_ROOT='$(MRUBY_ROOT)'
-endif
-
-##############################
-# internal variables
-
-export MSG_BEGIN = @for line in
-export MSG_END = ; do echo "$$line"; done
-
-export CP := cp
-export RM_F := rm -f
-export CAT := cat
-
-##############################
-# generic build targets, rules
-
-.PHONY : all
-all :
- @$(MAKE) -C src $(MAKE_FLAGS)
- @$(MAKE) -C mrblib $(MAKE_FLAGS)
-ifeq ($(ENABLE_GEMS),true)
- @echo "-- MAKE mrbgems --"
- @$(MAKE) -C mrbgems $(MAKE_FLAGS)
-endif
- $(MAKE) -C tools/mruby $(MAKE_FLAGS)
- @$(MAKE) -C tools/mirb $(MAKE_FLAGS)
-
-# mruby test
-.PHONY : test
-test : all
- @$(MAKE) -C test $(MAKE_FLAGS)
-
-# clean up
-.PHONY : clean
-clean :
- @$(MAKE) clean -C src $(MAKE_FLAGS)
-ifeq ($(ENABLE_GEMS),true)
- @echo "-- CLEAN mrbgems --"
- @$(MAKE) clean -C mrbgems $(MAKE_FLAGS)
-endif
- @$(MAKE) clean -C tools/mruby $(MAKE_FLAGS)
- @$(MAKE) clean -C tools/mirb $(MAKE_FLAGS)
- @$(MAKE) clean -C test $(MAKE_FLAGS)
-
-# display help for build configuration and interesting targets
-.PHONY : showconfig
-showconfig :
- $(MSG_BEGIN) \
- "" \
- " CC = $(CC)" \
- " LL = $(LL)" \
- " MAKE = $(MAKE)" \
- "" \
- " CFLAGS = $(CFLAGS)" \
- " ALL_CFLAGS = $(ALL_CFLAGS)" \
- $(MSG_END)
-
-.PHONY : help
-help :
- $(MSG_BEGIN) \
- "" \
- " Basic mruby Makefile" \
- "" \
- "targets:" \
- " all (default): build all targets, install (locally) in-repo" \
- " clean: clean all built and in-repo installed artifacts" \
- " showconfig: show build config summary" \
- " test: run all mruby tests" \
- $(MSG_END)
diff --git a/Rakefile b/Rakefile
new file mode 100644
index 000000000..ba24cdef9
--- /dev/null
+++ b/Rakefile
@@ -0,0 +1,101 @@
+# Build description.
+# basic build file for mruby
+
+# compiler, linker (gcc), archiver, parser generator
+CC = ENV['CC'] || 'gcc'
+LL = ENV['LL'] || 'gcc'
+AR = ENV['AR'] || 'ar'
+YACC = ENV['YACC'] || 'bison'
+MAKE = ENV['MAKE'] || 'make'
+
+# mruby source root path
+MRUBY_ROOT = ENV['MRUBY_ROOT'] || File.expand_path(File.dirname(__FILE__))
+
+# by default GEMs are deactivated
+ENABLE_GEMS = false
+
+# the default file which contains the active GEMs
+ACTIVE_GEMS = File.join(File.dirname(__FILE__), 'mrbgems', 'GEMS.active')
+
+# default compile option
+COMPILE_MODE = :debug
+
+
+##############################
+# compile flags
+
+case COMPILE_MODE.to_s
+when 'debug'
+ CFLAGS = ['-g', '-O3']
+when 'release'
+ CFLAGS = ['-O3']
+when 'small'
+ CFLAGS = ['-Os']
+else
+ CFLAGS = [ENV['CFLAGS']]
+end
+LDFLAGS = [ENV['LDFLAGS']]
+
+CFLAGS << "-Wall" << "-Werror-implicit-function-declaration" << "-I#{MRUBY_ROOT}/include"
+if ENV['OS'] == 'Windows_NT'
+ MAKE_FLAGS = "--no-print-directory CC=#{CC} LL=#{LL} CFLAGS='#{CFLAGS.join(' ')}' LDFLAGS='#{LDFLAGS.join(' ')}' ENABLE_GEMS='#{ENABLE_GEMS}' MRUBY_ROOT='#{MRUBY_ROOT}'"
+else
+ MAKE_FLAGS = "--no-print-directory CC='#{CC}' LL='#{LL}' CFLAGS='#{CFLAGS.join(' ')}' LDFLAGS='#{LDFLAGS.join(' ')}' ENABLE_GEMS='#{ENABLE_GEMS}' MRUBY_ROOT='#{MRUBY_ROOT}'"
+end
+
+
+
+##############################
+# internal variables
+
+CP = ENV['CP'] ||= 'cp'
+RM_F = ENV['RM_F'] ||= 'rm -f'
+CAT = ENV['CAT'] ||= 'cat'
+
+
+##############################
+# generic build targets, rules
+if ENABLE_GEMS
+ require './mrbgems/build_tasks'
+end
+
+task :default => :all
+
+desc "build all targets, install (locally) in-repo"
+task :all do
+ sh "#{MAKE} -C src #{MAKE_FLAGS}"
+ sh "#{MAKE} -C mrblib #{MAKE_FLAGS}"
+ if ENABLE_GEMS
+ puts "-- MAKE mrbgems --"
+ Rake::Task['mrbgems_all'].invoke
+ end
+ sh "#{MAKE} -C tools/mruby #{MAKE_FLAGS}"
+ sh "#{MAKE} -C tools/mirb #{MAKE_FLAGS}"
+end
+
+desc "sh all mruby tests"
+task :test => [:all] do
+ sh "#{MAKE} -C test #{MAKE_FLAGS}"
+end
+
+desc "clean all built and in-repo installed artifacts"
+task :clean do
+ sh "#{MAKE} clean -C src #{MAKE_FLAGS}"
+ sh "#{MAKE} clean -C mrblib #{MAKE_FLAGS}"
+ if ENABLE_GEMS
+ puts "-- MAKE mrbgems --"
+ Rake::Task['mrbgems_clean'].invoke
+ end
+ sh "#{MAKE} clean -C tools/mruby #{MAKE_FLAGS}"
+ sh "#{MAKE} clean -C tools/mirb #{MAKE_FLAGS}"
+end
+
+desc "show build config summary"
+task :showconfig do
+ puts " CC = #{CC}"
+ puts " LL = #{LL}"
+ puts " MAKE = #{MAKE}"
+ puts ""
+ puts " CFLAGS = #{CFLAGS.join(' ')}"
+ puts " LDFLAGS = #{LDFLAGS.join(' ')}"
+end
diff --git a/doc/mrbgems/c_and_ruby_extension_example/.gitignore b/doc/mrbgems/c_and_ruby_extension_example/.gitignore
new file mode 100644
index 000000000..e6ad3b5cf
--- /dev/null
+++ b/doc/mrbgems/c_and_ruby_extension_example/.gitignore
@@ -0,0 +1,3 @@
+gem_mixlib.c
+*.ctmp
+*.rbtmp
diff --git a/doc/mrbgems/c_extension_example/.gitignore b/doc/mrbgems/c_extension_example/.gitignore
new file mode 100644
index 000000000..e1ef5dc27
--- /dev/null
+++ b/doc/mrbgems/c_extension_example/.gitignore
@@ -0,0 +1,3 @@
+gem_srclib.c
+*.ctmp
+*.rbtmp
diff --git a/doc/mrbgems/ruby_extension_example/.gitignore b/doc/mrbgems/ruby_extension_example/.gitignore
new file mode 100644
index 000000000..0e23b7ac6
--- /dev/null
+++ b/doc/mrbgems/ruby_extension_example/.gitignore
@@ -0,0 +1,3 @@
+gem_mrblib.c
+*.ctmp
+*.rbtmp
diff --git a/minirake b/minirake
new file mode 100755
index 000000000..5ad05b964
--- /dev/null
+++ b/minirake
@@ -0,0 +1,409 @@
+#!/usr/bin/env ruby
+
+# Original is https://github.com/jimweirich/rake/
+# Copyright (c) 2003 Jim Weirich
+# License: MIT-LICENSE
+
+require 'getoptlong'
+
+module MiniRake
+ class Task
+ TASKS = Hash.new
+ RULES = Array.new
+
+ # List of prerequisites for a task.
+ attr_reader :prerequisites
+
+ # Source dependency for rule synthesized tasks. Nil if task was not
+ # sythesized from a rule.
+ attr_accessor :source
+
+ # Create a task named +task_name+ with no actions or prerequisites..
+ # use +enhance+ to add actions and prerequisites.
+ def initialize(task_name)
+ @name = task_name
+ @prerequisites = []
+ @actions = []
+ end
+
+ # Enhance a task with prerequisites or actions. Returns self.
+ def enhance(deps=nil, &block)
+ @prerequisites |= deps if deps
+ @actions << block if block_given?
+ self
+ end
+
+ # Name of the task.
+ def name
+ @name.to_s
+ 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.each { |n| Task[n].invoke }
+ execute if needed?
+ end
+
+ # Execute the actions associated with this task.
+ def execute
+ puts "Execute #{name}" if $trace
+ self.class.enhance_with_matching_rule(name) if @actions.empty?
+ unless $dryrun
+ @actions.each { |act| result = act.call(self) }
+ end
+ end
+
+ # Is this task needed?
+ def needed?
+ true
+ end
+
+ # Timestamp for this task. Basic tasks return the current time for
+ # their time stamp. Other tasks can be more sophisticated.
+ def timestamp
+ @prerequisites.collect { |p| Task[p].timestamp }.max || Time.now
+ end
+
+ # Class Methods ----------------------------------------------------
+
+ class << self
+
+ # Clear the task list. This cause rake to immediately forget all
+ # the tasks that have been assigned. (Normally used in the unit
+ # tests.)
+ def clear
+ TASKS.clear
+ RULES.clear
+ end
+
+ # List of all defined tasks.
+ def tasks
+ TASKS.keys.sort.collect { |tn| Task[tn] }
+ end
+
+ # Return a task with the given name. If the task is not currently
+ # known, try to synthesize one from the defined rules. If no
+ # rules are found, but an existing file matches the task name,
+ # assume it is a file task with no dependencies or actions.
+ def [](task_name)
+ task_name = task_name.to_s
+ if task = TASKS[task_name]
+ return task
+ end
+ if task = enhance_with_matching_rule(task_name)
+ return task
+ end
+ if File.exist?(task_name)
+ return FileTask.define_task(task_name)
+ end
+ fail "Don't know how to rake #{task_name}"
+ end
+
+ # Define a task given +args+ and an option block. If a rule with
+ # the given name already exists, the prerequisites and actions are
+ # added to the existing task.
+ def define_task(args, &block)
+ task_name, deps = resolve_args(args)
+ deps = [deps] if (Symbol === deps) || (String === deps)
+ deps = deps.collect {|d| d.to_s }
+ lookup(task_name).enhance(deps, &block)
+ end
+
+ # Define a rule for synthesizing tasks.
+ def create_rule(args, &block)
+ pattern, deps = resolve_args(args)
+ fail "Too many dependents specified in rule #{pattern}: #{deps.inspect}" if deps.size > 1
+ pattern = Regexp.new(Regexp.quote(pattern) + '$') if String === pattern
+ RULES << [pattern, deps, block]
+ end
+
+
+ # Lookup a task. Return an existing task if found, otherwise
+ # create a task of the current type.
+ def lookup(task_name)
+ name = task_name.to_s
+ TASKS[name] ||= self.new(name)
+ end
+
+ # If a rule can be found that matches the task name, enhance the
+ # task with the prerequisites and actions from the rule. Set the
+ # source attribute of the task appropriately for the rule. Return
+ # the enhanced task or nil of no rule was found.
+ def enhance_with_matching_rule(task_name)
+ RULES.each do |pattern, extensions, block|
+ if md = pattern.match(task_name)
+ ext = extensions.first
+ case ext
+ when String
+ source = task_name.sub(/\.[^.]*$/, ext)
+ when Proc
+ source = ext.call(task_name)
+ else
+ fail "Don't know how to handle rule dependent: #{ext.inspect}"
+ end
+ if File.exist?(source)
+ task = FileTask.define_task({task_name => [source]}, &block)
+ task.source = source
+ return task
+ end
+ end
+ end
+ nil
+ end
+
+ private
+
+ # Resolve the arguments for a task/rule.
+ def resolve_args(args)
+ case args
+ when Hash
+ fail "Too Many Task Names: #{args.keys.join(' ')}" if args.size > 1
+ fail "No Task Name Given" if args.size < 1
+ task_name = args.keys[0]
+ deps = args[task_name]
+ deps = [deps] if (String===deps) || (Regexp===deps) || (Proc===deps)
+ else
+ task_name = args
+ deps = []
+ end
+ [task_name, deps]
+ end
+ end
+ end
+
+
+ ######################################################################
+ class FileTask < Task
+ # Is this file task needed? Yes if it doesn't exist, or if its time
+ # stamp is out of date.
+ def needed?
+ return true unless File.exist?(name)
+ latest_prereq = @prerequisites.collect{|n| Task[n].timestamp}.max
+ return false if latest_prereq.nil?
+ timestamp < latest_prereq
+ end
+
+ # Time stamp for file task.
+ def timestamp
+ File.new(name.to_s).mtime
+ end
+ end
+end
+
+Rake = MiniRake
+
+
+######################################################################
+# Task Definition Functions ...
+
+# Declare a basic task.
+def task(args, &block)
+ MiniRake::Task.define_task(args, &block)
+end
+
+# Declare a file task.
+def file(args, &block)
+ MiniRake::FileTask.define_task(args, &block)
+end
+
+# Declare a set of files tasks to create the given directories on
+# demand.
+def directory(dir)
+ path = []
+ Sys.split_all(dir).each do |p|
+ path << p
+ FileTask.define_task(File.join(path)) do |t|
+ Sys.makedirs(t.name)
+ end
+ end
+end
+
+# Declare a rule for auto-tasks.
+def rule(args, &block)
+ MiniRake::Task.create_rule(args, &block)
+end
+
+# Write a message to standard out if $verbose is enabled.
+def log(msg)
+ print " " if $trace && $verbose
+ puts msg if $verbose
+end
+
+# Run the system command +cmd+.
+def sh(cmd)
+ log cmd
+ system(cmd) or fail "Command Failed: [#{cmd}]"
+end
+
+def desc(text)
+end
+
+######################################################################
+# Rake main application object. When invoking +rake+ from the command
+# line, a RakeApp object is created and run.
+#
+class RakeApp
+ RAKEFILES = ['rakefile', 'Rakefile']
+
+ OPTIONS = [
+ ['--dry-run', '-n', GetoptLong::NO_ARGUMENT,
+ "Do a dry run without executing actions."],
+ ['--help', '-H', GetoptLong::NO_ARGUMENT,
+ "Display this help message."],
+ ['--libdir', '-I', GetoptLong::REQUIRED_ARGUMENT,
+ "Include LIBDIR in the search path for required modules."],
+ ['--nosearch', '-N', GetoptLong::NO_ARGUMENT,
+ "Do not search parent directories for the Rakefile."],
+ ['--quiet', '-q', GetoptLong::NO_ARGUMENT,
+ "Do not log messages to standard output."],
+ ['--rakefile', '-f', GetoptLong::REQUIRED_ARGUMENT,
+ "Use FILE as the rakefile."],
+ ['--require', '-r', GetoptLong::REQUIRED_ARGUMENT,
+ "Require MODULE before executing rakefile."],
+ ['--tasks', '-T', GetoptLong::NO_ARGUMENT,
+ "Display the tasks and dependencies, then exit."],
+ ['--trace', '-t', GetoptLong::NO_ARGUMENT,
+ "Turn on invoke/execute tracing."],
+ ['--usage', '-h', GetoptLong::NO_ARGUMENT,
+ "Display usage."],
+ ['--verbose', '-v', GetoptLong::NO_ARGUMENT,
+ "Log message to standard output (default)."],
+ ]
+
+ # Create a RakeApp object.
+ def initialize
+ @rakefile = nil
+ @nosearch = false
+ end
+
+ # True if one of the files in RAKEFILES is in the current directory.
+ # If a match is found, it is copied into @rakefile.
+ def have_rakefile
+ RAKEFILES.each do |fn|
+ if File.exist?(fn)
+ @rakefile = fn
+ return true
+ end
+ end
+ return false
+ end
+
+ # Display the program usage line.
+ def usage
+ puts "rake [-f rakefile] {options} targets..."
+ end
+
+ # Display the rake command line help.
+ def help
+ usage
+ puts
+ puts "Options are ..."
+ puts
+ OPTIONS.sort.each do |long, short, mode, desc|
+ if mode == GetoptLong::REQUIRED_ARGUMENT
+ if desc =~ /\b([A-Z]{2,})\b/
+ long = long + "=#{$1}"
+ end
+ end
+ printf " %-20s (%s)\n", long, short
+ printf " %s\n", desc
+ end
+ end
+
+ # Display the tasks and dependencies.
+ def display_tasks
+ Task.tasks.each do |t|
+ puts "#{t.class} #{t.name}"
+ t.prerequisites.each { |pre| puts " #{pre}" }
+ end
+ end
+
+ # Return a list of the command line options supported by the
+ # program.
+ def command_line_options
+ OPTIONS.collect { |lst| lst[0..-2] }
+ end
+
+ # Do the option defined by +opt+ and +value+.
+ def do_option(opt, value)
+ case opt
+ when '--dry-run'
+ $dryrun = true
+ $trace = true
+ when '--help'
+ help
+ exit
+ when '--libdir'
+ $:.push(value)
+ when '--nosearch'
+ @nosearch = true
+ when '--quiet'
+ $verbose = false
+ when '--rakefile'
+ RAKEFILES.clear
+ RAKEFILES << value
+ when '--require'
+ require value
+ when '--tasks'
+ $show_tasks = true
+ when '--trace'
+ $trace = true
+ when '--usage'
+ usage
+ exit
+ when '--verbose'
+ $verbose = true
+ when '--version'
+ puts "rake, version #{RAKEVERSION}"
+ exit
+ else
+ fail "Unknown option: #{opt}"
+ end
+ end
+
+ # Read and handle the command line options.
+ def handle_options
+ $verbose = true
+ opts = GetoptLong.new(*command_line_options)
+ opts.each { |opt, value| do_option(opt, value) }
+ end
+
+ # Run the +rake+ application.
+ def run
+ handle_options
+ begin
+ here = Dir.pwd
+ while ! have_rakefile
+ Dir.chdir("..")
+ if Dir.pwd == here || @nosearch
+ fail "No Rakefile found (looking for: #{RAKEFILES.join(', ')})"
+ end
+ here = Dir.pwd
+ end
+ puts "(in #{Dir.pwd})"
+ $rakefile = @rakefile
+ load @rakefile
+ if $show_tasks
+ display_tasks
+ else
+ ARGV.push("default") if ARGV.size == 0
+ ARGV.each { |task_name| MiniRake::Task[task_name].invoke }
+ end
+ rescue Exception => ex
+ puts "rake aborted!"
+ puts ex.message
+ if $trace
+ puts ex.backtrace.join("\n")
+ else
+ puts ex.backtrace.find {|str| str =~ /#{@rakefile}/ } || ""
+ end
+ end
+ end
+end
+
+if __FILE__ == $0 then
+ RakeApp.new.run
+end \ No newline at end of file
diff --git a/mrbgems/Makefile b/mrbgems/Makefile
deleted file mode 100644
index 2c0a0962c..000000000
--- a/mrbgems/Makefile
+++ /dev/null
@@ -1,76 +0,0 @@
-# makefile description.
-# add gems to the ruby library
-
-ifeq ($(strip $(MRUBY_ROOT)),)
- MRUBY_ROOT := $(realpath ..)
-endif
-
-LIBR := ../lib/libmruby.a
-RM_F := rm -f
-CC_FLAGS := -Wall -Werror-implicit-function-declaration -g -O3 -MMD -I. -I./../include
-
-export CC = gcc
-export LL = gcc
-export AR = ar
-
-GENERATOR := $(MRUBY_ROOT)/mrbgems/generator
-ifeq ($(OS),Windows_NT)
- GENERATOR_BIN := $(GENERATOR).exe
-else
- GENERATOR_BIN := $(GENERATOR)
-endif
-GEM_INIT := gem_init
-GEM_MAKEFILE := g/Makefile
-GEM_MAKEFILE_LIST := g/MakefileGemList
-GEMDLIB := g/mrbgemtest.ctmp
-
-ifeq ($(strip $(ACTIVE_GEMS)),)
- # the default file which contains the active GEMs
- ACTIVE_GEMS = GEMS.active
-endif
-
-##############################
-# generic build targets, rules
-
-.PHONY : all
-all : all_gems $(GEM_INIT).a
-
-$(GEM_INIT).a : $(GEM_INIT).o
- $(AR) rs gem_init.a $(GEM_INIT).o
-
-all_gems : $(GENERATOR_BIN)
- @echo "Generate Gem List Makefile"
- $(GENERATOR_BIN) makefile_list $(ACTIVE_GEMS) > $(GEM_MAKEFILE_LIST)
- @echo "Generate Gem Makefile"
- $(GENERATOR_BIN) makefile $(ACTIVE_GEMS) "$(MRUBY_ROOT)" > $(GEM_MAKEFILE)
- @echo "Build all gems"
- $(MAKE) -C g MRUBY_ROOT='$(MRUBY_ROOT)' ACTIVE_GEMS="$(ACTIVE_GEMS)"
-
-$(GEM_INIT).c : $(GENERATOR_BIN)
- @echo "Generate Gem driver"
- $(GENERATOR_BIN) $(GEM_INIT) $(ACTIVE_GEMS) > $@
-
-$(GEM_INIT).o : $(GEM_INIT).c
- @echo "Build the driver which initializes all gems"
- $(CC) $(CC_FLAGS) -MMD -c $< -o $@
-
-# Generator
-
-$(GENERATOR_BIN) : $(GENERATOR).o
- @echo "Build the generator which creates the driver and Gem Makefile"
- $(LL) -o $@ $(CC_FLAGS) $<
-
-$(GENERATOR).o : $(GENERATOR).c
- $(CC) $(CC_FLAGS) -MMD -c $< -o $@
-
-.PHONY : prepare-test
-prepare-test :
- @$(MAKE) prepare-test -C g ACTIVE_GEMS="$(ACTIVE_GEMS)" MRUBY_ROOT='$(MRUBY_ROOT)'
-
-# clean driver and all gems
-.PHONY : clean
-clean : $(GENERATOR_BIN)
- @echo "Cleanup Gems"
- $(GENERATOR_BIN) makefile $(ACTIVE_GEMS) "$(MRUBY_ROOT)" > $(GEM_MAKEFILE)
- $(MAKE) clean -C g ACTIVE_GEMS="$(ACTIVE_GEMS)" MRUBY_ROOT='$(MRUBY_ROOT)'
- -$(RM_F) $(GEM_INIT).c *.o *.d $(GENERATOR_BIN) $(GEM_MAKEFILE) $(GEM_MAKEFILE_LIST) gem_init.a
diff --git a/mrbgems/build_tasks.rb b/mrbgems/build_tasks.rb
new file mode 100644
index 000000000..f7accdffa
--- /dev/null
+++ b/mrbgems/build_tasks.rb
@@ -0,0 +1,78 @@
+MRBGEMS_PATH = File.dirname(__FILE__)
+
+GEM_INIT = "#{MRBGEMS_PATH}/gem_init"
+GEM_MAKEFILE = "#{MRBGEMS_PATH}/g/Makefile"
+GEM_MAKEFILE_LIST = "#{MRBGEMS_PATH}/g/MakefileGemList"
+MAKEFILE_4_GEM = "#{MRUBY_ROOT}/mrbgems/Makefile4gem"
+
+GEM_MAKE_FLAGS = "#{MAKE_FLAGS} MAKEFILE_4_GEM='#{MAKEFILE_4_GEM}'"
+
+task :mrbgems_all => ["#{GEM_INIT}.a"] do
+ for_each_gem do |f|
+ sh "#{MAKE} -C #{f} #{GEM_MAKE_FLAGS}"
+ end
+end
+
+task :mrbgems_clean do
+ sh "cd #{MRUBY_ROOT}/mrbgems/g && #{RM_F} *.c *.d *.rbtmp *.ctmp *.o mrbtest"
+ for_each_gem do |f|
+ sh "#{MAKE} clean -C #{f} #{GEM_MAKE_FLAGS}"
+ end
+end
+
+task :mrbgems_prepare_test do
+ sh "#{CAT} #{for_each_gem{|f| "#{f}/test/*.rb "}} > #{MRUBY_ROOT}/mrbgems/g/mrbgemtest.rbtmp"
+ sh "#{MRUBY_ROOT}/bin/mrbc -Bmrbgemtest_irep -o#{MRUBY_ROOT}/mrbgems/g/mrbgemtest.ctmp #{MRUBY_ROOT}/mrbgems/g/mrbgemtest.rbtmp"
+end
+
+file "#{GEM_INIT}.a" => ["#{GEM_INIT}.c", "#{GEM_INIT}.o"] do |t|
+ sh "#{AR} rs #{t.name} #{t.prerequisites.join(' ')}"
+end
+
+rule ".o" => [".c"] do |t|
+ puts "Build the driver which initializes all gems"
+ sh "#{CC} #{CFLAGS.join(' ')} -I #{MRUBY_ROOT}/include -MMD -c #{t.source} -o #{t.name}"
+end
+
+file "#{GEM_INIT}.c" do |t|
+ puts "Generate Gem driver: #{t.name}"
+ open(t.name, 'w') do |f|
+ f.puts <<__EOF__
+/*
+ * This file contains a list of all
+ * initializing methods which are
+ * necessary to bootstrap all gems.
+ *
+ * IMPORTANT:
+ * This file was generated!
+ * All manual changes will get lost.
+ */
+
+#include "mruby.h"
+
+#{for_each_gem{|f| "void GENERATED_TMP_mrb_%s_gem_init(mrb_state*);\n" % [File.basename(f)]}}
+
+void
+mrb_init_mrbgems(mrb_state *mrb) {
+#{for_each_gem{|f| " GENERATED_TMP_mrb_%s_gem_init(mrb);\n" % [File.basename(f)]}}
+}
+__EOF__
+ end
+end
+
+def for_each_gem(&block)
+ IO.readlines(ACTIVE_GEMS).map { |line|
+ block.call(line.chomp)
+ }.join('')
+end
+
+task :mrbgems_generate_gem_makefile_list do
+ open(GEM_MAKEFILE_LIST, 'w') do |f|
+ f.puts <<__EOF__
+GEM_LIST := #{for_each_gem{|f| "#{f}/mrb-#{File.basename(f)}-gem.a"}}
+
+GEM_ARCHIVE_FILES := #{MRUBY_ROOT}/mrbgems/gem_init.a
+GEM_ARCHIVE_FILES += $(GEM_LIST)
+__EOF__
+ end
+end
diff --git a/test/Makefile b/test/Makefile
index 844f8cc22..4a205999b 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -78,6 +78,8 @@ MRUBY= ../bin/mruby
EXE := $(TARGET)
endif
+RAKE = ../minirake
+
##############################
# generic build targets, rules
@@ -106,7 +108,7 @@ $(OBJS) : %.o : %.c
# Compile C source from merged mruby source
$(CLIB) : $(DLIB) $(INIT)
ifeq ($(ENABLE_GEMS),true)
- @$(MAKE) prepare-test -C $(GEMDIR)
+ @$(RAKE) mrbgems_prepare_test
endif
$(CAT) $(INIT) $(DLIB) $(GEMDLIB) > $@