summaryrefslogtreecommitdiffstats
path: root/web/server/h2o/libh2o/deps/mruby/lib/mruby/build.rb
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--web/server/h2o/libh2o/deps/mruby/lib/mruby/build.rb355
1 files changed, 355 insertions, 0 deletions
diff --git a/web/server/h2o/libh2o/deps/mruby/lib/mruby/build.rb b/web/server/h2o/libh2o/deps/mruby/lib/mruby/build.rb
new file mode 100644
index 00000000..7d6aa49e
--- /dev/null
+++ b/web/server/h2o/libh2o/deps/mruby/lib/mruby/build.rb
@@ -0,0 +1,355 @@
+require "mruby/build/load_gems"
+require "mruby/build/command"
+
+module MRuby
+ class << self
+ def targets
+ @targets ||= {}
+ end
+
+ def each_target(&block)
+ return to_enum(:each_target) if block.nil?
+ @targets.each do |key, target|
+ target.instance_eval(&block)
+ end
+ end
+ end
+
+ class Toolchain
+ class << self
+ attr_accessor :toolchains
+ end
+
+ def initialize(name, &block)
+ @name, @initializer = name.to_s, block
+ MRuby::Toolchain.toolchains ||= {}
+ MRuby::Toolchain.toolchains[@name] = self
+ end
+
+ def setup(conf,params={})
+ conf.instance_exec(conf, params, &@initializer)
+ end
+
+ def self.load
+ Dir.glob("#{MRUBY_ROOT}/tasks/toolchains/*.rake").each do |file|
+ Kernel.load file
+ end
+ end
+ end
+ Toolchain.load
+
+ class Build
+ class << self
+ attr_accessor :current
+ end
+ include Rake::DSL
+ include LoadGems
+ attr_accessor :name, :bins, :exts, :file_separator, :build_dir, :gem_clone_dir
+ attr_reader :libmruby, :gems, :toolchains
+ attr_writer :enable_bintest, :enable_test
+
+ COMPILERS = %w(cc cxx objc asm)
+ COMMANDS = COMPILERS + %w(linker archiver yacc gperf git exts mrbc)
+ attr_block MRuby::Build::COMMANDS
+
+ Exts = Struct.new(:object, :executable, :library)
+
+ def initialize(name='host', build_dir=nil, &block)
+ @name = name.to_s
+
+ unless MRuby.targets[@name]
+ if ENV['OS'] == 'Windows_NT'
+ @exts = Exts.new('.o', '.exe', '.a')
+ else
+ @exts = Exts.new('.o', '', '.a')
+ end
+
+ build_dir = build_dir || ENV['MRUBY_BUILD_DIR'] || "#{MRUBY_ROOT}/build"
+
+ @file_separator = '/'
+ @build_dir = "#{build_dir}/#{@name}"
+ @gem_clone_dir = "#{build_dir}/mrbgems"
+ @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)
+
+ @bins = []
+ @gems, @libmruby = MRuby::Gem::List.new, []
+ @build_mrbtest_lib_only = false
+ @cxx_exception_enabled = false
+ @cxx_exception_disabled = false
+ @cxx_abi_enabled = false
+ @enable_bintest = false
+ @enable_test = false
+ @toolchains = []
+
+ MRuby.targets[@name] = self
+ end
+
+ MRuby::Build.current = MRuby.targets[@name]
+ MRuby.targets[@name].instance_eval(&block)
+
+ build_mrbc_exec if name == 'host'
+ build_mrbtest if test_enabled?
+ end
+
+ def enable_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
+
+ def disable_cxx_exception
+ if @cxx_exception_enabled or @cxx_abi_enabled
+ raise "cxx_exception already enabled"
+ end
+ @cxx_exception_disabled = true
+ end
+
+ def enable_cxx_exception
+ return if @cxx_exception_enabled
+ return if @cxx_abi_enabled
+ if @cxx_exception_disabled
+ raise "cxx_exception disabled"
+ end
+ @cxx_exception_enabled = true
+ compilers.each { |c|
+ c.defines += %w(MRB_ENABLE_CXX_EXCEPTION)
+ c.flags << c.cxx_exception_flag
+ }
+ linker.command = cxx.command if toolchains.find { |v| v == 'gcc' }
+ end
+
+ def cxx_exception_enabled?
+ @cxx_exception_enabled
+ end
+
+ def cxx_abi_enabled?
+ @cxx_abi_enabled
+ end
+
+ def enable_cxx_abi
+ return if @cxx_abi_enabled
+ if @cxx_exception_enabled
+ raise "cxx_exception already enabled"
+ end
+ compilers.each { |c|
+ c.defines += %w(MRB_ENABLE_CXX_EXCEPTION MRB_ENABLE_CXX_ABI)
+ c.flags << c.cxx_compile_flag
+ }
+ compilers.each { |c| c.flags << c.cxx_compile_flag }
+ 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|
+ FileUtils.mkdir_p File.dirname t.name
+ IO.write t.name, <<EOS
+#define __STDC_CONSTANT_MACROS
+#define __STDC_LIMIT_MACROS
+
+#ifndef MRB_ENABLE_CXX_ABI
+extern "C" {
+#endif
+#include "#{src}"
+#ifndef MRB_ENABLE_CXX_ABI
+}
+#endif
+EOS
+ 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
+
+ def bintest_enabled?
+ @enable_bintest
+ end
+
+ def toolchain(name, params={})
+ tc = Toolchain.toolchains[name.to_s]
+ fail "Unknown #{name} toolchain" unless tc
+ tc.setup(self, params)
+ @toolchains.unshift name.to_s
+ end
+
+ def primary_toolchain
+ @toolchains.first
+ end
+
+ def root
+ MRUBY_ROOT
+ end
+
+ def enable_test
+ @enable_test = true
+ end
+
+ def test_enabled?
+ @enable_test
+ end
+
+ def build_mrbtest
+ gem :core => 'mruby-test'
+ end
+
+ def build_mrbc_exec
+ gem :core => 'mruby-bin-mrbc'
+ end
+
+ def mrbcfile
+ 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
+ COMPILERS.map do |c|
+ instance_variable_get("@#{c}")
+ end
+ end
+
+ def define_rules
+ compilers.each do |compiler|
+ if respond_to?(:enable_gems?) && enable_gems?
+ compiler.defines -= %w(DISABLE_GEMS)
+ else
+ compiler.defines += %w(DISABLE_GEMS)
+ end
+ compiler.define_rules build_dir, File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
+ end
+ end
+
+ def filename(name)
+ if name.is_a?(Array)
+ name.flatten.map { |n| filename(n) }
+ else
+ '"%s"' % name.gsub('/', file_separator)
+ end
+ end
+
+ def cygwin_filename(name)
+ if name.is_a?(Array)
+ name.flatten.map { |n| cygwin_filename(n) }
+ else
+ '"%s"' % `cygpath -w "#{filename(name)}"`.strip
+ end
+ end
+
+ def exefile(name)
+ if name.is_a?(Array)
+ name.flatten.map { |n| exefile(n) }
+ else
+ "#{name}#{exts.executable}"
+ end
+ end
+
+ def objfile(name)
+ if name.is_a?(Array)
+ name.flatten.map { |n| objfile(n) }
+ else
+ "#{name}#{exts.object}"
+ end
+ end
+
+ def libfile(name)
+ if name.is_a?(Array)
+ name.flatten.map { |n| libfile(n) }
+ else
+ "#{name}#{exts.library}"
+ end
+ end
+
+ def build_mrbtest_lib_only
+ @build_mrbtest_lib_only = true
+ end
+
+ def build_mrbtest_lib_only?
+ @build_mrbtest_lib_only
+ end
+
+ def run_test
+ puts ">>> Test #{name} <<<"
+ mrbtest = exefile("#{build_dir}/bin/mrbtest")
+ sh "#{filename mrbtest.relative_path}#{$verbose ? ' -v' : ''}"
+ puts
+ run_bintest if bintest_enabled?
+ end
+
+ def run_bintest
+ targets = @gems.select { |v| File.directory? "#{v.dir}/bintest" }.map { |v| filename v.dir }
+ targets << filename(".") if File.directory? "./bintest"
+ sh "ruby test/bintest.rb #{targets.join ' '}"
+ end
+
+ def print_build_summary
+ puts "================================================"
+ puts " Config Name: #{@name}"
+ puts " Output Directory: #{self.build_dir.relative_path}"
+ puts " Binaries: #{@bins.join(', ')}" unless @bins.empty?
+ unless @gems.empty?
+ puts " Included Gems:"
+ @gems.map do |gem|
+ gem_version = " - #{gem.version}" if gem.version != '0.0.0'
+ gem_summary = " - #{gem.summary}" if gem.summary
+ puts " #{gem.name}#{gem_version}#{gem_summary}"
+ puts " - Binaries: #{gem.bins.join(', ')}" unless gem.bins.empty?
+ end
+ end
+ puts "================================================"
+ puts
+ end
+ end # Build
+
+ class CrossBuild < Build
+ attr_block %w(test_runner)
+ # cross compiling targets for building native extensions.
+ # host - arch of where the built binary will run
+ # build - arch of the machine building the binary
+ attr_accessor :host_target, :build_target
+
+ def initialize(name, build_dir=nil, &block)
+ @test_runner = Command::CrossTestRunner.new(self)
+ super
+ end
+
+ def mrbcfile
+ MRuby.targets['host'].exefile("#{MRuby.targets['host'].build_dir}/bin/mrbc")
+ end
+
+ def run_test
+ mrbtest = exefile("#{build_dir}/bin/mrbtest")
+ if (@test_runner.command == nil)
+ puts "You should run #{mrbtest} on target device."
+ puts
+ else
+ @test_runner.run(mrbtest)
+ end
+ end
+ end # CrossBuild
+end # MRuby