add seperation between "global" and "local" stuff, and allow to use custom ndk/sdk/ant directory

This commit is contained in:
Mathieu Virbel 2012-12-20 00:40:41 +01:00
parent 2e250079dc
commit c25c2dc9e9
4 changed files with 145 additions and 110 deletions

View file

@ -93,51 +93,6 @@ buildozer.spec
See buildozer/default.spec for an up-to-date spec file.
::
[app]
# (str) Title of your application
title = My Application
# (str) Package name
package.name = myapp
# (str) Package domain (needed for android/ios packaging)
package.domain = org.test
# (str) Source code where the main.py live
source.dir = .
# (list) Source files to include (let empty to include all the files)
source.include_exts = py,png,jpg
# (list) Source files to exclude (let empty to not excluding anything)
#source.exclude_exts = spec
# (str) Application versionning (method 1)
version.regex = __version__ = '(.*)'
version.filename = %(source.dir)s/main.py
# (str) Application versionning (method 2)
# version = 1.2.0
# (list) Application requirements
requirements = twisted,kivy
#
# Android specific
#
# (list) Permissions
#android.permissions = INTERNET
# (int) Minimum SDK allowed for installation
#android.minsdk = 8
# (int) Android SDK to use
#android.sdk = 16
# (str) Android entry point, default is ok for Kivy-based app
#android.entrypoint = org.renpy.android.PythonActivity
.. include:: buildozer/default.spec
:code: ini

View file

@ -17,9 +17,9 @@ from sys import stdout, exit
from urllib import urlretrieve
from re import search
from ConfigParser import SafeConfigParser
from os.path import join, exists, dirname, realpath, splitext
from os.path import join, exists, dirname, realpath, splitext, expanduser
from subprocess import Popen, PIPE
from os import environ, mkdir, unlink, rename, walk, sep, listdir
from os import environ, unlink, rename, walk, sep, listdir, makedirs
from copy import copy
from shutil import copyfile, rmtree
@ -103,20 +103,25 @@ class Buildozer(object):
self.specfilename)
exit(1)
# create global dir
self.mkdir(self.global_buildozer_dir)
# create local dir
specdir = dirname(self.specfilename)
self.mkdir(join(specdir, '.buildozer'))
self.mkdir(join(specdir, 'bin'))
self.state = shelve.open(join(self.buildozer_dir, 'state.db'))
if self.targetname:
self.mkdir(join(specdir, '.buildozer', self.targetname))
self.mkdir(join(specdir, '.buildozer', self.targetname, 'platform'))
self.mkdir(join(specdir, '.buildozer', self.targetname, 'app'))
target = self.targetname
self.mkdir(join(self.global_platform_dir, target, 'platform'))
self.mkdir(join(specdir, '.buildozer', target, 'platform'))
self.mkdir(join(specdir, '.buildozer', target, 'app'))
def mkdir(self, dn):
if exists(dn):
return
mkdir(dn)
makedirs(dn)
def file_exists(self, *args):
return exists(join(*args))
@ -125,6 +130,7 @@ class Buildozer(object):
if cwd:
source = join(cwd, source)
target = join(cwd, target)
self.log('Rename {0} to {1}'.format(source, target))
rename(source, target)
def file_extract(self, archive, cwd=None):
@ -245,28 +251,34 @@ class Buildozer(object):
self.log('Copy {0}'.format(sfn))
copyfile(sfn, rfn)
@property
def platform_dir(self):
return realpath(
join(dirname(self.specfilename), '.buildozer',
self.targetname, 'platform'))
@property
def app_dir(self):
return realpath(join(
dirname(self.specfilename), '.buildozer',
self.targetname, 'app'))
@property
def buildozer_dir(self):
return realpath(join(
dirname(self.specfilename), '.buildozer'))
@property
def platform_dir(self):
return join(self.buildozer_dir, self.targetname, 'platform')
@property
def app_dir(self):
return join(self.buildozer_dir, self.targetname, 'app')
@property
def bin_dir(self):
return realpath(join(
dirname(self.specfilename), 'bin'))
@property
def global_buildozer_dir(self):
return join(expanduser('~'), '.buildozer')
@property
def global_platform_dir(self):
return join(self.global_buildozer_dir, self.targetname, 'platform')
#
# command line invocation
#
@ -419,5 +431,7 @@ class Buildozer(object):
self.ensure_build_layout()
self.state['buildozer:defaultcommand'] = args
def run():
Buildozer().run_command(sys.argv[1:])

