Index: EcnlProtoTool/trunk/mruby-1.3.0/tasks/gitlab.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/tasks/gitlab.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/tasks/gitlab.rake	(revision 331)
@@ -0,0 +1,118 @@
+CI_VERSION = '0.7'.freeze
+CI_BASE = 'ubuntu:16.10'.freeze
+CI_COMPILERS = ['gcc-4.7',
+                'gcc-4.8',
+                'gcc-4.9',
+                'gcc-5',
+                'gcc-6',
+                'clang-3.5',
+                'clang-3.6',
+                'clang-3.7',
+                'clang-3.8',
+                'clang-3.9'].freeze
+
+def ci_image_tag(compiler)
+  compiler.tr('+', 'c').delete('-').delete('.')
+end
+
+def ci_docker_tag(compiler)
+  tag = ci_image_tag(compiler)
+  "registry.gitlab.com/dabroz/mruby:#{tag}_#{CI_VERSION}"
+end
+
+def run_cmd(cmd)
+  puts cmd
+  raise 'error' unless system cmd
+end
+
+desc 'recreate docker images for GitLab builds'
+task :gitlab_dockers do
+  CI_COMPILERS.each do |compiler|
+    tag = ci_image_tag(compiler)
+    filename = "Dockerfile.#{tag}"
+    File.open(filename, 'wb') do |f|
+      f << "# #{compiler} - #{tag}\n"
+      f << "FROM #{CI_BASE}\n"
+      f << "RUN apt-get update && apt-get install -y git ruby2.3 ruby2.3-dev bison\n"
+      f << "RUN apt-get update && apt-get install -y binutils manpages\n"
+      f << "RUN apt-get update && apt-get install -y #{compiler}\n"
+      if compiler['gcc']
+        f << "RUN apt-get update && apt-get install -y libx32#{compiler}-dev\n"
+        f << "RUN apt-get update && apt-get install --no-install-recommends -y #{compiler}-multilib\n"
+      end
+      f << "RUN dpkg --add-architecture i386\n"
+      f << "RUN apt-get update && apt-get install -y linux-libc-dev:i386\n"
+      if compiler['clang']
+        f << "RUN apt-get update && apt-get install --no-install-recommends -y libc6-dev-i386\n"
+        f << "RUN apt-get update && apt-get install -y gcc gcc-multilib\n"
+      end
+    end
+    docker_tag = ci_docker_tag(compiler)
+    cmd1 = "docker build -t #{docker_tag} -f #{filename} ."
+    cmd2 = "docker push #{docker_tag}"
+    run_cmd cmd1
+    run_cmd cmd2
+    File.delete(filename)
+  end
+end
+
+desc 'create build configurations and update .gitlab-ci.yml'
+task :gitlab_config do
+  require 'yaml'
+
+  configs = []
+  [true, false].each do |mode_32|
+    ['', 'MRB_USE_FLOAT'].each do |float_conf|
+      ['', 'MRB_INT16', 'MRB_INT64'].each do |int_conf|
+        ['', 'MRB_NAN_BOXING', 'MRB_WORD_BOXING'].each do |boxing_conf|
+          ['', 'MRB_UTF8_STRING'].each do |utf8_conf|
+            next if (float_conf == 'MRB_USE_FLOAT') && (boxing_conf == 'MRB_NAN_BOXING')
+            next if (int_conf == 'MRB_INT64') && (boxing_conf == 'MRB_NAN_BOXING')
+            next if (int_conf == 'MRB_INT16') && (boxing_conf == 'MRB_WORD_BOXING')
+            next if (int_conf == 'MRB_INT64') && (boxing_conf == 'MRB_WORD_BOXING') && mode_32
+            env = [float_conf, int_conf, boxing_conf, utf8_conf].map do |conf|
+              conf == '' ? nil : "-D#{conf}=1"
+            end.compact.join(' ')
+            bit = mode_32 ? '-m32 ' : ''
+            _info = ''
+            _info += mode_32 ? '32bit ' : '64bit '
+            _info += float_conf['USE'] ? 'float ' : ''
+            _info += int_conf['16'] ? 'int16 ' : ''
+            _info += int_conf['64'] ? 'int64 ' : ''
+            _info += boxing_conf['NAN'] ? 'nan ' : ''
+            _info += boxing_conf['word'] ? 'word ' : ''
+            _info += utf8_conf['UTF8'] ? 'utf8 ' : ''
+            _info = _info.gsub(/ +/, ' ').strip.tr(' ', '_')
+            configs << { '_info' => _info, 'CFLAGS' => "#{bit}#{env}", 'LDFLAGS' => bit.strip.to_s }
+          end
+        end
+      end
+    end
+  end
+  path = './.gitlab-ci.yml'
+  data = YAML.load_file(path)
+  data.keys.select do |key|
+    key.start_with? 'Test'
+  end.each do |key|
+    data.delete(key)
+  end
+  CI_COMPILERS.each do |compiler|
+    configs.each do |config|
+      name = "Test #{compiler} #{config['_info']}"
+      hash = {
+        'CC' => compiler,
+        'CXX' => compiler.gsub('gcc', 'g++').gsub('clang', 'clang++'),
+        'LD' => compiler
+      }
+      hash = hash.merge(config)
+      hash.delete('_info')
+      data[name] = {
+        'stage' => 'test',
+        'image' => ci_docker_tag(compiler),
+        'variables' => hash,
+        'script' => 'env; ./minirake --verbose all test'
+      }
+    end
+  end
+  File.open(path, 'w') { |f| YAML.dump(data, f) }
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/tasks/libmruby.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/tasks/libmruby.rake	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/tasks/libmruby.rake	(revision 331)
@@ -6,15 +6,17 @@
   file "#{build_dir}/lib/libmruby.flags.mak" => [__FILE__, libfile("#{build_dir}/lib/libmruby")] do |t|
     open(t.name, 'w') do |f|
