summaryrefslogtreecommitdiffhomepage
path: root/tasks
diff options
context:
space:
mode:
Diffstat (limited to 'tasks')
-rw-r--r--tasks/benchmark.rake12
-rw-r--r--tasks/bin.rake23
-rw-r--r--tasks/core.rake12
-rw-r--r--tasks/doc.rake60
-rw-r--r--tasks/gitlab.rake118
-rw-r--r--tasks/libmruby.rake31
-rw-r--r--tasks/mrbgems.rake26
-rw-r--r--tasks/mrblib.rake40
-rw-r--r--tasks/presym.rake48
-rw-r--r--tasks/test.rake69
-rw-r--r--tasks/toolchains/android.rake51
-rw-r--r--tasks/toolchains/clang.rake7
-rw-r--r--tasks/toolchains/gcc.rake48
-rw-r--r--tasks/toolchains/openwrt.rake32
-rw-r--r--tasks/toolchains/visualcpp.rake58
15 files changed, 408 insertions, 227 deletions
diff --git a/tasks/benchmark.rake b/tasks/benchmark.rake
index 84e69ebee..12e0d4602 100644
--- a/tasks/benchmark.rake
+++ b/tasks/benchmark.rake
@@ -5,14 +5,14 @@ end
$dat_files = []
def bm_files
- Dir.glob("#{MRUBY_ROOT}/benchmark/bm_*.rb")
+ Dir.glob("#{MRUBY_ROOT}/benchmark/bm_*.rb").sort
end
def build_config_name
- if ENV['MRUBY_CONFIG']
+ if !ENV['MRUBY_CONFIG'].to_s.empty?
File.basename(ENV['MRUBY_CONFIG'], '.rb').gsub('build_config_', '')
else
- "build"
+ "bm"
end
end
@@ -50,7 +50,7 @@ end
MRuby.each_target do |target|
- next if target.name == 'host'
+ next if target.name == 'host' || target.internal?
mruby_bin = "#{target.build_dir}/bin/mruby"
bm_files.each do |bm_file|
@@ -67,8 +67,8 @@ MRuby.each_target do |target|
puts "..."
data = (0...MRuby::BENCHMARK_REPEAT).map do |n|
- str = %x{(time -f "%e %S %U" #{mruby_bin} #{bm_file}) 2>&1 >/dev/null}
- str.split(' ').map(&:to_f)
+ str = %x{(time -p #{mruby_bin} #{bm_file}) 2>&1 >/dev/null}
+ str.scan(/\d+\.\d+$/).map(&:to_f) # [real, user, sys]
end
File.open(task.name, "w") do |f|
diff --git a/tasks/bin.rake b/tasks/bin.rake
new file mode 100644
index 000000000..5c764458d
--- /dev/null
+++ b/tasks/bin.rake
@@ -0,0 +1,23 @@
+MRuby.each_target do |build|
+ if build.host? && build.mrbc_build && !build.gems["mruby-bin-mrbc"]
+ exe = build.exefile("#{build.mrbc_build.build_dir}/bin/mrbc")
+ build.products << build.define_installer(exe)
+ end
+
+ build.bins.each{|bin| build.products << define_installer_if_needed(bin)}
+
+ build.gems.each do |gem|
+ linker_attrs = build.gems.linker_attrs(gem)
+ gem.bins.each do |bin|
+ exe = build.exefile("#{build.build_dir}/bin/#{bin}")
+ objs = Dir["#{gem.dir}/tools/#{bin}/*.{c,cpp,cxx,cc}"].map do |f|
+ build.objfile(f.pathmap("#{gem.build_dir}/tools/#{bin}/%n"))
+ end
+ file exe => objs.concat(build.libraries) do |t|
+ build.linker.run t.name, t.prerequisites, *linker_attrs
+ end
+
+ build.products << define_installer_if_needed(bin)
+ end
+ end
+end
diff --git a/tasks/core.rake b/tasks/core.rake
new file mode 100644
index 000000000..a47722e8b
--- /dev/null
+++ b/tasks/core.rake
@@ -0,0 +1,12 @@
+as_cxx_srcs = %w[vm error gc].map{|name| "#{MRUBY_ROOT}/src/#{name}.c"}
+
+MRuby.each_target do
+ objs = Dir.glob("#{MRUBY_ROOT}/src/*.c").map do |src|
+ if cxx_exception_enabled? && as_cxx_srcs.include?(src)
+ compile_as_cxx(src)
+ else
+ objfile(src.pathmap("#{build_dir}/src/%n"))
+ end
+ end
+ self.libmruby_core_objs << objs
+end
diff --git a/tasks/doc.rake b/tasks/doc.rake
new file mode 100644
index 000000000..8013ed038
--- /dev/null
+++ b/tasks/doc.rake
@@ -0,0 +1,60 @@
+desc 'generate document'
+task :doc => %w[doc:api doc:capi]
+
+namespace :doc do
+ desc 'generate yard docs'
+ task :api do
+ begin
+ sh "mrbdoc"
+ rescue
+ puts "ERROR: To generate yard documentation, you should install yard-mruby gem."
+ puts " $ gem install yard-mruby yard-coderay"
+ end
+ end
+
+ desc 'generate doxygen docs'
+ task :capi do
+ begin
+ sh "doxygen Doxyfile"
+ rescue
+ puts "ERROR: To generate C API documents, you need Doxygen."
+ puts " $ sudo apt-get install doxygen"
+ end
+ end
+
+ desc 'clean all built docs'
+ task :clean => %w[clean:api clean:capi]
+
+ namespace :clean do
+ desc 'clean yard docs'
+ task :api do
+ rm_rf 'doc/api'
+ end
+
+ desc 'clean doxygen docs'
+ task :capi do
+ rm_rf 'doc/capi'
+ end
+ end
+
+ namespace :view do
+ desc 'open yard docs'
+ task :api do
+ sh 'xdg-open doc/api/index.html'
+ end
+
+ desc 'open doxygen docs'
+ task :capi do
+ sh 'xdg-open doc/capi/html/index.html'
+ end
+ end
+end
+
+# deprecated
+task "api_doc" => "doc:api"
+task "capi_doc" => "doc:capi"
+task "clean_doc" => "doc:clean"
+task "clean_api_doc" => "doc:clean:api"
+task "clean_capi_doc" => "doc:clean:capi"
+task "view_api" => "doc:view:api"
+task "view_capi" => "doc:view:capi"
diff --git a/tasks/gitlab.rake b/tasks/gitlab.rake
deleted file mode 100644
index 471172377..000000000
--- a/tasks/gitlab.rake
+++ /dev/null
@@ -1,118 +0,0 @@
-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
diff --git a/tasks/libmruby.rake b/tasks/libmruby.rake
index b6ef29986..9a7a57ff7 100644
--- a/tasks/libmruby.rake
+++ b/tasks/libmruby.rake
@@ -1,25 +1,38 @@
MRuby.each_target do
- file libfile("#{build_dir}/lib/libmruby") => libmruby.flatten do |t|
+ file libmruby_core_static => libmruby_core_objs.flatten do |t|
archiver.run t.name, t.prerequisites
end
- file "#{build_dir}/lib/libmruby.flags.mak" => [__FILE__, libfile("#{build_dir}/lib/libmruby")] do |t|
- FileUtils.mkdir_p File.dirname t.name
+ products << libmruby_core_static
+
+ next unless libmruby_enabled?
+
+ file libmruby_static => libmruby_objs.flatten do |t|
+ archiver.run t.name, t.prerequisites
+ end
+
+ file "#{build_dir}/lib/libmruby.flags.mak" => [__FILE__, libmruby_static] do |t|
+ mkdir_p File.dirname t.name
open(t.name, 'w') do |f|
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_CC = #{cc.command}"
+ f.puts "MRUBY_LD = #{linker.command}"
+
+ libgems = gems.reject{|g| g.bin?}
+ gem_flags = libgems.map {|g| g.linker.flags }
+ gem_library_paths = libgems.map {|g| g.linker.library_paths }
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 }
+ gem_flags_before_libraries = libgems.map {|g| g.linker.flags_before_libraries }
f.puts "MRUBY_LDFLAGS_BEFORE_LIBS = #{[linker.flags_before_libraries, gem_flags_before_libraries].flatten.join(' ')}"
- gem_libraries = gems.map { |g| g.linker.libraries }
+ gem_libraries = libgems.map {|g| g.linker.libraries }
f.puts "MRUBY_LIBS = #{linker.option_library % 'mruby'} #{linker.library_flags(gem_libraries)}"
- f.puts "MRUBY_LIBMRUBY_PATH = #{libfile("#{build_dir}/lib/libmruby")}"
+ f.puts "MRUBY_LIBMRUBY_PATH = #{libmruby_static}"
end
end
- task :all => "#{build_dir}/lib/libmruby.flags.mak"
+
+ products << libmruby_static
end
diff --git a/tasks/mrbgems.rake b/tasks/mrbgems.rake
index e2aeb1514..4f24cfd93 100644
--- a/tasks/mrbgems.rake
+++ b/tasks/mrbgems.rake
@@ -1,14 +1,16 @@
MRuby.each_target do
+ active_gems_txt = "#{build_dir}/mrbgems/active_gems.txt"
+
if enable_gems?
# set up all gems
gems.each(&:setup)
gems.check self
# loader all gems
- self.libmruby << objfile("#{build_dir}/mrbgems/gem_init")
+ self.libmruby_objs << objfile("#{build_dir}/mrbgems/gem_init")
file objfile("#{build_dir}/mrbgems/gem_init") => ["#{build_dir}/mrbgems/gem_init.c", "#{build_dir}/LEGAL"]
- file "#{build_dir}/mrbgems/gem_init.c" => [MRUBY_CONFIG, __FILE__] do |t|
- FileUtils.mkdir_p "#{build_dir}/mrbgems"
+ file "#{build_dir}/mrbgems/gem_init.c" => [active_gems_txt, MRUBY_CONFIG, __FILE__] do |t|
+ mkdir_p "#{build_dir}/mrbgems"
open(t.name, 'w') do |f|
gem_func_gems = gems.select { |g| g.generate_functions }
gem_func_decls = gem_func_gems.each_with_object('') do |g, s|
@@ -35,7 +37,7 @@ MRuby.each_target do
f.puts %Q[]
f.write gem_func_decls
unless gem_final_calls.empty?
- f.puts %Q[]
+ f.puts %Q[]
f.puts %Q[static void]
f.puts %Q[mrb_final_mrbgems(mrb_state *mrb) {]
f.write gem_final_calls
@@ -51,11 +53,21 @@ MRuby.each_target do
end
end
+ file active_gems_txt => :generate_active_gems_txt
+ task :generate_active_gems_txt do |t|
+ def t.timestamp; Time.at(0) end
+ active_gems = gems.sort_by(&:name).inject(""){|s, g| s << "#{g.name}\n"}
+ if !File.exist?(active_gems_txt) || File.read(active_gems_txt) != active_gems
+ mkdir_p File.dirname(active_gems_txt)
+ File.write(active_gems_txt, active_gems)
+ end
+ end
+
# legal documents
file "#{build_dir}/LEGAL" => [MRUBY_CONFIG, __FILE__] do |t|
- FileUtils.mkdir_p File.dirname t.name
+ mkdir_p File.dirname t.name
open(t.name, 'w+') do |f|
- f.puts <<LEGAL
+ f.puts <<LEGAL
Copyright (c) #{Time.now.year} mruby developers
Permission is hereby granted, free of charge, to any person obtaining a
@@ -82,7 +94,7 @@ LEGAL
Additional Licenses
-Due to the reason that you choosed additional mruby packages (GEMS),
+Due to the reason that you chose additional mruby packages (GEMS),
please check the following additional licenses too:
GEMS_LEGAL
diff --git a/tasks/mrblib.rake b/tasks/mrblib.rake
new file mode 100644
index 000000000..485375e55
--- /dev/null
+++ b/tasks/mrblib.rake
@@ -0,0 +1,40 @@
+MRuby.each_target do
+ next unless libmruby_enabled?
+
+ src = "#{build_dir}/mrblib/mrblib.c"
+ rbfiles = Dir["#{MRUBY_ROOT}/mrblib/*.rb"].sort!
+
+ self.libmruby_objs << objfile(src.ext)
+
+ file src => [mrbcfile, __FILE__, *rbfiles] do |t|
+ if presym_enabled?
+ cdump = true
+ suffix = "proc"
+ else
+ cdump = false
+ suffix = "irep"
+ end
+ mkdir_p File.dirname(t.name)
+ File.open(t.name, 'w') do |f|
+ _pp "GEN", "mrblib/*.rb", "#{t.name.relative_path}"
+ f.puts %Q[/*]
+ f.puts %Q[ * This file is loading the mrblib]
+ f.puts %Q[ *]
+ f.puts %Q[ * IMPORTANT:]
+ f.puts %Q[ * This file was generated!]
+ f.puts %Q[ * All manual changes will get lost.]
+ f.puts %Q[ */]
+ unless presym_enabled?
+ f.puts %Q[#include <mruby.h>]
+ f.puts %Q[#include <mruby/irep.h>]
+ end
+ mrbc.run f, rbfiles, "mrblib_#{suffix}", cdump: cdump, static: true
+ f.puts %Q[void]
+ f.puts %Q[mrb_init_mrblib(mrb_state *mrb)]
+ f.puts %Q[{]
+ f.puts %Q[ mrblib_#{suffix}_init_syms(mrb);] if cdump
+ f.puts %Q[ mrb_load_#{suffix}(mrb, mrblib_#{suffix});]
+ f.puts %Q[}]
+ end
+ end
+end
diff --git a/tasks/presym.rake b/tasks/presym.rake
new file mode 100644
index 000000000..1ebc1a737
--- /dev/null
+++ b/tasks/presym.rake
@@ -0,0 +1,48 @@
+all_prerequisites = ->(task_name, prereqs) do
+ Rake::Task[task_name].prerequisites.each do |prereq_name|
+ next if prereqs[prereq_name]
+ prereqs[prereq_name] = true
+ all_prerequisites.(Rake::Task[prereq_name].name, prereqs)
+ end
+end
+
+MRuby.each_target do |build|
+ gensym_task = task(:gensym)
+ next unless build.presym_enabled?
+
+ presym = build.presym
+
+ include_dir = "#{build.build_dir}/include"
+ build.compilers.each{|c| c.include_paths << include_dir}
+ build.gems.each{|gem| gem.compilers.each{|c| c.include_paths << include_dir}}
+
+ prereqs = {}
+ ppps = []
+ build_dir = "#{build.build_dir}/"
+ mrbc_build_dir = "#{build.mrbc_build.build_dir}/" if build.mrbc_build
+ build.products.each{|product| all_prerequisites.(product, prereqs)}
+ prereqs.each_key do |prereq|
+ next unless File.extname(prereq) == build.exts.object
+ next unless prereq.start_with?(build_dir)
+ next if mrbc_build_dir && prereq.start_with?(mrbc_build_dir)
+ ppp = prereq.ext(build.exts.presym_preprocessed)
+ if Rake.application.lookup(ppp) ||
+ Rake.application.enhance_with_matching_rule(ppp)
+ ppps << ppp
+ end
+ end
+
+ file presym.list_path => ppps do
+ presyms = presym.scan(ppps)
+ current_presyms = presym.read_list if File.exist?(presym.list_path)
+ update = presyms != current_presyms
+ presym.write_list(presyms) if update
+ mkdir_p presym.header_dir
+ %w[id table].each do |type|
+ next if !update && File.exist?(presym.send("#{type}_header_path"))
+ presym.send("write_#{type}_header", presyms)
+ end
+ end
+
+ gensym_task.enhance([presym.list_path])
+end
diff --git a/tasks/test.rake b/tasks/test.rake
new file mode 100644
index 000000000..32a03fce6
--- /dev/null
+++ b/tasks/test.rake
@@ -0,0 +1,69 @@
+desc "build and run all mruby tests"
+task :test => "test:build" do
+ Rake::Task["test:run"].invoke
+end
+
+namespace :test do |test_ns|
+ desc "build and run library tests"
+ task :lib => "build:lib" do
+ test_ns["run:lib"].invoke
+ end
+
+ desc "build and run command binaries tests"
+ task :bin => "rake:all" do
+ test_ns["run:bin"].invoke
+ end
+
+ desc "build all mruby tests"
+ task :build => "build:lib"
+
+ namespace :build do |test_build_ns|
+ desc "build library tests"
+ task :lib => "rake:all" do
+ MRuby.each_target{|build| build.gem(core: 'mruby-test')}
+ test = test_build_ns["lib_without_loading_gem"]
+ test.invoke if test
+ end
+ end
+
+ desc "run all mruby tests"
+ task :run
+
+ namespace :run do
+ desc "run library tests"
+ task :lib
+
+ desc "run command binaries tests"
+ task :bin
+ end
+end
+
+MRuby.each_target do |build|
+ if build.test_enabled?
+ t = task "test:build:lib_without_loading_gem:#{build.name}" do
+ gem = build.gems["mruby-test"]
+ gem.setup
+ gem.setup_compilers
+ Rake::Task[build.define_installer_if_needed("mrbtest")].invoke
+ end
+ task "test:build:lib_without_loading_gem" => t
+
+ t = task "test:run:lib:#{build.name}" do
+ build.run_test
+ end
+ task "test:run" => t
+ task "test:run:lib" => t
+ end
+ if build.bintest_enabled?
+ t = task "test:run:bin:#{build.name}" do
+ build.run_bintest
+ end
+ task "test:run" => t
+ task "test:run:bin" => t
+ end
+end
+
+task :clean do
+ host = MRuby.targets["host"]
+ rm_f host.exefile("#{host.class.install_dir}/mrbtest") if host && host.test_enabled?
+end
diff --git a/tasks/toolchains/android.rake b/tasks/toolchains/android.rake
index c7df9ef80..48526bc43 100644
--- a/tasks/toolchains/android.rake
+++ b/tasks/toolchains/android.rake
@@ -10,6 +10,7 @@ class MRuby::Toolchain::Android
~/Android/Sdk/ndk-bundle
%LOCALAPPDATA%/Android/android-sdk/ndk-bundle
%LOCALAPPDATA%/Android/android-ndk
+ %LOCALAPPDATA%/Android/Sdk/ndk/*
~/Library/Android/sdk/ndk-bundle
~/Library/Android/ndk
}
@@ -40,6 +41,19 @@ Set ANDROID_PLATFORM environment variable or set :platform parameter
end
end
+ class SysrootNotReady < StandardError
+ def message
+ <<-EOM
+Couldn't find standard header files
+Please Move/Copy important file inside
+ <NDK_HOME>/sysroot/usr/include/
+to
+ <NDK_HOME>/platforms/<ANDROID_VERSION>/<ARCH>/usr/include/
+Higher NDK version will be use.
+ EOM
+ end
+ end
+
attr_reader :params
def initialize(params)
@@ -67,13 +81,32 @@ Set ANDROID_PLATFORM environment variable or set :platform parameter
end
def home_path
- @home_path ||= Pathname(
+ @home_path ||= Pathname.new(
params[:ndk_home] ||
ENV['ANDROID_NDK_HOME'] ||
DEFAULT_NDK_HOMES.find { |path|
path.gsub! '%LOCALAPPDATA%', ENV['LOCALAPPDATA'] || '%LOCALAPPDATA%'
path.gsub! '\\', '/'
path.gsub! '~', Dir.home || '~'
+ path.gsub!('*') do
+ next nil unless path[-1] == "*"
+ dirs = Dir.glob(path).collect do |d|
+ m = d.match(/(\d+)\.(\d+)\.(\d+)$/)
+ m ? [m[1], m[2], m[3]].collect { |v| v.to_i } : nil
+ end
+ dirs.compact!
+ dirs.sort! do |before, after|
+ f = 0
+ if (f = (after.first <=> before.first)) != 0
+ next f
+ elsif (f = (after[1] <=> before[1])) != 0
+ next f
+ else
+ next after.last <=> before.last
+ end
+ end
+ dirs.empty? ? nil.to_s : dirs.first.join(".")
+ end
File.directory?(path)
} || raise(AndroidNDKHomeNotFound)
)
@@ -124,7 +157,7 @@ Set ANDROID_PLATFORM environment variable or set :platform parameter
path = home_path.join('toolchains', 'llvm' , 'prebuilt', 'windows*')
Dir.glob(path.to_s){ |item|
next if File.file?(item)
- path = Pathname(item)
+ path = Pathname.new(item)
break
}
path.basename
@@ -146,7 +179,8 @@ Set ANDROID_PLATFORM environment variable or set :platform parameter
end
def sysroot
- @sysroot ||= home_path.join('platforms', platform,
+ return @sysroot if @sysroot
+ sysroot_path = home_path.join('platforms', platform,
case arch
when /armeabi/ then 'arch-arm'
when /arm64-v8a/ then 'arch-arm64'
@@ -156,6 +190,11 @@ Set ANDROID_PLATFORM environment variable or set :platform parameter
when /mips/ then 'arch-mips'
end
).to_s
+ if Dir.exist?(File.join(sysroot_path, "usr", "include"))
+ return @sysroot = sysroot_path
+ else
+ raise(SysrootNotReady)
+ end
end
def platform
@@ -259,6 +298,12 @@ Set ANDROID_PLATFORM environment variable or set :platform parameter
def cflags
flags = []
+ case RUBY_PLATFORM
+ when /mswin|mingw|win32/
+ # Build for Android don't need window flag
+ flags += %W(-U_WIN32 -U_WIN64)
+ end
+
flags += %W(-MMD -MP -D__android__ -DANDROID --sysroot="#{sysroot}")
flags += ctarget
case toolchain
diff --git a/tasks/toolchains/clang.rake b/tasks/toolchains/clang.rake
index c75fa030c..543cb73db 100644
--- a/tasks/toolchains/clang.rake
+++ b/tasks/toolchains/clang.rake
@@ -1,9 +1,8 @@
MRuby::Toolchain.new(:clang) do |conf, _params|
- toolchain :gcc
+ toolchain :gcc, default_command: 'clang'
[conf.cc, conf.objc, conf.asm].each do |cc|
- cc.command = ENV['CC'] || 'clang'
+ cc.flags << '-Wzero-length-array' unless ENV['CFLAGS']
end
- conf.cxx.command = ENV['CXX'] || 'clang++'
- conf.linker.command = ENV['LD'] || 'clang'
+ conf.cxx.flags << '-Wzero-length-array' unless ENV['CXXFLAGS'] || ENV['CFLAGS']
end
diff --git a/tasks/toolchains/gcc.rake b/tasks/toolchains/gcc.rake
index e0eb36f26..51bda6517 100644
--- a/tasks/toolchains/gcc.rake
+++ b/tasks/toolchains/gcc.rake
@@ -1,34 +1,35 @@
-MRuby::Toolchain.new(:gcc) do |conf, _params|
- [conf.cc, conf.objc, conf.asm].each do |cc|
- cc.command = ENV['CC'] || 'gcc'
- cc.flags = [ENV['CFLAGS'] || %w(-g -std=gnu99 -O3 -Wall -Werror-implicit-function-declaration -Wdeclaration-after-statement -Wwrite-strings)]
- 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}'
- cc.cxx_compile_flag = '-x c++ -std=c++03'
- cc.cxx_exception_flag = '-fexceptions'
- end
+MRuby::Toolchain.new(:gcc) do |conf, params|
+ default_command = params[:default_command] || 'gcc'
+ compiler_flags = %w(-g -O3 -Wall -Wundef)
+ c_mandatory_flags = %w(-std=gnu99)
+ cxx_invalid_flags = %w(-Werror-implicit-function-declaration)
+ compile_opt = '%{flags} -o "%{outfile}" "%{infile}"'
- [conf.cxx].each do |cxx|
- cxx.command = ENV['CXX'] || 'g++'
- cxx.flags = [ENV['CXXFLAGS'] || ENV['CFLAGS'] || %w(-g -O3 -Wall -Werror-implicit-function-declaration)]
- 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}'
- cxx.cxx_compile_flag = '-x c++ -std=c++03'
- cxx.cxx_exception_flag = '-fexceptions'
+ [conf.cc, conf.objc, conf.asm, conf.cxx].each do |compiler|
+ if compiler == conf.cxx
+ compiler.command = ENV['CXX'] || conf.cc.command.sub(/g\Kcc|$/, '++')
+ compiler.flags = [ENV['CXXFLAGS'] || ENV['CFLAGS'] || compiler_flags]
+ else
+ compiler.command = ENV['CC'] || default_command
+ compiler.flags = [c_mandatory_flags, ENV['CFLAGS'] || [compiler_flags, cxx_invalid_flags, %w(-Wwrite-strings)]]
+ end
+ compiler.option_include_path = %q[-I"%s"]
+ compiler.option_define = '-D%s'
+ compiler.compile_options = "-MMD -c #{compile_opt}"
+ compiler.preprocess_options = "-E -P #{compile_opt}"
+ compiler.cxx_compile_flag = '-x c++ -std=gnu++03'
+ compiler.cxx_exception_flag = '-fexceptions'
+ compiler.cxx_invalid_flags = c_mandatory_flags + cxx_invalid_flags
end
conf.linker do |linker|
- linker.command = ENV['LD'] || 'gcc'
+ linker.command = ENV['LD'] || ENV['CXX'] || ENV['CC'] || default_command
linker.flags = [ENV['LDFLAGS'] || %w()]
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}'
+ linker.link_options = '%{flags} -o "%{outfile}" %{objs} %{flags_before_libraries} %{libs} %{flags_after_libraries}'
end
[[conf.cc, 'c'], [conf.cxx, 'c++']].each do |cc, lang|
@@ -36,8 +37,7 @@ MRuby::Toolchain.new(:gcc) do |conf, _params|
def cc.header_search_paths
if @header_search_command != command
result = `echo | #{build.filename command} -x#{@header_search_language} -Wp,-v - -fsyntax-only 2>&1`
- result = `echo | #{command} -x#{@header_search_language} -Wp,-v - -fsyntax-only 2>&1` if $?.exitstatus != 0
- return include_paths if $?.exitstatus != 0
+ return include_paths if $?.exitstatus != 0
@frameworks = []
@header_search_paths = result.lines.map { |v|
diff --git a/tasks/toolchains/openwrt.rake b/tasks/toolchains/openwrt.rake
index 1637f6d91..6ef3f4e4a 100644
--- a/tasks/toolchains/openwrt.rake
+++ b/tasks/toolchains/openwrt.rake
@@ -1,26 +1,20 @@
# 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'
+ [conf.cc, conf.cxx, conf.objc, conf.asm].each do |cc|
+ if cc == conf.cxx
+ cc.command = ENV['TARGET_CXX']
+ cc.flags = ENV['TARGET_CXXFLAGS']
+ else
+ cc.command = ENV['TARGET_CC']
+ cc.flags = ENV['TARGET_CFLAGS']
+ end
+ cc.option_include_path = %q[-I"%s"]
cc.option_define = '-D%s'
- cc.compile_options = '%{flags} -MMD -o %{outfile} -c %{infile}'
+ cc.compile_options = '%{flags} -MMD -o "%{outfile}" -c "%{infile}"'
+ cc.preprocess_options = '%{flags} -o "%{outfile}" -E -P "%{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']
@@ -28,11 +22,11 @@ MRuby::Toolchain.new(:openwrt) do |conf|
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}'
+ 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}'
+ archiver.archive_options = 'rs "%{outfile}" %{objs}'
end
end
diff --git a/tasks/toolchains/visualcpp.rake b/tasks/toolchains/visualcpp.rake
index b008273a2..00e364082 100644
--- a/tasks/toolchains/visualcpp.rake
+++ b/tasks/toolchains/visualcpp.rake
@@ -1,25 +1,21 @@
MRuby::Toolchain.new(:visualcpp) do |conf, _params|
- conf.cc do |cc|
- cc.command = ENV['CC'] || 'cl.exe'
- # C4013: implicit function declaration
- cc.flags = [ENV['CFLAGS'] || %w(/c /nologo /W3 /we4013 /Zi /MD /O2 /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 /nologo /W3 /Zi /MD /O2 /EHs /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'
+ compiler_flags = %w(/nologo /W3 /MD /O2 /D_CRT_SECURE_NO_WARNINGS)
+ [conf.cc, conf.cxx].each do |compiler|
+ if compiler == conf.cc
+ compiler.command = ENV['CC'] || 'cl.exe'
+ # C4013: implicit function declaration
+ compiler.flags = [*(ENV['CFLAGS'] || compiler_flags + %w(/we4013))]
+ else
+ compiler.command = ENV['CXX'] || 'cl.exe'
+ compiler.flags = [*(ENV['CXXFLAGS'] || ENV['CFLAGS'] || compiler_flags + %w(/EHs))]
+ end
+ compiler.defines = %w(MRB_STACK_EXTEND_DOUBLING)
+ compiler.option_include_path = %q[/I"%s"]
+ compiler.option_define = '/D%s'
+ compiler.compile_options = %Q[/Zi /c /Fo"%{outfile}" %{flags} "%{infile}"]
+ compiler.preprocess_options = %Q[/EP %{flags} "%{infile}" > "%{outfile}"]
+ compiler.cxx_compile_flag = '/TP'
+ compiler.cxx_exception_flag = '/EHs'
end
conf.linker do |linker|
@@ -29,22 +25,22 @@ MRuby::Toolchain.new(:visualcpp) do |conf, _params|
linker.library_paths = %w()
linker.option_library = '%s.lib'
linker.option_library_path = '/LIBPATH:%s'
- linker.link_options = "%{flags} /OUT:%{outfile} %{objs} %{flags_before_libraries} %{libs} %{flags_after_libraries}"
+ linker.link_options = %Q[%{flags} /OUT:"%{outfile}" %{objs} %{flags_before_libraries} %{libs} %{flags_after_libraries}]
end
conf.archiver do |archiver|
archiver.command = ENV['AR'] || 'lib.exe'
- archiver.archive_options = '/nologo /OUT:%{outfile} %{objs}'
+ archiver.archive_options = '/nologo /OUT:"%{outfile}" %{objs}'
end
conf.yacc do |yacc|
yacc.command = ENV['YACC'] || 'bison.exe'
- yacc.compile_options = '-o %{outfile} %{infile}'
+ yacc.compile_options = %q[-o "%{outfile}" "%{infile}"]
end
conf.gperf do |gperf|
gperf.command = 'gperf.exe'
- gperf.compile_options = '-L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k"1,3,$" %{infile} > %{outfile}'
+ gperf.compile_options = %q[-L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k"1,3,$" "%{infile}" > "%{outfile}"]
end
conf.exts do |exts|
@@ -54,16 +50,4 @@ MRuby::Toolchain.new(:visualcpp) do |conf, _params|
end
conf.file_separator = '\\'
-
- # Unreliable detection and will result in invalid encoding errors for localized versions of Visual C++
- # 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