mirror of
https://github.com/zhigang1992/RubyMotion.git
synced 2026-03-29 22:43:28 +08:00
520 lines
22 KiB
Ruby
520 lines
22 KiB
Ruby
XCODE_PLATFORMS_DIR = ENV['xcode_platforms_dir']
|
|
IOS_SDK_VERSIONS = ENV['ios_sdk_versions'].split(',')
|
|
OSX_SDK_VERSIONS = ENV['osx_sdk_versions'].split(',')
|
|
|
|
ANDROID_SDK = ENV['android_sdk']
|
|
ANDROID_API_VERSIONS = ENV['android_api_versions'].split(',')
|
|
ANDROID_ARCHS = ENV['android_archs'].split(',')
|
|
|
|
verbose(true)
|
|
NEED_STRIP = !ENV['DEBUG']
|
|
|
|
task :default => :all
|
|
task :all => [:vm_files, :bridgesupport_files, :bridgesupport_static_stubs]
|
|
|
|
task :vm_files do
|
|
strip = File.join(XCODE_PLATFORMS_DIR, '../Toolchains/XcodeDefault.xctoolchain/usr/bin/strip')
|
|
|
|
first = true
|
|
OSX_SDK_VERSIONS.each do |sdk_version|
|
|
sdk = File.join('osx', sdk_version, 'MacOSX')
|
|
mkdir_p sdk
|
|
objs = "../vm/MacOSX#{sdk_version}.objs"
|
|
Dir.glob(File.join(objs, 'kernel-*.bc')).each do |path|
|
|
install path, sdk
|
|
end
|
|
install File.join(objs, 'librubymotion-static.a'), sdk
|
|
|
|
if first
|
|
objs = "../vm/MacOSX#{sdk_version}-repl.objs"
|
|
install File.join(objs, 'librubymotion-repl.dylib'), 'osx'
|
|
first = false
|
|
end
|
|
end
|
|
|
|
IOS_SDK_VERSIONS.each do |sdk_version|
|
|
ios = File.join('ios', sdk_version, 'iPhoneOS')
|
|
mkdir_p ios
|
|
objs = "../vm/iPhoneOS#{sdk_version}.objs"
|
|
Dir.glob(File.join(objs, 'kernel-*.bc')).each do |path|
|
|
install path, ios
|
|
end
|
|
install File.join(objs, 'librubymotion-static.a'), ios
|
|
|
|
sim = File.join('ios', sdk_version, 'iPhoneSimulator')
|
|
mkdir_p sim
|
|
objs = "../vm/iPhoneSimulator#{sdk_version}.objs"
|
|
Dir.glob(File.join(objs, 'kernel-*.bc')).each do |path|
|
|
install path, sim
|
|
end
|
|
install File.join(objs, 'librubymotion-static.a'), sim
|
|
end
|
|
|
|
if IOS_SDK_VERSIONS.size > 1
|
|
# Create a fat librubymotion-repl.dylib library for iOS simulator. The i386 slice has a deployment_target for 4.3 and the x86_64 slice has a deployment_target for 7.1.
|
|
first_ios_repl = "../vm/iPhoneSimulator#{IOS_SDK_VERSIONS.first}-repl.objs/librubymotion-repl.dylib"
|
|
|
|
# FIXME : Need to use latest SDK version instead of '7.1'
|
|
raise "does not target 7.1?" unless IOS_SDK_VERSIONS.include?('7.1')
|
|
last_ios_repl = "../vm/iPhoneSimulator7.1-repl.objs/librubymotion-repl.dylib"
|
|
|
|
sh "/usr/bin/lipo -extract_family x86_64 \"#{last_ios_repl}\" -output /tmp/librubymotion-repl64.dylib"
|
|
sh "/usr/bin/lipo -create \"#{first_ios_repl}\" /tmp/librubymotion-repl64.dylib -output ios/librubymotion-repl.dylib"
|
|
end
|
|
|
|
# XXX we are no longer stripping symbols since it apparently removes exception handlers
|
|
# (iOS 7 only). Not a big deal since we do not compile with debug metadata by default (-g).
|
|
# remove debug symbols
|
|
#if NEED_STRIP
|
|
# Dir.glob('{osx,ios}/**/*.{a,dylib}').each { |x| sh("\"#{strip}\" -S \"#{x}\"") }
|
|
#end
|
|
end
|
|
|
|
def apply_bridgesupport_fixes(bs)
|
|
rules = []
|
|
case File.basename(bs, '.bridgesupport')
|
|
when 'CoreMIDI', 'AudioToolbox', 'AudioUnit'
|
|
rules << [/<cftype /, '<opaque ']
|
|
else
|
|
rules << [/<opaque /, '<cftype ']
|
|
end
|
|
txt = File.read(bs)
|
|
rules.each { |a| txt.gsub!(a[0], a[1]) }
|
|
File.open(bs, 'w') { |io| io.write(txt) }
|
|
end
|
|
|
|
def merge_bridgesupport(base_bridgesupport, merge_brigesupport)
|
|
return unless base_bridgesupport && merge_brigesupport
|
|
base = File.read(base_bridgesupport)
|
|
merge = File.read(merge_brigesupport)
|
|
File.open(base_bridgesupport, "w") { |io|
|
|
lines = base.lines.to_a
|
|
io.print lines[0..-2].join # skip last "</signatures>" in base
|
|
if lines.last.strip != "</signatures>"
|
|
io.puts "<signatures version='1.0'>"
|
|
end
|
|
io.print merge.lines.to_a[2..-1].join # skip first "<?xml version='1.0'?>\n<signatures version='1.0'>" in merge
|
|
}
|
|
end
|
|
|
|
def apply_CoreText_fix(framework_path)
|
|
header_path = File.join(framework_path, 'Headers', 'CTRunDelegate.h')
|
|
content = File.read(header_path)
|
|
signature = 'CFTypeID CTRunDelegateGetTypeID'
|
|
message = "// Disabled by the RubyMotion build system: #{signature}"
|
|
unless content.include?(message)
|
|
content.sub!(/^#{signature}/, message)
|
|
File.open(header_path, 'w') { |f| f << content }
|
|
end
|
|
end
|
|
|
|
EXCLUDED_FRAMEWORKS = ['Kernel', 'System', 'IOKit', 'Ruby', 'RubyCocoa', 'vecLib']
|
|
task :bridgesupport_files do
|
|
platform_dev_path = "#{XCODE_PLATFORMS_DIR}/MacOSX.platform/Developer"
|
|
OSX_SDK_VERSIONS.each do |sdk_version|
|
|
sdk_path = "#{platform_dev_path}/SDKs/MacOSX#{sdk_version}.sdk"
|
|
sdk_frameworks = "#{sdk_path}/System/Library/Frameworks"
|
|
mkdir_p "osx/#{sdk_version}/BridgeSupport"
|
|
mkdir_p "osx/#{sdk_version}/BridgeSupport/child"
|
|
|
|
Dir.glob('*.bridgesupport').each { |bs| cp bs, "osx/#{sdk_version}/BridgeSupport" }
|
|
Dir.glob('osx/*.bridgesupport').each { |bs| cp bs, "osx/#{sdk_version}/BridgeSupport" }
|
|
|
|
generate_bridgesupport_file = lambda do |sdk_path, sdk_version, framework_path, is_handle_nested|
|
|
framework = File.basename(framework_path, '.framework')
|
|
break if EXCLUDED_FRAMEWORKS.include?(framework)
|
|
break unless File.exist?(File.join(framework_path, framework))
|
|
break unless File.exist?(File.join(framework_path, 'Headers'))
|
|
dest = "osx/#{sdk_version}/BridgeSupport/#{framework}.bridgesupport"
|
|
dest = "osx/#{sdk_version}/BridgeSupport/child/#{framework}.bridgesupport" if is_handle_nested
|
|
|
|
linked_framework =
|
|
case framework
|
|
when 'HIToolbox', 'Ink' then 'Carbon'
|
|
when 'CFNetwork', 'LaunchServices', 'Metadata', 'OSServices', 'SearchKit' then 'CoreServices'
|
|
when 'ColorSync', 'CoreText', 'HIServices', 'ImageIO' then 'ApplicationServices'
|
|
else framework
|
|
end
|
|
|
|
unless File.exist?(dest)
|
|
a = sdk_version.scan(/(\d+)\.(\d+)/)[0]
|
|
sdk_version_headers = ((a[0].to_i * 100) + (a[1].to_i * 10)).to_s
|
|
sh "../bin/gen_bridge_metadata --format complete --cflags \"-isysroot #{sdk_path} -mmacosx-version-min=#{sdk_version} -DTARGET_OS_MAC -D__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__=#{sdk_version_headers} -F#{File.dirname(framework_path)} -framework #{linked_framework}\" --framework #{framework_path} > #{dest}"
|
|
apply_bridgesupport_fixes(dest)
|
|
return dest
|
|
end
|
|
return dest if is_handle_nested
|
|
end
|
|
|
|
Dir.glob(File.join(sdk_frameworks, '*.framework')).each do |framework_path|
|
|
base_bridgesupport_path = generate_bridgesupport_file.call(sdk_path, sdk_version, framework_path, false)
|
|
if base_bridgesupport_path
|
|
child_framework_paths = Dir.glob(File.join(framework_path, '/Frameworks/*.framework'))
|
|
child_framework_paths.delete_if { |x| x.include?("CoreGraphics") } if sdk_version != "10.7"
|
|
child_framework_paths.each do |child_framework_path|
|
|
if sdk_version == "10.7" && child_framework_path.include?("CoreGraphics")
|
|
dest = 'osx/10.7/BridgeSupport/child/CoreGraphics.bridgesupport'
|
|
sh "../bin/gen_bridge_metadata --format complete --cflags \"-isysroot #{sdk_path} -F#{sdk_path}/System/Library/Frameworks/ApplicationServices.framework/Frameworks -mmacosx-version-min=10.7 -DTARGET_OS_MAC -D__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__=100700 -framework ApplicationServices\" --framework #{child_framework_path} > #{dest}"
|
|
apply_bridgesupport_fixes(dest)
|
|
merge_path = dest
|
|
else
|
|
merge_path = generate_bridgesupport_file.call(sdk_path, sdk_version, child_framework_path, true)
|
|
end
|
|
merge_bridgesupport(base_bridgesupport_path, merge_path)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
platform_dev_path = "#{XCODE_PLATFORMS_DIR}/iPhoneSimulator.platform/Developer"
|
|
IOS_SDK_VERSIONS.each do |sdk_version|
|
|
sdk_path = "#{platform_dev_path}/SDKs/iPhoneSimulator#{sdk_version}.sdk"
|
|
sdk_frameworks = "#{sdk_path}/System/Library/Frameworks"
|
|
mkdir_p "ios/#{sdk_version}/BridgeSupport"
|
|
mkdir_p "ios/#{sdk_version}/BridgeSupport/child"
|
|
|
|
Dir.glob('*.bridgesupport').each { |bs| cp bs, "ios/#{sdk_version}/BridgeSupport" }
|
|
Dir.glob('ios/*.bridgesupport').each { |bs| cp bs, "ios/#{sdk_version}/BridgeSupport" }
|
|
|
|
generate_bridgesupport_file = lambda do |sdk_path, sdk_version, framework_path, is_handle_nested|
|
|
framework = File.basename(framework_path, '.framework')
|
|
break if EXCLUDED_FRAMEWORKS.include?(framework)
|
|
break unless File.exist?(File.join(framework_path, framework))
|
|
break unless File.exist?(File.join(framework_path, 'Headers'))
|
|
dest = "ios/#{sdk_version}/BridgeSupport/#{framework}.bridgesupport"
|
|
dest = "ios/#{sdk_version}/BridgeSupport/child/#{framework}.bridgesupport" if is_handle_nested
|
|
unless File.exist?(dest)
|
|
apply_CoreText_fix(framework_path) if framework == 'CoreText'
|
|
|
|
a = sdk_version.scan(/(\d+)\.(\d+)/)[0]
|
|
sdk_version_headers = ((a[0].to_i * 10000) + (a[1].to_i * 100)).to_s
|
|
extra_flags = (sdk_version >= '7.0') ? '--64-bit' : '--no-64-bit'
|
|
sh "../bin/gen_bridge_metadata --format complete #{extra_flags} --cflags \"-isysroot #{sdk_path} -miphoneos-version-min=#{sdk_version} -DTARGET_OS_IPHONE -D__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__=#{sdk_version_headers} -framework #{framework}\" --framework #{framework_path} > #{dest}"
|
|
apply_bridgesupport_fixes(dest)
|
|
|
|
if framework == 'Foundation' and sdk_version >= '7.0'
|
|
# In iOS 7.0, NSObject is defined in /usr/include/objc/NSObject.h
|
|
sh "../bin/gen_bridge_metadata --format complete #{extra_flags} --cflags \"-isysroot #{sdk_path} -miphoneos-version-min=#{sdk_version} -DTARGET_OS_IPHONE -D__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__=#{sdk_version_headers} -framework #{framework} -I#{sdk_path}/usr/include \" objc/NSObject.h objc/NSObjCRuntime.h > /tmp/NSObject.bridgesupport"
|
|
merge_bridgesupport dest, '/tmp/NSObject.bridgesupport'
|
|
end
|
|
|
|
if framework == 'AudioToolbox'
|
|
# Generate AudioUnit.bridgesupport and merge it into AudioToolbox.bridgesupport
|
|
framework_path = File.join(framework_path, '../AudioUnit.framework')
|
|
framework = File.basename(framework_path, '.framework')
|
|
headers_path = File.join(framework_path, 'Headers')
|
|
sh "../bin/gen_bridge_metadata --format complete #{extra_flags} --cflags \"-isysroot #{sdk_path} -miphoneos-version-min=#{sdk_version} -DTARGET_OS_IPHONE -D__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__=#{sdk_version_headers} -framework #{framework} -I#{headers_path}\" #{headers_path}/*.h > /tmp/AudioUnit.bridgesupport"
|
|
apply_bridgesupport_fixes('/tmp/AudioUnit.bridgesupport')
|
|
merge_bridgesupport dest, '/tmp/AudioUnit.bridgesupport'
|
|
end
|
|
|
|
return dest
|
|
end
|
|
return dest if is_handle_nested
|
|
end
|
|
|
|
Dir.glob(File.join(sdk_frameworks, '*.framework')).each do |framework_path|
|
|
base_bridgesupport_path = generate_bridgesupport_file.call(sdk_path, sdk_version, framework_path, false)
|
|
if base_bridgesupport_path
|
|
child_framework_paths = Dir.glob(File.join(framework_path, '/Frameworks/*.framework'))
|
|
child_framework_paths.each do |child_framework_path|
|
|
merge_path = generate_bridgesupport_file.call(sdk_path, sdk_version, child_framework_path, true)
|
|
merge_bridgesupport(base_bridgesupport_path, merge_path)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
Rake::Task['UIAutomation:generate_bridgesupport_files'].invoke
|
|
end
|
|
|
|
def generate_bs_static_stub(file, includes)
|
|
require 'rubygems'
|
|
require 'nokogiri'
|
|
text = ''
|
|
includes.each { |inc| text << "#import <#{inc}>\n" }
|
|
|
|
gen_func_code = Proc.new do |node, declared_type_attribute|
|
|
name = node['name'].to_s
|
|
retval = node.xpath('./retval')[0][declared_type_attribute].to_s
|
|
args = node.xpath('./arg').map { |node| node[declared_type_attribute].to_s }
|
|
if retval.strip.empty?
|
|
nil
|
|
else
|
|
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"
|
|
func
|
|
end
|
|
end
|
|
|
|
doc = Nokogiri::XML(File.read(file))
|
|
did_something = false
|
|
doc.xpath("/signatures/function[@inline=\"true\"]").each do |node|
|
|
code64 = gen_func_code.call(node, 'declared_type64')
|
|
code32 = gen_func_code.call(node, 'declared_type')
|
|
|
|
if code64
|
|
text << "\n#if defined(__LP64__)\n"
|
|
text << code64
|
|
text << "\n#endif\n"
|
|
end
|
|
|
|
if code32
|
|
text << "\n#if !defined(__LP64__)\n" if code64
|
|
text << code32
|
|
text << "\n#endif\n" if code64
|
|
end
|
|
|
|
did_something = true
|
|
end
|
|
|
|
did_something ? text : nil
|
|
end
|
|
|
|
task :bridgesupport_static_stubs do
|
|
OSX_SDK_VERSIONS.each do |sdk_version|
|
|
Dir.glob("osx/#{sdk_version}/BridgeSupport/*.bridgesupport") do |bs_path|
|
|
framework = File.basename(bs_path).sub(/\.bridgesupport/, '')
|
|
|
|
case framework
|
|
when 'GLKit' # TODO
|
|
next
|
|
end
|
|
|
|
code = "osx/#{sdk_version}/BridgeSupport/#{framework}_stubs.m"
|
|
includes = case framework
|
|
when 'OpenGLES'
|
|
['OpenGLES/EAGLDrawable.h']
|
|
else
|
|
['Cocoa/Cocoa.h', "#{framework}/#{framework}.h"]
|
|
end
|
|
unless File.exist?(code)
|
|
text = generate_bs_static_stub(bs_path, includes)
|
|
next unless text
|
|
File.open(code, 'w') { |io|
|
|
io.puts '#pragma GCC diagnostic ignored "-Wdeprecated-declarations"'
|
|
io.write(text)
|
|
}
|
|
end
|
|
|
|
obj = "osx/#{sdk_version}/MacOSX/#{framework}_stubs.o"
|
|
next if File.exist?(obj)
|
|
platform_dev = "#{XCODE_PLATFORMS_DIR}/MacOSX.platform/Developer"
|
|
cflags = "-isysroot #{platform_dev}/SDKs/MacOSX#{sdk_version}.sdk"
|
|
cflags << " -arch i386 -arch x86_64"
|
|
cflags << " -mmacosx-version-min=#{sdk_version} -Wall -Werror -O3 -fobjc-abi-version=2 -fobjc-legacy-dispatch"
|
|
sh "/usr/bin/clang #{cflags} #{code} -c -o #{obj}"
|
|
end
|
|
end
|
|
|
|
IOS_SDK_VERSIONS.each do |sdk_version|
|
|
Dir.glob("ios/#{sdk_version}/BridgeSupport/*.bridgesupport") do |bs_path|
|
|
framework = File.basename(bs_path).sub(/\.bridgesupport/, '')
|
|
|
|
code = "ios/#{sdk_version}/BridgeSupport/#{framework}_stubs.m"
|
|
includes = case framework
|
|
when 'OpenGLES'
|
|
['OpenGLES/EAGLDrawable.h']
|
|
else
|
|
['UIKit/UIKit.h', "#{framework}/#{framework}.h"]
|
|
end
|
|
unless File.exist?(code)
|
|
text = generate_bs_static_stub(bs_path, includes)
|
|
next unless text
|
|
File.open(code, 'w') { |io| io.write(text) }
|
|
end
|
|
|
|
device_archs =
|
|
if sdk_version < '5.0'
|
|
['armv6', 'armv7']
|
|
elsif sdk_version >= '7.0'
|
|
['armv7', 'armv7s', 'arm64']
|
|
elsif sdk_version >= '6.0'
|
|
['armv7', 'armv7s']
|
|
else
|
|
['armv7']
|
|
end
|
|
|
|
sim_archs =
|
|
if sdk_version >= '7.0'
|
|
['i386', 'x86_64']
|
|
else
|
|
['i386']
|
|
end
|
|
|
|
[['iPhoneOS', *device_archs], ['iPhoneSimulator', *sim_archs]].each do |platform, *archs|
|
|
obj = "ios/#{sdk_version}/#{platform}/#{framework}_stubs.o"
|
|
next if File.exist?(obj)
|
|
platform_dev = "#{XCODE_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 "#{XCODE_PLATFORMS_DIR}/../Toolchains/XcodeDefault.xctoolchain/usr/bin/clang #{cflags} #{code} -c -o #{obj}"
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
namespace :UIAutomation do
|
|
desc 'Dump the headers of the private iOS UIAutomation frameworks'
|
|
task :dump_headers do
|
|
if `which class-dump`.empty?
|
|
$stderr.puts "[!] This requires the `class-dump` tool. Install it with: $ brew install class-dump."
|
|
exit 1
|
|
end
|
|
|
|
IOS_SDK_VERSIONS.each do |sdk_version|
|
|
framework_path = "#{XCODE_PLATFORMS_DIR}/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator#{sdk_version}.sdk/Developer/Library/PrivateFrameworks/UIAutomation.framework"
|
|
destination = File.join('UIAutomation', sdk_version)
|
|
next if File.exist?(destination)
|
|
# Use the 386 slice here because it's easier to differentiate between
|
|
# CGFloat and NSTimeInterval. Otherwise a `double` arg is too ambigous.
|
|
sh "class-dump --arch i386 -H -o #{destination} '#{framework_path}'"
|
|
Dir.glob("UIAutomation/#{sdk_version}/*.h").each do |header|
|
|
content = File.read(header)
|
|
if File.basename(header) == 'CDStructures.h'
|
|
# Remove definitions of structs such as `CGRect`.
|
|
content.sub!(/#pragma mark Named Structures.+?#pragma/m, '#pragma')
|
|
else
|
|
# Use definitions such as `CGRect` from canonical headers.
|
|
content = "#import <CoreGraphics/CGGeometry.h>\n" << content
|
|
# Replace `struct CGRect` with just `CGRect`.
|
|
content.gsub!(/struct (CGAffineTransform|CGPoint|CGSize|CGRect)/) { $1 }
|
|
|
|
content.gsub!(/(duration):\(double\)/i) { "#{$1}:(NSTimeInterval)" }
|
|
|
|
content.gsub!(/\(((float|int|unsigned int)(\s*\*)?)\)/) do
|
|
type = case $2
|
|
when 'float'
|
|
'CGFloat'
|
|
when 'int'
|
|
'NSInteger'
|
|
when 'unsigned int'
|
|
'NSUInteger'
|
|
end
|
|
"(#{type}#{$3})"
|
|
end
|
|
end
|
|
File.open(header, 'w') { |f| f << content }
|
|
end
|
|
end
|
|
end
|
|
|
|
desc 'Generate BridgeSupport from dumped headers'
|
|
task :generate_bridgesupport_files => :dump_headers do
|
|
IOS_SDK_VERSIONS.each do |sdk_version|
|
|
destination = "ios/#{sdk_version}/BridgeSupport/UIAutomation.bridgesupport"
|
|
next if File.exist?(destination)
|
|
platform_dev_path = "#{XCODE_PLATFORMS_DIR}/iPhoneSimulator.platform/Developer"
|
|
sdk_path = "#{platform_dev_path}/SDKs/iPhoneSimulator#{sdk_version}.sdk"
|
|
a = sdk_version.scan(/(\d+)\.(\d+)/)[0]
|
|
sdk_version_headers = ((a[0].to_i * 10000) + (a[1].to_i * 100)).to_s
|
|
extra_flags = (sdk_version >= '7.0') ? '--64-bit' : '--no-64-bit'
|
|
Dir.chdir "UIAutomation/#{sdk_version}" do
|
|
sh "/usr/bin/gen_bridge_metadata --format complete #{extra_flags} --cflags \"-isysroot #{sdk_path} -miphoneos-version-min=#{sdk_version} -DTARGET_OS_IPHONE -D__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__=#{sdk_version_headers} -I.\" *.h > ../../#{destination}"
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
task :clean do
|
|
IOS_SDK_VERSIONS.each { |path| rm_rf('ios/' + path) }
|
|
OSX_SDK_VERSIONS.each { |path| rm_rf('osx/' + path) }
|
|
ANDROID_API_VERSIONS.each { |path| rm_rf('android/' + path) }
|
|
Dir.glob(["ios/*.dylib", "osx/*.dylib"]) { |path| rm_rf(path) }
|
|
rm_rf 'UIAutomation'
|
|
end
|
|
|
|
# TODO - merge to main task
|
|
ANDROID_API_PACKAGES = %w{java android}
|
|
task :android do
|
|
ANDROID_API_VERSIONS.each do |api_vers|
|
|
# Copy runtime library and kernel file
|
|
ANDROID_ARCHS.each do |arch|
|
|
dest_lib_path = "android/#{api_vers}/#{arch}"
|
|
mkdir_p dest_lib_path
|
|
vm_objs_dir = "../vm/android-#{api_vers}-#{arch}.objs"
|
|
cp "#{vm_objs_dir}/librubymotion-static.a", dest_lib_path
|
|
cp "#{vm_objs_dir}/kernel-#{arch}.bc", dest_lib_path
|
|
end
|
|
|
|
# Copy runtime jar.
|
|
cp "../vm/android-#{api_vers}-classes/rubymotion.jar", "android/#{api_vers}"
|
|
|
|
# Generate .bridgesupport files
|
|
jar_path = File.join(ANDROID_SDK, 'platforms', "android-#{api_vers}", 'android.jar')
|
|
tmp_path = File.join("/tmp/rm_android_#{api_vers}")
|
|
tmp_path_clear = !File.exist?(tmp_path)
|
|
mkdir_p tmp_path if tmp_path_clear
|
|
data_dir = Dir.pwd
|
|
Dir.chdir(tmp_path) do
|
|
sh "/usr/bin/unzip \"#{jar_path}\"" if tmp_path_clear
|
|
ANDROID_API_PACKAGES.each do |package|
|
|
bs_path = "#{data_dir}/android/#{api_vers}/BridgeSupport/#{package}.bridgesupport"
|
|
next if File.exist?(bs_path)
|
|
mkdir_p File.dirname(bs_path)
|
|
classes = Dir.glob("#{package}/**/*.class").map { |x| x.gsub('/', '.').gsub('$', '.').sub(/\.class$/, '') }
|
|
javap_tmp_path = "/tmp/rm_android_#{api_vers}_#{package}.txt"
|
|
sh "/usr/bin/javap -s #{classes.join(' ')} > \"#{javap_tmp_path}\""
|
|
bs_data = ''
|
|
bs_data << <<EOS
|
|
<?xml version='1.0'?>
|
|
<signatures version='1.0'>
|
|
EOS
|
|
txt = File.read(javap_tmp_path)
|
|
res = txt.scan(/(class)\s+([^\s]+)\s+extends\s+[^{]+\s*\{([^}]+)\}/)
|
|
res += txt.scan(/(class)\s([^\s{]+)\s*\{([^}]+)\}/) # Also grab classes without superclasses (ex. java.lang.Object)
|
|
res += txt.scan(/(interface)\s([^\s{]+)\s*\{([^}]+)\}/) # Also grab interfaces
|
|
res.each do |type, elem, body_txt|
|
|
elem_path = elem.gsub(/\./, '/')
|
|
bs_data << <<EOS
|
|
<#{type} name=\"#{elem_path}\">
|
|
EOS
|
|
body_txt.strip.split(/\n/).each_cons(2) do |elem_line, signature_line|
|
|
signature_line = signature_line.strip
|
|
md = signature_line.match(/^Signature:\s+(.+)$/)
|
|
next unless md
|
|
signature = md[1]
|
|
|
|
elem_line = elem_line.strip
|
|
if md = elem_line.match(/\s([^(\s]+)\(/)
|
|
# A method.
|
|
method = md[1]
|
|
if method == elem
|
|
# An initializer.
|
|
method = '<init>'
|
|
end
|
|
class_method = elem_line.include?('static')
|
|
bs_data << <<EOS
|
|
<method name=\"#{method}\" type=\"#{signature}\"#{class_method ? ' class_method="true"' : ''}/>
|
|
EOS
|
|
elsif md = elem_line.match(/\s([^;\s]+);$/)
|
|
# A constant.
|
|
constant = md[1]
|
|
bs_data << <<EOS
|
|
<const name=\"#{constant}\" type=\"#{signature}\"/>
|
|
EOS
|
|
end
|
|
end
|
|
bs_data << <<EOS
|
|
</#{type}>
|
|
EOS
|
|
end
|
|
bs_data << <<EOS
|
|
</signatures>
|
|
EOS
|
|
File.open(bs_path, 'w') { |io| io.write(bs_data) }
|
|
end
|
|
end
|
|
end
|
|
end
|