-      f.puts "MRUBY_CFLAGS = #{cc.all_flags.gsub('"', '\\"')}"
+      f.puts "MRUBY_CFLAGS = #{cc.all_flags}"
 
       gem_flags = gems.map { |g| g.linker.flags }
       gem_library_paths = gems.map { |g| g.linker.library_paths }
-      f.puts "MRUBY_LDFLAGS = #{linker.all_flags(gem_library_paths, gem_flags).gsub('"', '\\"')} #{linker.option_library_path % "#{build_dir}/lib"}"
+      f.puts "MRUBY_LDFLAGS = #{linker.all_flags(gem_library_paths, gem_flags)} #{linker.option_library_path % "#{build_dir}/lib"}"
 
       gem_flags_before_libraries = gems.map { |g| g.linker.flags_before_libraries }
-      f.puts "MRUBY_LDFLAGS_BEFORE_LIBS = #{[linker.flags_before_libraries, gem_flags_before_libraries].flatten.join(' ').gsub('"', '\\"')}"
+      f.puts "MRUBY_LDFLAGS_BEFORE_LIBS = #{[linker.flags_before_libraries, gem_flags_before_libraries].flatten.join(' ')}"
 
       gem_libraries = gems.map { |g| g.linker.libraries }
-      f.puts "MRUBY_LIBS = #{linker.option_library % 'mruby'} #{linker.library_flags(gem_libraries).gsub('"', '\\"')}"
+      f.puts "MRUBY_LIBS = #{linker.option_library % 'mruby'} #{linker.library_flags(gem_libraries)}"
+
+      f.puts "MRUBY_LIBMRUBY_PATH = #{libfile("#{build_dir}/lib/libmruby")}"
     end
   end
Index: EcnlProtoTool/trunk/mruby-1.3.0/tasks/mrbgem_spec.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/tasks/mrbgem_spec.rake	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/tasks/mrbgem_spec.rake	(revision 331)
@@ -2,4 +2,5 @@
 require 'forwardable'
 require 'tsort'
+require 'shellwords'
 
 module MRuby
@@ -18,4 +19,5 @@
       alias mruby build
       attr_accessor :build_config_initializer
+      attr_accessor :mrblib_dir, :objs_dir
 
       attr_accessor :version
@@ -45,4 +47,6 @@
         @initializer = block
         @version = "0.0.0"
+        @mrblib_dir = "mrblib"
+        @objs_dir = "src"
         MRuby::Gem.current = self
       end
@@ -55,6 +59,6 @@
         @linker = LinkerConfig.new([], [], [], [], [])
 
-        @rbfiles = Dir.glob("#{dir}/mrblib/**/*.rb").sort
-        @objs = Dir.glob("#{dir}/src/*.{c,cpp,cxx,cc,m,asm,s,S}").map do |f|
+        @rbfiles = Dir.glob("#{@dir}/#{@mrblib_dir}/**/*.rb").sort
+        @objs = Dir.glob("#{@dir}/#{@objs_dir}/*.{c,cpp,cxx,cc,m,asm,s,S}").map do |f|
           objfile(f.relative_path_from(@dir).to_s.pathmap("#{build_dir}/%X"))
         end
@@ -87,5 +91,7 @@
 
         instance_eval(&@build_config_initializer) if @build_config_initializer
-
+      end
+
+      def setup_compilers
         compilers.each do |compiler|
           compiler.define_rules build_dir, "#{dir}"
@@ -122,4 +128,19 @@
       def test_rbireps
         "#{build_dir}/gem_test.c"
