PLATFORMS_DIR = ENV['platforms_dir'] SDK_VERSION = ENV['sdk_version'] verbose(true) task :default => :all task :all => [:vm_files, :bridgesupport_files, :bridgesupport_static_stubs, :deploy, :sim] 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_files do frameworks = %w{UIKit Foundation CoreGraphics CoreLocation MapKit AddressBook} 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" unless File.exist?(dest) sh "gen_bridge_metadata --format complete --no-64-bit --cflags \"--sysroot=#{sdk_path} -miphoneos-version-min=#{SDK_VERSION} -D__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__=#{SDK_VERSION}\" --framework #{sdk_frameworks}/#{framework}.framework > #{dest}" end end end def generate_bs_static_stub(file, includes) require 'rubygems' require 'nokogiri' text = '' includes.each { |inc| text << "#import <#{inc}>\n" } doc = Nokogiri::XML(File.read(file)) doc.xpath("/signatures/function[@inline=\"true\"]").each do |node| name = node['name'].to_s retval = node.xpath('./retval')[0]['declared_type'].to_s args = node.xpath('./arg').map { |node| node['declared_type'].to_s } proto = "#{retval} __concrete__#{name}(" proto << (0...args.size).to_a.map { |i| "#{args[i]} arg#{i}" }.join(', ') proto << ")" func = '' func << proto func << "\n{\n " func << " return " if retval != 'void' func << name << '(' func << (0...args.size).to_a.map { |i| "arg#{i}" }.join(', ') func << ");\n}\n\n" text << func end text end task :bridgesupport_static_stubs do Dir.glob('BridgeSupport/*.bridgesupport') do |bs_path| framework = File.basename(bs_path).sub(/\.bridgesupport/, '') code = "BridgeSupport/#{framework}_stubs.m" includes = ['UIKit/UIKit.h', "#{framework}/#{framework}.h"] File.open(code, 'w') { |io| io.write(generate_bs_static_stub(bs_path, includes)) } unless File.exist?(code) [%w{iPhoneOS armv6 armv7}, %w{iPhoneSimulator i386}].each do |platform, *archs| obj = "#{platform}/#{framework}_stubs.o" next if File.exist?(obj) platform_dev = "#{PLATFORMS_DIR}/#{platform}.platform/Developer" cflags = "-isysroot #{platform_dev}/SDKs/#{platform}#{SDK_VERSION}.sdk " cflags << archs.map { |a| "-arch #{a}" }.join(' ') cflags << " -miphoneos-version-min=#{SDK_VERSION} -Wall -Werror -O3 -fobjc-abi-version=2 -fobjc-legacy-dispatch" sh "#{platform_dev}/usr/bin/gcc #{cflags} #{code} -c -o #{obj}" end end end task :deploy do sh "/usr/bin/gcc -I./src -std=c99 -Wall -O3 src/deploy.m -o deploy -framework Foundation" sh "/usr/bin/strip -x deploy" end task :sim do sh "/usr/bin/gcc -I./src -std=c99 -Wall -O3 src/sim.m -o sim -framework Foundation" sh "/usr/bin/strip -x sim" end task :clean do %w{ruby llc iPhoneOS iPhoneSimulator BridgeSupport deploy sim}.each { |path| rm_rf(path) } end