summaryrefslogtreecommitdiffhomepage
path: root/tasks/mruby_build.rake
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2013-01-20 14:41:50 -0800
committerYukihiro "Matz" Matsumoto <[email protected]>2013-01-20 14:41:50 -0800
commit8e86ff2283d427b5cb2a02607e1aab998cb5090c (patch)
treebd40d166673b2290053f1742660d573d5586a974 /tasks/mruby_build.rake
parentcc16bd7c0d70b326ddcf8de8a511116dae9fc30d (diff)
parentced80d2b4b1ed4ef0752a8bbaf0dbfe7aa6c6a95 (diff)
downloadmruby-8e86ff2283d427b5cb2a02607e1aab998cb5090c.tar.gz
mruby-8e86ff2283d427b5cb2a02607e1aab998cb5090c.zip
Merge pull request #755 from masuidrive/imprive_build_scripts
Improved build scripts and config files
Diffstat (limited to 'tasks/mruby_build.rake')
-rw-r--r--tasks/mruby_build.rake239
1 files changed, 109 insertions, 130 deletions
diff --git a/tasks/mruby_build.rake b/tasks/mruby_build.rake
index de9e556b4..bcae9dfd9 100644
--- a/tasks/mruby_build.rake
+++ b/tasks/mruby_build.rake
@@ -1,7 +1,8 @@
+load 'tasks/mruby_build_gem.rake'
+load 'tasks/mruby_build_commands.rake'
+
module MRuby
class << self
- attr_accessor :build
-
def targets
@targets ||= {}
end
@@ -13,170 +14,148 @@ module MRuby
end
end
- class Build
- include Rake::DSL
- attr_accessor :name
- attr_accessor :cc, :cflags, :includes
- attr_accessor :ld, :ldflags, :libs
- attr_accessor :ar
- attr_writer :cxx, :cxxflags
- attr_writer :objcc, :objcflags
- attr_writer :asm, :asmflags
- attr_accessor :bins
- attr_accessor :gperf, :yacc
- attr_accessor :cat, :git
- attr_reader :root, :gems
- attr_reader :libmruby
-
- def initialize(&block)
- @name ||= 'host'
- @root = File.expand_path("#{File.dirname(__FILE__)}/..")
- @cc, @cflags, @includes = 'gcc', %W(-DDISABLE_GEMS -MMD), %W(#{@root}/include)
- @ldflags, @libs = [], %w(-lm)
- @ar = 'ar'
- @cxxflags, @objccflags, @asmflags = [], [], []
-
- @yacc, @gperf = 'bison', 'gperf'
- @cat, @git = 'cat', 'git'
+ class Toolchain
+ class << self
+ attr_accessor :toolchains
+ end
- @bins = %w(mruby mrbc mirb)
+ def initialize(name, &block)
+ @name, @initializer = name.to_s, block
+ MRuby::Toolchain.toolchains ||= {}
+ MRuby::Toolchain.toolchains[@name] = self
+ end
- @gems, @libmruby = [], []
+ def setup(conf)
+ conf.instance_eval(&@initializer)
+ end
- MRuby.targets[name.to_s] = self
- MRuby.build = self
- instance_eval(&block)
+ def toolchain(name)
+ @@toolchains[name.to_s].setup(self)
end
- def cxx; @cxx || cc; end
- def cxxflags; !@cxxflags || @cxxflags.empty? ? cflags : @cxxflags; end
+ def self.load
+ Dir.glob("#{File.dirname(__FILE__)}/toolchains/*.rake").each do |file|
+ Kernel.load file
+ end
+ end
+ end
+ Toolchain.load
- def objcc; @objcc || cc; end
- def objcflags; !@objcflags || @objcflags.empty? ? cflags : @objcflags; end
+ class Build
+ class << self
+ attr_accessor :current
+ end
+ include Rake::DSL
+ include LoadGems
+ attr_accessor :name, :bins, :exts, :file_separator
+ attr_reader :root, :libmruby, :gems
- def asm; @asm || cc; end
- def asmflags; !@asmflags || @asmflags.empty? ? cflags : @asmflags; end
+ COMPILERS = %w(cc cxx objc asm)
+ COMMANDS = COMPILERS + %w(linker archiver yacc gperf git exts mrbc)
+ attr_block MRuby::Build::COMMANDS
- def ld; @ld || cc; end
+ Exts = Struct.new(:object, :executable, :library)
- def gem(gemdir)
- gemdir = load_external_gem(gemdir) if gemdir.is_a?(Hash)
+ def initialize(name='host', &block)
+ MRuby::Build.current = self
+ @name = name
+ @root = File.expand_path("#{File.dirname(__FILE__)}/..")
- [@cflags, @cxxflags, @objcflags, @asmflags].each do |f|
- f.delete '-DDISABLE_GEMS' if f
+ if ENV['OS'] == 'Windows_NT'
+ @exts = Exts.new('.o', '.exe', '.a')
+ @file_separator = '\\'
+ else
+ @exts = Exts.new('.o', '', '.a')
+ @file_separator = '/'
end
- Gem::processing_path = gemdir
- load File.join(gemdir, "mrbgem.rake")
- end
- def load_external_gem(params)
- if params[:github]
- params[:git] = "[email protected]:#{params[:github]}.git"
- end
+ @cc = Command::Compiler.new(self, %w(.c))
+ @cxx = Command::Compiler.new(self, %w(.cc .cxx .cpp))
+ @objc = Command::Compiler.new(self, %w(.m))
+ @asm = Command::Compiler.new(self, %w(.S .asm))
+ @linker = Command::Linker.new(self)
+ @archiver = Command::Archiver.new(self)
+ @yacc = Command::Yacc.new(self)
+ @gperf = Command::Gperf.new(self)
+ @git = Command::Git.new(self)
+ @mrbc = Command::Mrbc.new(self)
- if params[:git]
- url = params[:git]
- gemdir = "build/mrbgems/#{url.match(/([-_\w]+)(\.[-_\w]+|)$/).to_a[1]}"
- return gemdir if File.exists?(gemdir)
- options = []
- options << "--branch \"#{params[:branch]}\"" if params[:branch]
- run_git_clone gemdir, url, options
- gemdir
- else
- fail "unknown gem option #{params}"
- end
- end
+ @bins = %w(mruby mrbc mirb)
+ @gems, @libmruby = [], []
- def enable_gems?
+ MRuby.targets[name.to_s] = self
+
+ instance_eval(&block)
+
+ compilers.each do |compiler|
+ compiler.defines -= %w(DISABLE_GEMS) if respond_to?(:enable_gems?) && enable_gems?
+ compiler.define_rules build_dir
+ end
end
- def gemlibs
- enable_gems? ? ["#{build_dir}/mrbgems/gem_init.o"] + @gems.map{ |g| g.lib } : []
+ def toolchain(name)
+ Toolchain.toolchains[name.to_s].setup(self)
end
def build_dir
- #@build_dir ||= "build/#{name}"
"build/#{self.name}"
end
def mrbcfile
- @mrbcfile ||= exefile("build/host/bin/mrbc")
- end
-
- def compile_c(outfile, infile, flags=[], includes=[])
- FileUtils.mkdir_p File.dirname(outfile)
- flags = [cflags, gems.map { |g| g.mruby_cflags }, flags]
- flags << [self.includes, gems.map { |g| g.mruby_includes }, includes].flatten.map { |f| "-I#{filename f}" }
- sh "#{filename cc} #{flags.flatten.join(' ')} -o #{filename outfile} -c #{filename infile}"
- end
-
- def compile_cxx(outfile, infile, flags=[], includes=[])
- FileUtils.mkdir_p File.dirname(outfile)
- flags = [cxxflags, gems.map { |g| g.mruby_cflags }, flags]
- flags << [self.includes, gems.map { |g| g.mruby_includes }, includes].flatten.map { |f| "-I#{filename f}" }
- sh "#{filename cxx} #{flags.flatten.join(' ')} -o #{filename outfile} -c #{filename infile}"
- end
-
- def compile_objc(outfile, infile, flags=[], includes=[])
- FileUtils.mkdir_p File.dirname(outfile)
- flags = [objcflags, gems.map { |g| g.mruby_cflags }, flags]
- flags << [self.includes, gems.map { |g| g.mruby_includes }, includes].flatten.map { |f| "-I#{filename f}" }
- sh "#{filename objcc} #{flags.flatten.join(' ')} -o #{filename outfile} -c #{filename infile}"
- end
-
- def compile_asm(outfile, infile, flags=[], includes=[])
- FileUtils.mkdir_p File.dirname(outfile)
- flags = [asmflags, gems.map { |g| g.mruby_cflags }, flags]
- flags << [self.includes, gems.map { |g| g.mruby_includes }, includes].flatten.map { |f| "-I#{filename f}" }
- sh "#{filename asm} #{flags.flatten.join(' ')} -o #{filename outfile} -c #{filename infile}"
- end
-
- def compile_mruby(outfile, infiles, funcname)
- cmd = "#{cat} #{filenames [infiles]} | #{filename mrbcfile} -B#{funcname}"
- if outfile.is_a?(IO)
- IO.popen("#{cmd} -o- -", 'r') do |f|
- outfile.puts f.read
- end
- else
- FileUtils.mkdir_p File.dirname(outfile)
- sh "#{cmd} -o#{filename outfile} -"
- end
- end
-
- def link(outfile, objfiles, flags=[], libs=[])
- FileUtils.mkdir_p File.dirname(outfile)
- flags = [ldflags, flags]
- libs = [libs, self.libs]
- sh "#{filename ld} -o #{filename outfile} #{flags.join(' ')} #{filenames objfiles} #{libs.flatten.join(' ')}"
+ exefile("build/host/bin/mrbc")
end
-
- def archive(outfile, options, objfiles)
- FileUtils.mkdir_p File.dirname(outfile)
- sh "#{filename ar} #{options} #{filename outfile} #{filenames objfiles}"
+
+ def compilers
+ COMPILERS.map do |c|
+ instance_variable_get("@#{c}")
+ end
end
- def run_yacc(outfile, infile)
- FileUtils.mkdir_p File.dirname(outfile)
- sh "#{filename yacc} -o #{filename outfile} #{filename infile}"
+ def filename(name)
+ if name.is_a?(Array)
+ name.map { |n| filename(n) }
+ else
+ '"%s"' % name.gsub('/', file_separator)
+ end
end
- def run_gperf(outfile, infile)
- FileUtils.mkdir_p File.dirname(outfile)
- sh %Q[#{filename gperf} -L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k"1,3,$" #{filename infile} > #{filename outfile}]
+ def exefile(name)
+ if name.is_a?(Array)
+ name.map { |n| exefile(n) }
+ else
+ "#{name}#{exts.executable}"
+ end
end
- def run_git_clone(gemdir, giturl, options=[])
- sh "#{filename git} clone #{options.join(' ')} #{filename giturl} #{filename gemdir}"
+ def objfile(name)
+ if name.is_a?(Array)
+ name.map { |n| objfile(n) }
+ else
+ "#{name}#{exts.object}"
+ end
end
+ def libfile(name)
+ if name.is_a?(Array)
+ name.map { |n| libfile(n) }
+ else
+ "#{name}#{exts.library}"
+ end
+ end
+ def run_test
+ puts ">>> Test #{name} <<<"
+ mrbtest = exefile("#{build_dir}/test/mrbtest")
+ sh "#{filename mrbtest}"
+ puts
+ end
end # Build
class CrossBuild < Build
- def initialize(name, &block)
- @name ||= name
- super(&block)
+ def run_test
+ mrbtest = exefile("#{build_dir}/test/mrbtest")
+ puts "You should run #{mrbtest} on target device."
+ puts
end
end # CrossBuild
end # MRuby