+      end
+
+      def search_package(name, version_query=nil)
+        package_query = name
+        package_query += " #{version_query}" if version_query
+        _pp "PKG-CONFIG", package_query
+        escaped_package_query = Shellwords.escape(package_query)
+        if system("pkg-config --exists #{escaped_package_query}")
+          cc.flags += [`pkg-config --cflags #{escaped_package_query}`.strip]
+          cxx.flags += [`pkg-config --cflags #{escaped_package_query}`.strip]
+          linker.flags_before_libraries += [`pkg-config --libs #{escaped_package_query}`.strip]
+          true
+        else
+          false
+        end
       end
 
@@ -182,6 +203,6 @@
         print_gem_comment(f)
         f.puts %Q[#include <stdlib.h>] unless rbfiles.empty?
-        f.puts %Q[#include "mruby.h"]
-        f.puts %Q[#include "mruby/irep.h"] unless rbfiles.empty?
+        f.puts %Q[#include <mruby.h>]
+        f.puts %Q[#include <mruby/irep.h>] unless rbfiles.empty?
       end
 
@@ -190,8 +211,8 @@
         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"]
-        f.puts %Q[#include "mruby/variable.h"]
-        f.puts %Q[#include "mruby/hash.h"] unless test_args.empty?
+        f.puts %Q[#include <mruby.h>]
+        f.puts %Q[#include <mruby/irep.h>]
+        f.puts %Q[#include <mruby/variable.h>]
+        f.puts %Q[#include <mruby/hash.h>] unless test_args.empty?
       end
 
@@ -401,4 +422,6 @@
         @ary = tsort_dependencies gem_table.keys, gem_table, true
 
+        each(&:setup_compilers)
+
         each do |g|
           import_include_paths(g)
@@ -414,7 +437,10 @@
           import_include_paths(dep_g)
 
+          dep_g.export_include_paths.uniq!
           g.compilers.each do |compiler|
             compiler.include_paths += dep_g.export_include_paths
             g.export_include_paths += dep_g.export_include_paths
+            compiler.include_paths.uniq!
+            g.export_include_paths.uniq!
           end
         end
Index: EcnlProtoTool/trunk/mruby-1.3.0/tasks/mrbgems.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/tasks/mrbgems.rake	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/tasks/mrbgems.rake	(revision 331)
@@ -32,5 +32,5 @@
         f.puts %Q[ */]
         f.puts %Q[]
-        f.puts %Q[#include "mruby.h"]
+        f.puts %Q[#include <mruby.h>]
         f.puts %Q[]
         f.write gem_func_decls
Index: EcnlProtoTool/trunk/mruby-1.3.0/tasks/mruby_build.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/tasks/mruby_build.rake	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/tasks/mruby_build.rake	(revision 331)
@@ -84,6 +84,7 @@
         @gems, @libmruby = MRuby::Gem::List.new, []
         @build_mrbtest_lib_only = false
+        @cxx_exception_enabled = false
+        @cxx_exception_disabled = false
         @cxx_abi_enabled = false
-        @cxx_exception_disabled = false
         @enable_bintest = false
         @enable_test = false
@@ -111,5 +112,26 @@
 
     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
 
@@ -119,6 +141,13 @@
 
     def enable_cxx_abi
-      return if @cxx_exception_disabled or @cxx_abi_enabled
-      compilers.each { |c| c.defines += %w(MRB_ENABLE_CXX_EXCEPTION) }
+      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
@@ -136,9 +165,11 @@
 #define __STDC_LIMIT_MACROS
 
+#ifndef MRB_ENABLE_CXX_ABI
 extern "C" {
+#endif
 #include "#{src}"
+#ifndef MRB_ENABLE_CXX_ABI
 }
-
-#{src == "#{MRUBY_ROOT}/src/error.c"? 'mrb_int mrb_jmpbuf::jmpbuf_id = 0;' : ''}
+#endif
 EOS
       end
Index: EcnlProtoTool/trunk/mruby-1.3.0/tasks/mruby_build_commands.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/tasks/mruby_build_commands.rake	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/tasks/mruby_build_commands.rake	(revision 331)
@@ -43,4 +43,5 @@
     attr_accessor :flags, :include_paths, :defines, :source_exts
     attr_accessor :compile_options, :option_define, :option_include_path, :out_ext
+    attr_accessor :cxx_compile_flag, :cxx_exception_flag
 
     def initialize(build, source_exts=[])
Index: EcnlProtoTool/trunk/mruby-1.3.0/tasks/mruby_build_gem.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/tasks/mruby_build_gem.rake	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/tasks/mruby_build_gem.rake	(revision 331)
@@ -39,5 +39,5 @@
         Dir.glob("#{Gem.current.dir}/#{subdir}/*.{cpp,cxx,cc}")
       end.flatten
-      enable_cxx_abi unless cxx_srcs.empty?
+      enable_cxx_exception unless cxx_srcs.empty?
 
       Gem.current
Index: EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/android.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/tasks/toolchains/android.rake	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/android.rake	(revision 331)
@@ -1,14 +1,23 @@
 class MRuby::Toolchain::Android
-  DEFAULT_ARCH = 'armeabi'
-  DEFAULT_PLATFORM = 'android-14'
-  DEFAULT_TOOLCHAIN = :gcc
+
+  DEFAULT_ARCH = 'armeabi' # TODO : Revise if arch should have a default
+
+  DEFAULT_TOOLCHAIN = :clang
+
   DEFAULT_NDK_HOMES = %w{
+    /usr/local/opt/android-sdk/ndk-bundle
     /usr/local/opt/android-ndk
+    %LOCALAPPDATA%/Android/android-sdk/ndk-bundle
+    %LOCALAPPDATA%/Android/android-ndk
+    ~/Library/Android/sdk/ndk-bundle
+    ~/Library/Android/ndk
   }
-  TOOLCHAINS = [:gcc, :clang]
+
+  TOOLCHAINS = [:clang, :gcc]
+
   ARCHITECTURES = %w{
     armeabi armeabi-v7a arm64-v8a
+    x86 x86_64
     mips mips64
-    x86 x86_64
   }
 
@@ -22,8 +31,37 @@
   end
 
+  class PlatformDirNotFound < StandardError
+    def message
+        <<-EOM
+Couldn't find Android NDK platform directories.
+Set ANDROID_PLATFORM environment variable or set :platform parameter
+        EOM
+    end
+  end
+
   attr_reader :params
 
   def initialize(params)
     @params = params
+  end
+
+  def bin_gcc(command)
+    command = command.to_s
+
+    command = case arch
+      when /armeabi/    then 'arm-linux-androideabi-'
+      when /arm64-v8a/  then 'aarch64-linux-android-'
+      when /x86_64/     then 'x86_64-linux-android-'
+      when /x86/        then 'i686-linux-android-'
+      when /mips64/     then 'mips64el-linux-android-'
+      when /mips/       then 'mipsel-linux-android-'
+      end + command
+
+    gcc_toolchain_path.join('bin', command).to_s
+  end
+
+  def bin(command)
+    command = command.to_s
+    toolchain_path.join('bin', command).to_s
   end
 
@@ -31,99 +69,189 @@
     @home_path ||= Pathname(
       params[:ndk_home] ||
-        ENV['ANDROID_NDK_HOME'] ||
-        DEFAULT_NDK_HOMES.find{ |path| File.directory?(path) } ||
-        raise(AndroidNDKHomeNotFound)
+      ENV['ANDROID_NDK_HOME'] ||
+      DEFAULT_NDK_HOMES.find { |path|
+        path.gsub! '%LOCALAPPDATA%', ENV['LOCALAPPDATA'] || '%LOCALAPPDATA%'
+        path.gsub! '\\', '/'
+        path.gsub! '~', Dir.home || '~'
+        File.directory?(path)
+      } || raise(AndroidNDKHomeNotFound)
     )
   end
 
+  def toolchain
+    @toolchain ||= params.fetch(:toolchain){ DEFAULT_TOOLCHAIN }
+  end
+
+  def toolchain_path
+    @toolchain_path ||= case toolchain
+      when :gcc
+        gcc_toolchain_path
+      when :clang
+        home_path.join('toolchains', 'llvm' , 'prebuilt', host_platform)
+      end
+  end
+
+  def gcc_toolchain_path
+    if @gcc_toolchain_path === nil then
+      prefix = case arch
+        when /armeabi/    then 'arm-linux-androideabi-'
+        when /arm64-v8a/  then 'aarch64-linux-android-'
+        when /x86_64/     then 'x86_64-'
+        when /x86/        then 'x86-'
+        when /mips64/     then 'mips64el-linux-android-'
+        when /mips/       then 'mipsel-linux-android-'
+        end
+
+      test = case arch
+        when /armeabi/    then 'arm-linux-androideabi-*'
+        when /arm64-v8a/  then 'aarch64-linux-android-*'
+        when /x86_64/     then 'x86_64-*'
+        when /x86/        then 'x86-*'
+        when /mips64/     then 'mips64el-linux-android-*'
+        when /mips/       then 'mipsel-linux-android-*'
+        end
+
+      gcc_toolchain_version = Dir[home_path.join('toolchains', test)].map{|t| t.match(/-(\d+\.\d+)$/); $1.to_f }.max
+      @gcc_toolchain_path = home_path.join('toolchains', prefix + gcc_toolchain_version.to_s, 'prebuilt', host_platform)
+    end
+    @gcc_toolchain_path
+  end
+
+  def host_platform
+    @host_platform ||= case RUBY_PLATFORM
+      when /cygwin|mswin|mingw|bccwin|wince|emx/i
+        path = home_path.join('toolchains', 'llvm' , 'prebuilt', 'windows*')
+        Dir.glob(path.to_s){ |item|
+          next if File.file?(item)
+          path = Pathname(item)
+          break
+        }
+        path.basename
+      when /x86_64-darwin/i
+        'darwin-x86_64'
+      when /darwin/i
+        'darwin-x86'
+      when /x86_64-linux/i
+        'linux-x86_64'
+      when /linux/i
+        'linux-x86'
+      else
+        raise NotImplementedError, "Unknown host platform (#{RUBY_PLATFORM})"
+      end
+  end
+
   def arch
-    params.fetch(:arch){ DEFAULT_ARCH }
+    @arch ||= (params[:arch] || ENV['ANDROID_ARCH'] || DEFAULT_ARCH).to_s
+  end
+
+  def sysroot
+    @sysroot ||= home_path.join('platforms', platform,
+        case arch
+        when /armeabi/    then 'arch-arm'
+        when /arm64-v8a/  then 'arch-arm64'
+        when /x86_64/     then 'arch-x86_64'
+        when /x86/        then 'arch-x86'
+        when /mips64/     then 'arch-mips64'
+        when /mips/       then 'arch-mips'
+        end
+      ).to_s
   end
 
   def platform
-    params.fetch(:platform){ DEFAULT_PLATFORM }
-  end
-
-  def toolchain
-    params.fetch(:toolchain){ DEFAULT_TOOLCHAIN }
-  end
-
-  def toolchain_version
-    params.fetch(:toolchain_version) do
-      test = case toolchain
-      when :gcc
-        case arch
-        when /armeabi/
-          'arm-linux-androideabi-*'
-        when /arm64/
-          'aarch64-linux-android-*'
-        when /mips64/
-          'mips64el-linux-android-*'
-        when /mips/
-          'mipsel-linux-android-*'
-        when /x86_64/
-          'x86_64-*'
-        when /x86/
-          'x86-*'
+    if @platform === nil then
+      @platform = params[:platform] || ENV['ANDROID_PLATFORM'] || nil
+      if @platform === nil
+        Dir.glob(home_path.join('platforms/android-*').to_s){ |item|
+          next if File.file?(item)
+          if @platform === nil
+            @platform = Integer(item.rpartition('-')[2])
+          else
+            platform = Integer(item.rpartition('-')[2])
+            @platform = platform > @platform ? platform : @platform
+          end
+        }
+        if @platform === nil
+          raise(PlatformDirNotFound)
+        else
+          @platform = "android-#{@platform}"
         end
-      when :clang
-        'llvm-*'
-      end
-
-      Dir[home_path.join('toolchains',test)].map{|t| t.match(/-(\d+\.\d+)$/); $1.to_f }.max
-    end
-  end
-
-  def toolchain_path
-    prefix = case toolchain
-             when :clang then 'llvm-'
-             when :gcc
-               case arch
-               when /armeabi/ then 'arm-linux-androideabi-'
-               when /arm64/   then 'aarch64-linux-android-'
-               when /x86_64/  then 'x86_64-'
-               when /x86/     then 'x86-'
-               when /mips64/  then 'mips64el-linux-android-'
-               when /mips/    then 'mipsel-linux-android-'
-               end
-             end
-    home_path.join('toolchains', prefix + toolchain_version.to_s, 'prebuilt', host_platform)
-  end
-
-  def sysroot
-    path = case arch
-           when /armeabi/ then 'arch-arm'
-           when /arm64/   then 'arch-arm64'
-           when /x86_64/  then 'arch-x86_64'
-           when /x86/     then 'arch-x86'
-           when /mips64/  then 'arch-mips64'
-           when /mips/    then 'arch-mips'
-           end
-
-    home_path.join('platforms', platform, path).to_s
-  end
-
-  def bin(command)
-    command = command.to_s
-
-    if toolchain == :gcc
-      command = case arch
-                when /armeabi/ then 'arm-linux-androideabi-'
-                when /arm64/   then 'aarch64-linux-android-'
-                when /x86_64/  then 'x86_64-linux-android-'
-                when /x86/     then 'i686-linux-android-'
-                when /mips64/  then 'mips64el-linux-android-'
-                when /mips/    then 'mipsel-linux-android-'
-                end + command
-    end
-
-    toolchain_path.join('bin',command).to_s
+      end
+    end
+    if Integer(@platform.rpartition('-')[2]) < 21
+      case arch
+      when /arm64-v8a/, /x86_64/, /mips64/
+        raise NotImplementedError, "Platform (#{@platform}) has no implementation for architecture (#{arch})"
+      end
+    end
+    @platform
+  end
+
+  def armeabi_v7a_mfpu
+    @armeabi_v7a_mfpu ||= (params[:mfpu] || 'vfpv3-d16').to_s
+  end
+
+  def armeabi_v7a_mfloat_abi
+    @armeabi_v7a_mfloat_abi ||= (params[:mfloat_abi] || 'softfp').to_s
+  end
+
+  def no_warn_mismatch
+    if %W(soft softfp).include? armeabi_v7a_mfloat_abi
+      ''
+    else
+      ',--no-warn-mismatch'
+    end
   end
 
   def cc
     case toolchain
-    when :gcc   then bin(:gcc)
-    when :clang then bin(:clang)
-    end
+    when :gcc then bin_gcc('gcc')
+    when :clang then bin('clang')
+    end
+  end
+
+  def ar
+    case toolchain
+    when :gcc   then bin_gcc('ar')
+    when :clang then bin_gcc('ar')
+    end
+  end
+
+  def ctarget
+    flags = []
+
+    case toolchain
+    when :gcc
+      case arch
+      when /armeabi-v7a/  then flags += %W(-march=armv7-a)
+      when /armeabi/      then flags += %W(-march=armv5te)
+      when /arm64-v8a/    then flags += %W(-march=armv8-a)
+      when /x86_64/       then flags += %W(-march=x86-64)
+      when /x86/          then flags += %W(-march=i686)
+      when /mips64/       then flags += %W(-march=mips64r6)
+      when /mips/         then flags += %W(-march=mips32)
+      end
+    when :clang
+      case arch
+      when /armeabi-v7a/  then flags += %W(-target armv7-none-linux-androideabi)
+      when /armeabi/      then flags += %W(-target armv5te-none-linux-androideabi)
+      when /arm64-v8a/    then flags += %W(-target aarch64-none-linux-android)
+      when /x86_64/       then flags += %W(-target x86_64-none-linux-android)
+      when /x86/          then flags += %W(-target i686-none-linux-android)
+      when /mips64/       then flags += %W(-target mips64el-none-linux-android)
+      when /mips/         then flags += %W(-target mipsel-none-linux-android)
+      end
+    end
+
+    case arch
+    when /armeabi-v7a/  then flags += %W(-mfpu=#{armeabi_v7a_mfpu} -mfloat-abi=#{armeabi_v7a_mfloat_abi})
+    when /armeabi/      then flags += %W(-mtune=xscale -msoft-float)
+    when /arm64-v8a/    then flags += %W()
+    when /x86_64/       then flags += %W()
+    when /x86/          then flags += %W()
+    when /mips64/       then flags += %W(-fmessage-length=0)
+    when /mips/         then flags += %W(-fmessage-length=0)
+    end
+
+    flags
   end
 
@@ -131,86 +259,63 @@
     flags = []
 
+    flags += %W(-MMD -MP -D__android__ -DANDROID --sysroot="#{sysroot}")
+    flags += ctarget
     case toolchain
     when :gcc
-      flags += %W(-ffunction-sections -funwind-tables -no-canonical-prefixes)
-      flags += %W(-D__android__ -mandroid --sysroot="#{sysroot}")
-      case arch
-      when /arm64/
-        flags += %W(-fpic -fstack-protector-strong)
-      when 'armeabi-v7a-hard'
-        flags += %W(-fpic -fstack-protector-strong -march=armv7-a -mhard-float -D_NDK_MATH_NO_SOFTFP=1 -mfpu=vfpv3-d16)
-      when 'armeabi-v7a'
-        flags += %W(-fpic -fstack-protector-strong -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16)
-      when /arm/
-        flags += %W(-fpic -fstack-protector-strong -march=armv5te -mtune=xscale -msoft-float)
-      when /mips/
-        flags += %W(-fpic -fno-strict-aliasing -finline-functions -fmessage-length=0 -fno-inline-functions-called-once -fgcse-after-reload -frerun-cse-after-loop -frename-registers)
-      when /x86/
-        flags += %W(-fstack-protector-strong)
-      end
     when :clang
-    end
+      flags += %W(-gcc-toolchain "#{gcc_toolchain_path.to_s}" -Wno-invalid-command-line-argument -Wno-unused-command-line-argument)
+    end
+    flags += %W(-fpic -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes)
 
     flags
-  end
-
-  def ld
-    cc
   end
 
   def ldflags
     flags = []
+
+    flags += %W(--sysroot="#{sysroot}")
+
+    flags
+  end
+
+  def ldflags_before_libraries
+    flags = []
+
     case toolchain
     when :gcc
-      flags += %W(-no-canonical-prefixes)
-      flags += %W(-D__android__ -mandroid --sysroot="#{sysroot}")
-      case arch
-      when 'armeabi-v7a-hard'
-        flags += %W(-march=armv7-a -Wl,--fix-cortex-a8 -Wl,--no-warn-mismatch -lm_hard)
-      when 'armeabi-v7a'
-        flags += %W(-march=armv7-a -Wl,--fix-cortex-a8)
-      end
-    end
-    
+      case arch
+      when /armeabi-v7a/  then flags += %W(-Wl#{no_warn_mismatch})
+      end
+    when :clang
+      flags += %W(-gcc-toolchain "#{gcc_toolchain_path.to_s}")
+      case arch
+      when /armeabi-v7a/  then flags += %W(-target armv7-none-linux-androideabi -Wl,--fix-cortex-a8#{no_warn_mismatch})
+      when /armeabi/      then flags += %W(-target armv5te-none-linux-androideabi)
+      when /arm64-v8a/    then flags += %W(-target aarch64-none-linux-android)
+      when /x86_64/       then flags += %W(-target x86_64-none-linux-android)
+      when /x86/          then flags += %W(-target i686-none-linux-android)
+      when /mips64/       then flags += %W(-target mips64el-none-linux-android)
+      when /mips/         then flags += %W(-target mipsel-none-linux-android)
+      end
+    end
+    flags += %W(-no-canonical-prefixes)
+
     flags
   end
-
-  def ar
-    case toolchain
-    when :gcc   then bin(:ar)
-    when :clang then bin('llvm-ar')
-    end
-  end
-
-  def host_platform
-    case RUBY_PLATFORM
-    when /cygwin|mswin|mingw|bccwin|wince|emx/i
-      'windows'
-    when /x86_64-darwin/i
-      'darwin-x86_64'
-    when /darwin/i
-      'darwin-x86'
-    when /x86_64-linux/i
-      'linux-x86_64'
-    when /linux/i
-      'linux-x86'
-    else
-      raise NotImplementedError, "Unknown host platform (#{RUBY_PLATFORM})"
-    end
-  end
 end
 
 MRuby::Toolchain.new(:android) do |conf, params|
-  ndk = MRuby::Toolchain::Android.new(params)
-
-  toolchain ndk.toolchain
+  android = MRuby::Toolchain::Android.new(params)
+
+  toolchain android.toolchain
 
   [conf.cc, conf.cxx, conf.objc, conf.asm].each do |cc|
-    cc.command = ndk.cc
-    cc.flags = ndk.cflags
-  end
-  conf.linker.command = ndk.ld
-  conf.linker.flags = ndk.ldflags
-  conf.archiver.command = ndk.ar
+    cc.command = android.cc
+    cc.flags = android.cflags
+  end
+
+  conf.archiver.command = android.ar
+  conf.linker.command = android.cc
+  conf.linker.flags = android.ldflags
+  conf.linker.flags_before_libraries = android.ldflags_before_libraries
 end
-
Index: EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/clang.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/tasks/toolchains/clang.rake	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/clang.rake	(revision 331)
@@ -1,3 +1,3 @@
-MRuby::Toolchain.new(:clang) do |conf|
+MRuby::Toolchain.new(:clang) do |conf, _params|
   toolchain :gcc
 
Index: EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/gcc.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/tasks/toolchains/gcc.rake	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/gcc.rake	(revision 331)
@@ -1,3 +1,3 @@
-MRuby::Toolchain.new(:gcc) do |conf|
+MRuby::Toolchain.new(:gcc) do |conf, _params|
   [conf.cc, conf.objc, conf.asm].each do |cc|
     cc.command = ENV['CC'] || 'gcc'
@@ -7,4 +7,6 @@
     cc.option_define = '-D%s'
     cc.compile_options = '%{flags} -MMD -o %{outfile} -c %{infile}'
+    cc.cxx_compile_flag = '-x c++ -std=c++03'
+    cc.cxx_exception_flag = '-fexceptions'
   end
 
@@ -16,4 +18,6 @@
     cxx.option_define = '-D%s'
     cxx.compile_options = '%{flags} -MMD -o %{outfile} -c %{infile}'
+    cxx.cxx_compile_flag = '-x c++ -std=c++03'
+    cxx.cxx_exception_flag = '-fexceptions'
   end
 
Index: EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/openwrt.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/openwrt.rake	(revision 331)
+++ EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/openwrt.rake	(revision 331)
@@ -0,0 +1,38 @@
+# usage of environmental variables to set the
+# cross compiling toolchain proper
+MRuby::Toolchain.new(:openwrt) do |conf|
+  [conf.cc, conf.objc, conf.asm].each do |cc|
+    cc.command = ENV['TARGET_CC']
+    cc.flags = ENV['TARGET_CFLAGS']
+    cc.include_paths = ["#{MRUBY_ROOT}/include"]
+    cc.defines = %w(DISABLE_GEMS)
+    cc.option_include_path = '-I%s'
+    cc.option_define = '-D%s'
+    cc.compile_options = '%{flags} -MMD -o %{outfile} -c %{infile}'
+  end
+
+  [conf.cxx].each do |cxx|
+    cxx.command = ENV['TARGET_CXX']
+    cxx.flags = ENV['TARGET_CXXFLAGS']
+    cxx.include_paths = ["#{MRUBY_ROOT}/include"]
+    cxx.defines = %w(DISABLE_GEMS)
+    cxx.option_include_path = '-I%s'
+    cxx.option_define = '-D%s'
+    cxx.compile_options = '%{flags} -MMD -o %{outfile} -c %{infile}'
+   end
+
+  conf.linker do |linker|
+    linker.command = ENV['TARGET_CC']
+    linker.flags = ENV['TARGET_LDFLAGS']
+    linker.libraries = %w(m)
+    linker.library_paths = []
+    linker.option_library = '-l%s'
+    linker.option_library_path = '-L%s'
+    linker.link_options = '%{flags} -o %{outfile} %{objs} %{flags_before_libraries} %{libs} %{flags_after_libraries}'
+  end
+
+  conf.archiver do |archiver|
+    archiver.command = ENV['TARGET_AR']
+    archiver.archive_options = 'rs %{outfile} %{objs}'
+  end
+end
Index: EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/visualcpp.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/tasks/toolchains/visualcpp.rake	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/tasks/toolchains/visualcpp.rake	(revision 331)
@@ -1,27 +1,24 @@
-MRuby::Toolchain.new(:visualcpp) do |conf|
+MRuby::Toolchain.new(:visualcpp) do |conf, _params|
   conf.cc do |cc|
     cc.command = ENV['CC'] || 'cl.exe'
-    cc.flags = [ENV['CFLAGS'] || %w(/c /nologo /utf-8 /W4 /GS /analyze- /Zc:wchar_t /ZI /Gm /Od /Zc:inline /fp:precise /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /Oy- /MDd /EHsc /DWIN32 /D_DEBUG /D_CONSOLE /D_CRT_SECURE_NO_WARNINGS)]
-    cc.flags << %w(/we4002 /we4003 /we4005 /we4007 /we4010 /we4013 /we4015 /we4020 /we4022 /we4024 /we4028 /we4029 /we4031 /we4033 /we4034 /we4042 /we4047 /we4048 /we4049 /we4056 /we4067 /we4074 /we4079 /we4083 /we4088 /we4089 /we4090 /we4091 /we4094 /we4096 /we4098 /we4099 /we4113 /we4133 /we4715 /we4716)
-    cc.flags << %w(/wd4214 /wd4100 /wd4996)
-    cc.flags << "/Fd\"#{conf.build_dir}\\vc140.pdb\""
-    cc.flags << "/Fp\"%{outdir}\\%{outfilebase}.pch\""
+    # C4013: implicit function declaration
+    cc.flags = [ENV['CFLAGS'] || %w(/c /nologo /W3 /we4013 /Zi /MD /O2 /utf-8 /D_CRT_SECURE_NO_WARNINGS)]
     cc.defines = %w(DISABLE_GEMS MRB_STACK_EXTEND_DOUBLING)
     cc.option_include_path = '/I%s'
     cc.option_define = '/D%s'
     cc.compile_options = "%{flags} /Fo%{outfile} %{infile}"
+    cc.cxx_compile_flag = '/TP'
+    cc.cxx_exception_flag = '/EHs'
   end
 
   conf.cxx do |cxx|
     cxx.command = ENV['CXX'] || 'cl.exe'
-    cxx.flags = [ENV['CXXFLAGS'] || ENV['CFLAGS'] || %w(/c /utf-8 /nologo /W4 /GS /analyze- /Zc:wchar_t /ZI /Gm /Od /Zc:inline /fp:precise /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /Oy- /MDd /EHsc /DWIN32 /D_DEBUG /D_CONSOLE /D_CRT_SECURE_NO_WARNINGS)]
-    cxx.flags << %w(/we4002 /we4003 /we4005 /we4007 /we4010 /we4013 /we4015 /we4020 /we4022 /we4024 /we4028 /we4029 /we4031 /we4033 /we4034 /we4042 /we4047 /we4048 /we4049 /we4056 /we4067 /we4074 /we4079 /we4083 /we4088 /we4089 /we4090 /we4091 /we4094 /we4096 /we4098 /we4099 /we4113 /we4133 /we4715 /we4716)
-    cxx.flags << %w(/wd4214 /wd4100 /wd4996)
-    cxx.flags << "/Fd\"#{conf.build_dir}\\vc140.pdb\""
-    cxx.flags << "/Fp\"%{outdir}\\%{outfilebase}.pch\""
+    cxx.flags = [ENV['CXXFLAGS'] || ENV['CFLAGS'] || %w(/c /nologo /W3 /Zi /MD /O2 /EHs /utf-8 /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'
     cxx.compile_options = "%{flags} /Fo%{outfile} %{infile}"
+    cxx.cxx_compile_flag = '/TP'
+    cxx.cxx_exception_flag = '/EHs'
   end
 
@@ -61,3 +58,14 @@
 
   conf.file_separator = '\\'
+
+  if require 'open3'
+    Open3.popen3 conf.cc.command do |_, _, e, _|
+      if /Version (\d{2})\.\d{2}\.\d{5}/ =~ e.gets && $1.to_i <= 17
+        m = "# VS2010/2012 support will be dropped after the next release! #"
+        h = "#" * m.length
+        puts h, m, h
+      end
+    end
+  end
+
 end