View file

@ -35,11 +35,23 @@ requirements = twisted,kivy
# (list) Permissions
#android.permissions = INTERNET
# (int) Minimum SDK allowed for installation
#android.minsdk = 8
# (int) Android API to use
#android.api = 14
# (int) Android SDK to use
#android.sdk = 16
# (int) Minimum API required (8 = Android 2.2 devices)
#android.minapi = 8
# (int) Android SDK version to use
#android.sdk = 21
# (str) Android NDK version to use
#android.ndk = 8c
# (str) Android NDK directory (if empty, it will be automatically downloaded.)
#android.ndk_path =
# (str) Android SDK directory (if empty, it will be automatically downloaded.)
#android.sdk_path =
# (str) Android entry point, default is ok for Kivy-based app
#android.entrypoint = org.renpy.android.PythonActivity

View file

@ -9,6 +9,7 @@ Android target, based on python-for-android project
ANDROID_API = '14'
ANDROID_MINAPI = '8'
ANDROID_SDK_VERSION = '21'
ANDROID_NDK_VERSION = '8c'
APACHE_ANT_VERSION = '1.8.4'
@ -24,27 +25,80 @@ from shutil import copyfile
class TargetAndroid(Target):
@property
def android_sdk_version(self):
return self.buildozer.config.getdefault(
'app', 'android.sdk', ANDROID_SDK_VERSION)
@property
def android_ndk_version(self):
return self.buildozer.config.getdefault(
'app', 'android.ndk', ANDROID_NDK_VERSION)
@property
def android_api(self):
return self.buildozer.config.getdefault(
'app', 'android.api', ANDROID_API)
@property
def android_minapi(self):
return self.buildozer.config.getdefault(
'app', 'android.minapi', ANDROID_MINAPI)
@property
def android_sdk_dir(self):
directory = self.buildozer.config.getdefault(
'app', 'android.sdk_path', '')
if directory:
return realpath(directory)
version = self.buildozer.config.getdefault(
'app', 'android.sdk', self.android_sdk_version)
return join(self.buildozer.global_platform_dir,
'android-sdk-{0}'.format(version))
@property
def android_ndk_dir(self):
directory = self.buildozer.config.getdefault(
'app', 'android.ndk_path', '')
if directory:
return realpath(directory)
version = self.buildozer.config.getdefault(
'app', 'android.ndk', self.android_ndk_version)
return join(self.buildozer.global_platform_dir,
'android-sdk-{0}'.format(version))
@property
def apache_ant_dir(self):
directory = self.buildozer.config.getdefault(
'app', 'android.ant_path', '')
if directory:
return realpath(directory)
version = self.buildozer.config.getdefault(
'app', 'android.ant', APACHE_ANT_VERSION)
return join(self.buildozer.global_platform_dir,
'apache-ant-{0}'.format(version))
def check_requirements(self):
if platform in ('win32', 'cygwin'):
try:
self._set_win32_java_home()
except:
traceback.print_exc()
self.android_cmd = join('android-sdk', 'tools', 'android.bat')
self.ant_cmd = join('apache-ant', 'bin', 'ant.bat')
self.adb_cmd = join('android-sdk', 'platform-tools', 'adb.exe')
self.android_cmd = join(self.android_sdk_dir, 'tools', 'android.bat')
self.ant_cmd = join(self.apache_ant_dir, 'bin', 'ant.bat')
self.adb_cmd = join(self.android_sdk_dir, 'platform-tools', 'adb.exe')
self.javac_cmd = self._locate_java('javac.exe')
self.keytool_cmd = self._locate_java('keytool.exe')
elif platform in ('darwin', ):
self.android_cmd = join('android-sdk', 'tools', 'android')
self.ant_cmd = join('apache-ant', 'bin', 'ant')
self.adb_cmd = join('android-sdk', 'platform-tools', 'adb')
self.android_cmd = join(self.android_sdk_dir, 'tools', 'android')
self.ant_cmd = join(self.apache_ant_dir, 'bin', 'ant')
self.adb_cmd = join(self.android_sdk_dir, 'platform-tools', 'adb')
self.javac_cmd = self._locate_java('javac')
self.keytool_cmd = self._locate_java('keytool')
else:
self.android_cmd = join('android-sdk', 'tools', 'android')
self.ant_cmd = join('apache-ant', 'bin', 'ant')
self.adb_cmd = join('android-sdk', 'platform-tools', 'adb')
self.android_cmd = join(self.android_sdk_dir, 'tools', 'android')
self.ant_cmd = join(self.apache_ant_dir, 'bin', 'ant')
self.adb_cmd = join(self.android_sdk_dir, 'platform-tools', 'adb')
self.javac_cmd = self._locate_java('javac')
self.keytool_cmd = self._locate_java('keytool')
@ -74,26 +128,23 @@ class TargetAndroid(Target):
return s
def _install_apache_ant(self):
ant_dir = join(self.buildozer.platform_dir, 'apache-ant')
ant_dir = self.apache_ant_dir
if self.buildozer.file_exists(ant_dir):
self.buildozer.log('Apache ANT found at {0}'.format(ant_dir))
return ant_dir
self.buildozer.log('Android ANT is missing, downloading')
archive = 'apache-ant-{0}-bin.tar.gz'.format(APACHE_ANT_VERSION)
unpacked = 'apache-ant-{0}'.format(APACHE_ANT_VERSION)
url = 'http://archive.apache.org/dist/ant/binaries/'
self.buildozer.download(url, archive,
cwd=self.buildozer.platform_dir)
self.buildozer.file_extract(archive, cwd=self.buildozer.platform_dir)
self.buildozer.file_rename(unpacked, 'apache-ant',
cwd=self.buildozer.platform_dir)
cwd=self.buildozer.global_platform_dir)
self.buildozer.file_extract(archive,
cwd=self.buildozer.global_platform_dir)
self.buildozer.log('Apache ANT installation done.')
return ant_dir
def _install_android_sdk(self):
sdk_dir = join(self.buildozer.platform_dir, 'android-sdk')
sdk_dir = self.android_sdk_dir
if self.buildozer.file_exists(sdk_dir):
self.buildozer.log('Android SDK found at {0}'.format(sdk_dir))
return sdk_dir
@ -111,20 +162,21 @@ class TargetAndroid(Target):
else:
raise SystemError('Unsupported platform: {0}'.format(platform))
archive = archive.format(ANDROID_SDK_VERSION)
archive = archive.format(self.android_sdk_version)
url = 'http://dl.google.com/android/'
self.buildozer.download(url, archive,
cwd=self.buildozer.platform_dir)
cwd=self.buildozer.global_platform_dir)
self.buildozer.log('Unpacking Android SDK')
self.buildozer.file_extract(archive, cwd=self.buildozer.platform_dir)
self.buildozer.file_rename(unpacked, 'android-sdk',
cwd=self.buildozer.platform_dir)
self.buildozer.file_extract(archive,
cwd=self.buildozer.global_platform_dir)
self.buildozer.file_rename(unpacked, sdk_dir,
cwd=self.buildozer.global_platform_dir)
self.buildozer.log('Android SDK installation done.')
return sdk_dir
def _install_android_ndk(self):
ndk_dir = join(self.buildozer.platform_dir, 'android-ndk')
ndk_dir = self.android_ndk_dir
if self.buildozer.file_exists(ndk_dir):
self.buildozer.log('Android NDK found at {0}'.format(ndk_dir))
return ndk_dir
@ -140,33 +192,34 @@ class TargetAndroid(Target):
raise SystemError('Unsupported platform: {0}'.format(platform))
unpacked = 'android-ndk-r{0}'
archive = archive.format(ANDROID_NDK_VERSION)
unpacked = unpacked.format(ANDROID_NDK_VERSION)
archive = archive.format(self.android_ndk_version)
unpacked = unpacked.format(self.android_ndk_version)
url = 'http://dl.google.com/android/ndk/'
self.buildozer.download(url, archive,
cwd=self.buildozer.platform_dir)
cwd=self.buildozer.global_platform_dir)
self.buildozer.log('Unpacking Android NDK')
self.buildozer.file_extract(archive, cwd=self.buildozer.platform_dir)
self.buildozer.file_rename(unpacked, 'android-ndk',
cwd=self.buildozer.platform_dir)
self.buildozer.file_extract(archive,
cwd=self.buildozer.global_platform_dir)
self.buildozer.file_rename(unpacked, ndk_dir,
cwd=self.buildozer.global_platform_dir)
self.buildozer.log('Android NDK installation done.')
return ndk_dir
def _install_android_packages(self):
packages = []
android_platform = join(self.sdk_dir, 'platforms',
'android-{0}'.format(ANDROID_API))
android_platform = join(self.android_sdk_dir, 'platforms',
'android-{0}'.format(self.android_api))
if not self.buildozer.file_exists(android_platform):
packages.append('android-{0}'.format(ANDROID_API))
if not self.buildozer.file_exists(self.sdk_dir, 'platform-tools'):
packages.append('android-{0}'.format(self.android_api))
if not self.buildozer.file_exists(self.android_sdk_dir, 'platform-tools'):
packages.append('platform-tools')
if not packages:
self.buildozer.log('Android packages already installed.')
return
self.buildozer.cmd('{0} update sdk -u -a -t {1}'.format(
self.android_cmd, ','.join(packages)),
cwd=self.buildozer.platform_dir)
cwd=self.buildozer.global_platform_dir)
self.buildozer.log('Android packages installation done.')
def install_platform(self):
@ -180,14 +233,15 @@ class TargetAndroid(Target):
cmd('git pull origin master', cwd=pa_dir)
self._install_apache_ant()
self.sdk_dir = sdk_dir = self._install_android_sdk()
self.ndk_dir = ndk_dir = self._install_android_ndk()
self._install_android_sdk()
self._install_android_ndk()
self._install_android_packages()
self.buildozer.environ.update({
'ANDROIDSDK': realpath(sdk_dir),
'ANDROIDNDK': realpath(ndk_dir),
'ANDROIDSDK': self.android_sdk_dir,
'ANDROIDNDK': self.android_ndk_dir,
'ANDROIDAPI': ANDROID_API,
'ANDROIDNDKVER': ANDROID_NDK_VERSION})
'ANDROIDNDKVER': self.android_ndk_version})
def compile_platform(self):
# for android, the compilation depends really on the app requirements.
@ -317,7 +371,7 @@ class TargetAndroid(Target):
# push on the device
self.buildozer.cmd('{0} install -r {1}'.format(
self.adb_cmd, full_apk), cwd=self.buildozer.platform_dir)
self.adb_cmd, full_apk), cwd=self.buildozer.global_platform_dir)
self.buildozer.log('Application pushed on the device.')
@ -331,7 +385,7 @@ class TargetAndroid(Target):
self.buildozer.cmd(
'{adb} shell am start -n {package}/{entry} -a {entry}'.format(
adb=self.adb_cmd, package=package, entry=entrypoint),
cwd=self.buildozer.platform_dir)
cwd=self.buildozer.global_platform_dir)
self.buildozer.log('Application started on the device.')