Merge pull request #262 from kivy/osx

OS X Target for Bulldozer
This commit is contained in:
Akshay Arora 2015-12-31 02:25:41 +05:30
commit bcefc5395c

268
buildozer/targets/osx.py Normal file
View file

@ -0,0 +1,268 @@
'''
OSX target, based on kivy-sdk-packager
'''
import sys
if sys.platform != 'darwin':
raise NotImplementedError('This will only work on osx')
#Global variables
#Global imports
import traceback
import os
import io
from pipes import quote
from sys import platform, executable
from buildozer import BuildozerException
from buildozer import IS_PY3
from buildozer.target import Target
from os import environ
from os.path import (exists, join, realpath, expanduser,
basename, relpath, abspath, dirname)
from shutil import copyfile
from glob import glob
from subprocess import check_call, check_output
from buildozer.libs.version import parse
class TargetOSX(Target):
def ensure_sdk(self):
self.buildozer.info('Check if kivy-sdk-packager exists')
if exists(
join(self.buildozer.platform_dir, 'kivy-sdk-packager-master')):
self.buildozer.info(
'kivy-sdk-packager found at '\
'{}'.format(self.buildozer.platform_dir))
return
self.buildozer.info('kivy-sdk-packager does not exist, clone it')
platdir = self.buildozer.platform_dir
check_call(
('curl', '-O', '-L',
'https://github.com/kivy/kivy-sdk-packager/archive/master.zip'),
cwd=platdir)
check_call(('unzip', 'master.zip'), cwd=platdir)
check_call(('rm', 'master.zip'), cwd=platdir)
def download_kivy(self, cwd, kivy='Kivy2'):
self.buildozer.info('Downloading kivy...')
if not exists(cwd+'/'+kivy+'.7z'):
check_call(
('curl', '-O', '-L',
'http://kivy.org/downloads/tests/{}.7z'.format(kivy)),
cwd=cwd)
if not exists(cwd+'/Keka.app'):
if exists('/Applications/Keka.app'):
check_call(
('cp', '-a', '/Applications/Keka.app', './Keka.app'),
cwd=cwd)
else:
check_call(('curl', '-o',
'http://www.kekaosx.com/release/Keka-1.0.4-intel.dmg'),
cwd=cwd)
check_call(
('hdiutil', 'attach', 'Keka-1.0.4-intel.dmg'),
cwd=cwd)
check_call(
('cp', '-a','/Volumes/Keka/Keka.app',
'./Keka.app'), cwd=cwd)
check_call(('hdutil', 'detach', '/Volumes/Keka'))
check_call(
('Keka.app/Contents/Resources/keka7z',
'x', '{}.7z'.format(kivy)), cwd=cwd)
check_call(('rm', '-rf', '{}.7z'.format('Kivy2')), cwd=cwd)
check_call(('mv', '{}.app'.format(kivy), 'Kivy.app'),cwd=cwd)
def ensure_kivyapp(self):
self.buildozer.info('check if Kivy.app exists in local dir')
kivy_app_dir = join(
self.buildozer.platform_dir,
'kivy-sdk-packager-master', 'osx')
if exists(join(kivy_app_dir, 'Kivy.app')):
self.buildozer.info('Kivy.app found at ' + kivy_app_dir)
return
# check if Kivy.app exists in /Applications
if not exists('/Applications/Kivy.app'):
self.download_kivy(kivy_app_dir)
return
else:
self.buildozer.info('Kivy.app found at /Applications/Kivy.app')
self.buildozer.info('copying it to platform dir')
check_call(
('cp', '-a', '/Applications/Kivy.app',
join(kivy_app_dir, 'Kivy.app')))
return
def check_requirements(self):
self.ensure_sdk()
self.ensure_kivyapp()
def check_configuration_tokens(self, errors=None):
if errors:
self.buildozer.info('Check target configuration tokens')
self.buildozer.error(
'{0} error(s) found in the buildozer.spec'.format(
len(errors)))
for error in errors:
print(error)
exit(1)
# check
def build_package(self):
self.buildozer.info('Building package')
kivy_app_dir = join(
self.buildozer.platform_dir,
'kivy-sdk-packager-master', 'osx', 'Kivy.app')
bc = self.buildozer.config
bcg = bc.get
bcgl = bc.getlist
package_name = bcg('app', 'package.name')
domain = bcg('app', 'package.domain')
title = bcg('app', 'title')
app_deps = bcgl('app', 'requirements', '')
garden_deps = bcgl('app', 'garden_requirements', '')
icon = bc.getdefault('app', 'icon.filename', '')
version = self.buildozer.get_version()
author = bc.getdefault('app', 'author', '')
#print(title, package_name, domain, version,
# source_dir, app_deps, garden_deps, icon, author)
#return
self.buildozer.info('Create {}.app'.format(package_name))
cwd = join(self.buildozer.platform_dir,'kivy-sdk-packager-master', 'osx')
# remove kivy from app_deps
app_deps = ','.join(
[word for word in app_deps if 'kivy' not in word])
cmd = [
'python', 'package_app.py', self.buildozer.app_dir,
'--appname={}'.format(package_name),
'--bundlename={}'.format(title),
'--bundleid={}'.format(domain),
'--bundleversion={}'.format(version),
#'--deps={}'.format(app_deps),
'--displayname={}'.format(title)
]
if icon:
cmd.append('--icon={}'.format(icon))
if author:
cmd.append('--author={}'.format(author))
check_output(cmd, cwd=cwd)
self.buildozer.info('{}.app created.'.format(package_name))
self.buildozer.info('Creating {}.dmg'.format(package_name))
check_output(
('sh', '-x', 'create-osx-dmg.sh', package_name + '.app'),
cwd=cwd)
self.buildozer.info('{}.dmg created'.format(package_name))
self.buildozer.info('moving {}.dmg to bin.'.format(package_name))
binpath = join(
self.buildozer.builddir or
dirname(abspath(self.buildozer.specfilename)), 'bin')
check_output(
('cp', '-a', package_name+'.dmg', binpath),
cwd=cwd)
self.buildozer.info('All Done!')
def compile_platform(self):
pass
def install_platform(self):
# ultimate configuration check.
# some of our configuration cannot be check without platform.
self.check_configuration_tokens()
#
self.buildozer.environ.update({
'PACKAGES_PATH': self.buildozer.global_packages_dir,
})
def get_custom_commands(self):
result = []
for x in dir(self):
if not x.startswith('cmd_'):
continue
if x[4:] in self.buildozer.standard_cmds:
continue
result.append((x[4:], getattr(self, x).__doc__))
return result
def get_available_packages(self):
return ['kivy']
def run_commands(self, args):
if not args:
self.buildozer.error('Missing target command')
self.buildozer.usage()
exit(1)
result = []
last_command = []
for arg in args:
if not arg.startswith('--'):
if last_command:
result.append(last_command)
last_command = []
last_command.append(arg)
else:
if not last_command:
self.buildozer.error('Argument passed without a command')
self.buildozer.usage()
exit(1)
last_command.append(arg)
if last_command:
result.append(last_command)
config_check = False
for item in result:
command, args = item[0], item[1:]
if not hasattr(self, 'cmd_{0}'.format(command)):
self.buildozer.error('Unknown command {0}'.format(command))
exit(1)
func = getattr(self, 'cmd_{0}'.format(command))
need_config_check = not hasattr(func, '__no_config')
if need_config_check and not config_check:
config_check = True
self.check_configuration_tokens()
func(args)
def check_build_prepared(self):
self._build_prepared = False
def cmd_clean(self, *args):
self.buildozer.clean_platform()
def cmd_update(self, *args):
self.platform_update = True
self.buildozer.prepare_for_build()
def cmd_debug(self, *args):
self.buildozer.prepare_for_build()
self.build_mode = 'debug'
self.check_build_prepared()
self.buildozer.build()
def cmd_release(self, *args):
self.buildozer.prepare_for_build()
self.build_mode = 'release'
self.buildozer.build()
def cmd_deploy(self, *args):
self.buildozer.prepare_for_build()
def cmd_run(self, *args):
self.buildozer.prepare_for_build()
def cmd_serve(self, *args):
self.buildozer.cmd_serve()
def get_target(buildozer):
return TargetOSX(buildozer)