mirror of
https://github.com/zhigang1992/RubyMotion.git
synced 2026-04-01 22:42:55 +08:00
integrate library
This commit is contained in:
23
Rakefile
Normal file
23
Rakefile
Normal file
@@ -0,0 +1,23 @@
|
||||
PLATFORMS_DIR = '/Developer/Platforms'
|
||||
SDK_VERSION = '4.3'
|
||||
|
||||
def rake(dir, cmd='all')
|
||||
Dir.chdir(dir) do
|
||||
sh "rake platforms_dir=#{PLATFORMS_DIR} sdk_version=#{SDK_VERSION} #{cmd}"
|
||||
end
|
||||
end
|
||||
|
||||
targets = %w{vm data doc}
|
||||
|
||||
task :default => :all
|
||||
task :all => targets
|
||||
|
||||
targets.each do |target|
|
||||
task target do
|
||||
rake(target)
|
||||
end
|
||||
end
|
||||
|
||||
task :clean do
|
||||
targets.each { |target| rake(target, 'clean') }
|
||||
end
|
||||
33
data/Rakefile
Normal file
33
data/Rakefile
Normal file
@@ -0,0 +1,33 @@
|
||||
platforms_dir = ENV['platforms_dir']
|
||||
sdk_version = ENV['sdk_version']
|
||||
|
||||
task :default => :all
|
||||
task :all => [:vm_files, :bridgesupport]
|
||||
|
||||
task :vm_files do
|
||||
install '../vm/miniruby', 'ruby'
|
||||
install '/usr/local/bin/llc', 'llc'
|
||||
mkdir_p 'iPhoneOS'
|
||||
install '../vm/.ios-objs/kernel-armv6.bc', 'iPhoneOS'
|
||||
install '../vm/.ios-objs/kernel-armv7.bc', 'iPhoneOS'
|
||||
install '../vm/.ios-objs/libmacruby-static.a', 'iPhoneOS'
|
||||
mkdir_p 'iPhoneSimulator'
|
||||
install '../vm/.simulator-objs/kernel-i386.bc', 'iPhoneSimulator'
|
||||
install '../vm/.simulator-objs/libmacruby-static.a', 'iPhoneSimulator'
|
||||
end
|
||||
|
||||
task :bridgesupport do
|
||||
frameworks = %w{UIKit Foundation CoreGraphics}
|
||||
platform_dev_path = "#{platforms_dir}/iPhoneSimulator.platform/Developer"
|
||||
sdk_path = "#{platform_dev_path}/SDKs/iPhoneSimulator#{sdk_version}.sdk"
|
||||
sdk_frameworks = "#{sdk_path}/System/Library/Frameworks"
|
||||
mkdir_p 'BridgeSupport'
|
||||
frameworks.each do |framework|
|
||||
dest = "BridgeSupport/#{framework}.bridgesupport"
|
||||
sh "gen_bridge_metadata --format complete --no-64-bit --cflags \"--sysroot=#{sdk_path} -miphoneos-version-min=#{sdk_version}\" --framework #{sdk_frameworks}/#{framework}.framework > #{dest}" unless File.exist?(dest)
|
||||
end
|
||||
end
|
||||
|
||||
task :clean do
|
||||
%w{ruby llc iPhoneOS iPhoneSimulator BridgeSupport}.each { |path| rm_rf(path) }
|
||||
end
|
||||
11
doc/Rakefile
Normal file
11
doc/Rakefile
Normal file
@@ -0,0 +1,11 @@
|
||||
platforms_dir = ENV['platforms_dir']
|
||||
sdk_version = ENV['sdk_version']
|
||||
|
||||
task :default => :all
|
||||
task :all do
|
||||
# TODO
|
||||
end
|
||||
|
||||
task :clean do
|
||||
# TODO
|
||||
end
|
||||
42
lib/rubixir/rake.rb
Normal file
42
lib/rubixir/rake.rb
Normal file
@@ -0,0 +1,42 @@
|
||||
require 'rubixir/rake/config'
|
||||
require 'rubixir/rake/builder'
|
||||
|
||||
module Rubixir
|
||||
CONFIG = Config.new('.')
|
||||
BUILDER = Builder.new
|
||||
end
|
||||
|
||||
desc "Build the project, then run the simulator"
|
||||
task :default => :simulator
|
||||
|
||||
namespace :build do
|
||||
desc "Build the simulator version"
|
||||
task :simulator do
|
||||
Rubixir::BUILDER.compile(Rubixir::CONFIG, 'iPhoneSimulator')
|
||||
end
|
||||
|
||||
desc "Build the iOS version"
|
||||
task :ios do
|
||||
Rubixir::BUILDER.compile(Rubixir::CONFIG, 'iPhoneOS')
|
||||
end
|
||||
|
||||
desc "Build everything"
|
||||
task :all => [:simulator, :ios]
|
||||
end
|
||||
|
||||
desc "Run the simulator"
|
||||
task :simulator => ['build:simulator'] do
|
||||
sim = File.join(Rubixir::CONFIG.platform_dir('iPhoneSimulator'), '/Developer/Applications/iPhone Simulator.app/Contents/MacOS/iPhone Simulator')
|
||||
app = File.join(Rubixir::CONFIG.build_dir, 'iPhoneSimulator/main')
|
||||
sh "\"#{sim}\" -SimulateApplication \"#{app}\""
|
||||
end
|
||||
|
||||
desc "Deploy on the device"
|
||||
task :deploy do
|
||||
# TODO
|
||||
end
|
||||
|
||||
desc "Clear build objects"
|
||||
task :clean do
|
||||
rm_rf(Rubixir::CONFIG.build_dir)
|
||||
end
|
||||
133
lib/rubixir/rake/builder.rb
Normal file
133
lib/rubixir/rake/builder.rb
Normal file
@@ -0,0 +1,133 @@
|
||||
module Rubixir
|
||||
class Builder
|
||||
def compile(config, platform)
|
||||
datadir = File.join(File.dirname(__FILE__), '../../../data')
|
||||
libstatic = File.join(datadir, 'libmacruby-static.a')
|
||||
archs = Dir.glob(File.join(datadir, platform, '*.bc')).map do |path|
|
||||
path.scan(/kernel-(.+).bc$/)[0][0]
|
||||
end
|
||||
ruby = File.join(datadir, 'ruby')
|
||||
llc = File.join(datadir, 'llc')
|
||||
|
||||
# Locate SDK.
|
||||
sdk = config.sdk(platform)
|
||||
|
||||
# Locate compilers.
|
||||
cc = File.join(config.platform_dir(platform), 'Developer/usr/bin/gcc')
|
||||
cxx = File.join(config.platform_dir(platform), 'Developer/usr/bin/g++')
|
||||
|
||||
build_dir = File.join(config.build_dir, platform)
|
||||
|
||||
bs_flags = ''
|
||||
config.frameworks.each do |framework|
|
||||
bs_path = File.join(datadir, 'BridgeSupport', framework + '.bridgesupport')
|
||||
if File.exist?(bs_path)
|
||||
bs_flags << "--uses-bs \"" + bs_path + "\" "
|
||||
end
|
||||
end
|
||||
|
||||
objs = []
|
||||
config.files.each do |path|
|
||||
# Generate init function.
|
||||
init_func = "MREP_#{`uuidgen`.strip.gsub('-', '')}"
|
||||
|
||||
arch_objs = []
|
||||
archs.each do |arch|
|
||||
# Locate arch kernel.
|
||||
kernel = File.join(datadir, platform, "kernel-#{arch}.bc")
|
||||
raise "Can't locate kernel file" unless File.exist?(kernel)
|
||||
|
||||
# Prepare build_dir.
|
||||
bc = File.join(build_dir, "#{path}.#{arch}.bc")
|
||||
FileUtils.mkdir_p(File.dirname(bc))
|
||||
|
||||
# LLVM bitcode.
|
||||
sh "/usr/bin/env VM_KERNEL_PATH=\"#{kernel}\" #{ruby} #{bs_flags} --emit-llvm \"#{bc}\" #{init_func} \"#{path}\""
|
||||
|
||||
# Assembly.
|
||||
asm = File.join(build_dir, "#{path}.#{arch}.s")
|
||||
llc_arch = case arch
|
||||
when 'i386'; 'x86'
|
||||
when 'x86_64'; 'x86-64'
|
||||
when /^arm/; 'arm'
|
||||
else; arch
|
||||
end
|
||||
sh "#{llc} \"#{bc}\" -o=\"#{asm}\" -march=#{llc_arch} -relocation-model=pic -disable-fp-elim -jit-enable-eh"
|
||||
|
||||
# Object.
|
||||
obj = File.join(build_dir, "#{path}.#{arch}.o")
|
||||
sh "#{cc} -fexceptions -c -arch #{arch} \"#{asm}\" -o \"#{obj}\""
|
||||
|
||||
arch_objs << obj
|
||||
end
|
||||
|
||||
# Assemble fat binary.
|
||||
arch_objs_list = arch_objs.map { |x| "\"#{x}\"" }.join(' ')
|
||||
obj = File.join(build_dir, "#{path}.o")
|
||||
sh "lipo -create #{arch_objs_list} -output \"#{obj}\""
|
||||
|
||||
objs << [obj, init_func]
|
||||
end
|
||||
|
||||
# Generate main file.
|
||||
main_txt = <<EOS
|
||||
#import <UIKit/UIKit.h>
|
||||
extern "C" {
|
||||
void ruby_sysinit(int *, char ***);
|
||||
void ruby_init(void);
|
||||
void ruby_init_loadpath(void);
|
||||
void ruby_script(const char *);
|
||||
void ruby_set_argv(int, char **);
|
||||
void rb_vm_init_compiler(void);
|
||||
void rb_vm_init_jit(void);
|
||||
void rb_vm_aot_feature_provide(const char *, void *);
|
||||
void *rb_vm_top_self(void);
|
||||
void rb_vm_print_current_exception(void);
|
||||
void rb_exit(int);
|
||||
EOS
|
||||
objs.each do |_, init_func|
|
||||
main_txt << "void #{init_func}(void *, void *);\n"
|
||||
end
|
||||
main_txt << <<EOS
|
||||
}
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
const char *progname = argv[0];
|
||||
ruby_init();
|
||||
ruby_init_loadpath();
|
||||
ruby_script(progname);
|
||||
try {
|
||||
void *self = rb_vm_top_self();
|
||||
EOS
|
||||
objs.each do |_, init_func|
|
||||
main_txt << "#{init_func}(self, 0);\n"
|
||||
end
|
||||
main_txt << <<EOS
|
||||
}
|
||||
catch (...) {
|
||||
rb_vm_print_current_exception();
|
||||
rb_exit(1);
|
||||
}
|
||||
int retval = UIApplicationMain(argc, argv, nil, @"AppDelegate");
|
||||
[pool release];
|
||||
rb_exit(retval);
|
||||
}
|
||||
EOS
|
||||
|
||||
# Compile main file.
|
||||
main = File.join(build_dir, 'main.mm')
|
||||
File.open(main, 'w') { |io| io.write(main_txt) }
|
||||
main_o = File.join(build_dir, 'main.o')
|
||||
arch_flags = archs.map { |x| "-arch #{x}" }.join(' ')
|
||||
sh "#{cxx} \"#{main}\" #{arch_flags} -fexceptions -fblocks -isysroot \"#{sdk}\" -miphoneos-version-min=4.3 -fobjc-legacy-dispatch -fobjc-abi-version=2 -c -o \"#{main_o}\""
|
||||
|
||||
# Link executable.
|
||||
objs_list = objs.map { |path, _| path }.unshift(main_o).map { |x| "\"#{x}\"" }.join(' ')
|
||||
main_exec = File.join(build_dir, "main")
|
||||
frameworks = config.frameworks.map { |x| "-framework #{x}" }.join(' ')
|
||||
sh "#{cxx} -o #{main_exec} #{objs_list} #{arch_flags} -isysroot \"#{sdk}\" -L#{File.join(datadir, platform)} -lmacruby-static -lobjc -licucore #{frameworks}"
|
||||
end
|
||||
end
|
||||
end
|
||||
25
lib/rubixir/rake/config.rb
Normal file
25
lib/rubixir/rake/config.rb
Normal file
@@ -0,0 +1,25 @@
|
||||
module Rubixir
|
||||
class Config
|
||||
attr_accessor :files, :platforms_dir, :sdk_version, :frameworks,
|
||||
:app_delegate_class, :app_name, :build_dir
|
||||
|
||||
def initialize(project_dir)
|
||||
@files = Dir.glob(File.join(project_dir, 'app/**/*.rb'))
|
||||
@platforms_dir = '/Developer/Platforms'
|
||||
@sdk_version = '4.3'
|
||||
@frameworks = ['UIKit', 'Foundation', 'CoreGraphics']
|
||||
@app_delegate_class = 'AppDelegate'
|
||||
@app_name = 'My App'
|
||||
@build_dir = File.join(project_dir, 'build')
|
||||
end
|
||||
|
||||
def platform_dir(platform)
|
||||
File.join(@platforms_dir, platform + '.platform')
|
||||
end
|
||||
|
||||
def sdk(platform)
|
||||
File.join(platform_dir(platform), 'Developer/SDKs',
|
||||
platform + @sdk_version + '.sdk')
|
||||
end
|
||||
end
|
||||
end
|
||||
4
sample/hello/Rakefile
Normal file
4
sample/hello/Rakefile
Normal file
@@ -0,0 +1,4 @@
|
||||
$:.unshift('../../lib')
|
||||
require 'rubixir/rake'
|
||||
|
||||
Rubixir::CONFIG.app_name = 'Hello'
|
||||
40
sample/hello/app/main.rb
Normal file
40
sample/hello/app/main.rb
Normal file
@@ -0,0 +1,40 @@
|
||||
class MyView < UIView
|
||||
def drawRect(rect)
|
||||
if @moved
|
||||
red, green, blue = rand(100), rand(100), rand(100)
|
||||
bgcolor = UIColor.colorWithRed(red/100.0, green:green/100.0, blue:blue/100.0, alpha:1.0)
|
||||
text = "ZOMG!"
|
||||
else
|
||||
bgcolor = UIColor.blackColor
|
||||
text = @touches ? "Touched #{@touches} times!" : "Hello Ruby!"
|
||||
end
|
||||
|
||||
bgcolor.set
|
||||
UIBezierPath.bezierPathWithRect(frame).fill
|
||||
|
||||
font = UIFont.systemFontOfSize(24)
|
||||
UIColor.whiteColor.set
|
||||
text.drawAtPoint(CGPoint.new(10, 20), withFont:font)
|
||||
end
|
||||
|
||||
def touchesMoved(touches, withEvent:event)
|
||||
@moved = true
|
||||
setNeedsDisplay
|
||||
end
|
||||
|
||||
def touchesEnded(touches, withEvent:event)
|
||||
@moved = false
|
||||
@touches ||= 0
|
||||
@touches += 1
|
||||
setNeedsDisplay
|
||||
end
|
||||
end
|
||||
|
||||
class AppDelegate
|
||||
def application(application, didFinishLaunchingWithOptions:launchOptions)
|
||||
window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
|
||||
view = MyView.alloc.initWithFrame(window.frame)
|
||||
window.addSubview(view)
|
||||
window.makeKeyAndVisible
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user