Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SDL2/Gradle bootstrap with fixes #1071

Merged
merged 27 commits into from
Sep 30, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
e3df8a8
sdl2/gradle: first version (not yet compiled) of a sdl2 build based o…
tito May 6, 2017
fba89ce
more fixes to get gradle build working
tito May 6, 2017
6c3bafe
fixes android recipe for sdl2_gradle
tito May 6, 2017
7a7cba9
fixes aars
tito May 6, 2017
155e60d
fix private version (the issue remain in sdl2 bootstrap)
tito May 17, 2017
ca5e037
add release signing config for gradle build
tito May 24, 2017
57f7436
gradle dont show the name of the apk in its output. So in release mod…
tito May 24, 2017
6b85a8d
gradle: ensure the signing config are used only if --sign is passed.
tito May 24, 2017
600c837
Moved libs dir in bootstrap back to 'libs' instead of 'src/main/...'
inclement Jul 2, 2017
3110fdc
Deleted NDK build from build.tmpl.gradle
inclement Jul 2, 2017
7c841fb
Removed abifilters from build.tmpl.gradle
inclement Jul 2, 2017
59a5916
Changed Android.mk back to old version
inclement Jul 2, 2017
41f5cf0
Fixed site-packages copy during crystax install
inclement Jul 2, 2017
7d84513
Updated TODO in sdl2_gradle __init__.py (all done now)
inclement Jul 2, 2017
343c27f
Deleted unused apk function
inclement Jul 2, 2017
902f2ba
Removed unnecessary method (was already commented out)
inclement Jul 15, 2017
c1db1a6
Added appropriate ant build files to sdl2_gradle bootstrap
inclement Jul 16, 2017
fbfc134
Added --java-build-tool option for ant vs gradle
inclement Jul 16, 2017
eb16a59
Fixed typo == -> = when setting build_type
inclement Jul 16, 2017
370c346
Made gradle use correct build tools and target sdk versions
inclement Jul 16, 2017
70bd0d0
Fixed syntax error from missing '' in build.tmpl.gradle
inclement Jul 16, 2017
dda2332
Added build-tools version check for ant/gradle selection
inclement Jul 16, 2017
453079d
Changed AndroidManifest.tmpl.xml to use the correct target SDK
inclement Jul 16, 2017
6b2793c
Added ant.properties to sdl2_gradle git
inclement Jul 23, 2017
dc3cc3c
Added all sdl2_gradle bootstrap changes to sdl2 bootstrap
inclement Jul 23, 2017
971ed44
Removed sdl2_gradle bootstrap (now unnecessary)
inclement Jul 23, 2017
924d57d
Updated SDK installation docs
inclement Sep 30, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions doc/source/quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,31 @@ Installing Android SDK

You need to download and unpack the Android SDK and NDK to a directory (let's say $HOME/Documents/):

- `Android SDK <https://developer.android.com/sdk/index.html#Other>`_
- `Android SDK <https://developer.android.com/studio/index.html>`_
- `Android NDK <https://developer.android.com/ndk/downloads/index.html>`_

For the Android SDK, you can download 'just the command line
tools'. When you have extracted these you'll see only a directory
named ``tools``, and you will need to run extra commands to install
the SDK packages needed.

First, install a platform to target (you can also replace ``19`` with
a different platform number, this will be used again later)::

$SDK_DIR/tools/bin/sdkmanager "platforms;android-19"

Second, install the build-tools. You can use
``$SDK_DIR/tools/bin/sdkmanager --list`` to see all the
possibilities, but 26.0.2 is the latest version at the time of writing::

$SDK_DIR/tools/bin/sdkmanager "build-tools;26.0.2"

Then, you can edit your ``~/.bashrc`` or other favorite shell to include new environment variables necessary for building on android::

# Adjust the paths!
export ANDROIDSDK="$HOME/Documents/android-sdk-21"
export ANDROIDNDK="$HOME/Documents/android-ndk-r10e"
export ANDROIDAPI="14" # Minimum API version your application require
export ANDROIDAPI="19" # Minimum API version your application require
export ANDROIDNDKVER="r10e" # Version of the NDK you installed

You have the possibility to configure on any command the PATH to the SDK, NDK and Android API using:
Expand Down
11 changes: 6 additions & 5 deletions pythonforandroid/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import importlib

from pythonforandroid.logger import (warning, shprint, info, logger,
debug)
debug, error)
from pythonforandroid.util import (current_directory, ensure_dir,
temp_directory, which)
from pythonforandroid.recipe import Recipe
Expand Down Expand Up @@ -195,20 +195,21 @@ def get_bootstrap(cls, name, ctx):
bootstrap.ctx = ctx
return bootstrap

def distribute_libs(self, arch, src_dirs, wildcard='*'):
def distribute_libs(self, arch, src_dirs, wildcard='*', dest_dir="libs"):
'''Copy existing arch libs from build dirs to current dist dir.'''
info('Copying libs')
tgt_dir = join('libs', arch.arch)
tgt_dir = join(dest_dir, arch.arch)
ensure_dir(tgt_dir)
for src_dir in src_dirs:
for lib in glob.glob(join(src_dir, wildcard)):
shprint(sh.cp, '-a', lib, tgt_dir)

def distribute_javaclasses(self, javaclass_dir):
def distribute_javaclasses(self, javaclass_dir, dest_dir="src"):
'''Copy existing javaclasses from build dir to current dist dir.'''
info('Copying java files')
ensure_dir(dest_dir)
for filename in glob.glob(javaclass_dir):
shprint(sh.cp, '-a', filename, 'src')
shprint(sh.cp, '-a', filename, dest_dir)

def distribute_aars(self, arch):
'''Process existing .aar bundles and copy to current dist dir.'''
Expand Down
130 changes: 72 additions & 58 deletions pythonforandroid/bootstraps/sdl2/__init__.py
Original file line number Diff line number Diff line change
@@ -1,67 +1,82 @@
from pythonforandroid.toolchain import Bootstrap, shprint, current_directory, info, warning, ArchARM, info_main
from pythonforandroid.toolchain import (
Bootstrap, shprint, current_directory, info, info_main)
from pythonforandroid.util import ensure_dir
from os.path import join, exists, curdir, abspath
from os import walk
import glob
import sh

class SDL2Bootstrap(Bootstrap):
name = 'sdl2'

EXCLUDE_EXTS = (".py", ".pyc", ".so.o", ".so.a", ".so.libs", ".pyx")


class SDL2GradleBootstrap(Bootstrap):
name = 'sdl2_gradle'

recipe_depends = ['sdl2', ('python2', 'python3crystax')]

def run_distribute(self):
info_main('# Creating Android project from build and {} bootstrap'.format(
self.name))
info_main("# Creating Android project ({})".format(self.name))

arch = self.ctx.archs[0]
python_install_dir = self.ctx.get_python_install_dir()
from_crystax = self.ctx.python_recipe.from_crystax
crystax_python_dir = join("crystax_python", "crystax_python")

if len(self.ctx.archs) > 1:
raise ValueError("SDL2/gradle support only one arch")

info("Copying SDL2/gradle build for {}".format(arch))
shprint(sh.rm, "-rf", self.dist_dir)
shprint(sh.cp, "-r", self.build_dir, self.dist_dir)

info('This currently just copies the SDL2 build stuff straight from the build dir.')
shprint(sh.rm, '-rf', self.dist_dir)
shprint(sh.cp, '-r', self.build_dir, self.dist_dir)
# either the build use environemnt variable (ANDROID_HOME)
# or the local.properties if exists
with current_directory(self.dist_dir):
with open('local.properties', 'w') as fileh:
fileh.write('sdk.dir={}'.format(self.ctx.sdk_dir))

arch = self.ctx.archs[0]
if len(self.ctx.archs) > 1:
raise ValueError('built for more than one arch, but bootstrap cannot handle that yet')
info('Bootstrap running with arch {}'.format(arch))

with current_directory(self.dist_dir):
info('Copying python distribution')
info("Copying Python distribution")

if not exists('private') and not self.ctx.python_recipe.from_crystax:
shprint(sh.mkdir, 'private')
if not exists('crystax_python') and self.ctx.python_recipe.from_crystax:
shprint(sh.mkdir, 'crystax_python')
shprint(sh.mkdir, 'crystax_python/crystax_python')
if not exists('assets'):
shprint(sh.mkdir, 'assets')
if not exists("private") and not from_crystax:
ensure_dir("private")
if not exists("crystax_python") and from_crystax:
ensure_dir(crystax_python_dir)

hostpython = sh.Command(self.ctx.hostpython)
if not self.ctx.python_recipe.from_crystax:
if not from_crystax:
try:
shprint(hostpython, '-OO', '-m', 'compileall',
self.ctx.get_python_install_dir(),
python_install_dir,
_tail=10, _filterout="^Listing")
except sh.ErrorReturnCode:
pass
if not exists('python-install'):
shprint(sh.cp, '-a', self.ctx.get_python_install_dir(), './python-install')
shprint(
sh.cp, '-a', python_install_dir, './python-install')

self.distribute_libs(arch, [self.ctx.get_libs_dir(arch.arch)])
self.distribute_aars(arch)
self.distribute_javaclasses(self.ctx.javaclass_dir)

if not self.ctx.python_recipe.from_crystax:
info('Filling private directory')
if not exists(join('private', 'lib')):
info('private/lib does not exist, making')
shprint(sh.cp, '-a', join('python-install', 'lib'), 'private')
shprint(sh.mkdir, '-p', join('private', 'include', 'python2.7'))
self.distribute_javaclasses(self.ctx.javaclass_dir,
dest_dir=join("src", "main", "java"))

if not from_crystax:
info("Filling private directory")
if not exists(join("private", "lib")):
info("private/lib does not exist, making")
shprint(sh.cp, "-a",
join("python-install", "lib"), "private")
shprint(sh.mkdir, "-p",
join("private", "include", "python2.7"))

# AND: Copylibs stuff should go here
if exists(join('libs', arch.arch, 'libpymodules.so')):
shprint(sh.mv, join('libs', arch.arch, 'libpymodules.so'), 'private/')
shprint(sh.cp, join('python-install', 'include' , 'python2.7', 'pyconfig.h'), join('private', 'include', 'python2.7/'))
libpymodules_fn = join("libs", arch.arch, "libpymodules.so")
if exists(libpymodules_fn):
shprint(sh.mv, libpymodules_fn, 'private/')
shprint(sh.cp,
join('python-install', 'include',
'python2.7', 'pyconfig.h'),
join('private', 'include', 'python2.7/'))

info('Removing some unwanted files')
shprint(sh.rm, '-f', join('private', 'lib', 'libpython2.7.so'))
Expand All @@ -70,54 +85,53 @@ def run_distribute(self):
libdir = join(self.dist_dir, 'private', 'lib', 'python2.7')
site_packages_dir = join(libdir, 'site-packages')
with current_directory(libdir):
# shprint(sh.xargs, 'rm', sh.grep('-E', '*\.(py|pyx|so\.o|so\.a|so\.libs)$', sh.find('.')))
removes = []
for dirname, something, filens in walk('.'):
for filename in filens:
for suffix in ('py', 'pyc', 'so.o', 'so.a', 'so.libs'):
for dirname, root, filenames in walk("."):
for filename in filenames:
for suffix in EXCLUDE_EXTS:
if filename.endswith(suffix):
removes.append(filename)
shprint(sh.rm, '-f', *removes)

info('Deleting some other stuff not used on android')
# To quote the original distribute.sh, 'well...'
# shprint(sh.rm, '-rf', 'ctypes')
shprint(sh.rm, '-rf', 'lib2to3')
shprint(sh.rm, '-rf', 'idlelib')
for filename in glob.glob('config/libpython*.a'):
shprint(sh.rm, '-f', filename)
shprint(sh.rm, '-rf', 'config/python.o')
# shprint(sh.rm, '-rf', 'lib-dynload/_ctypes_test.so')
# shprint(sh.rm, '-rf', 'lib-dynload/_testcapi.so')

else: # Python *is* loaded from crystax
ndk_dir = self.ctx.ndk_dir
py_recipe = self.ctx.python_recipe
python_dir = join(ndk_dir, 'sources', 'python', py_recipe.version,
'libs', arch.arch)

shprint(sh.cp, '-r', join(python_dir, 'stdlib.zip'), 'crystax_python/crystax_python')
shprint(sh.cp, '-r', join(python_dir, 'modules'), 'crystax_python/crystax_python')
shprint(sh.cp, '-r', self.ctx.get_python_install_dir(), 'crystax_python/crystax_python/site-packages')
python_dir = join(ndk_dir, 'sources', 'python',
py_recipe.version, 'libs', arch.arch)
shprint(sh.cp, '-r', join(python_dir,
'stdlib.zip'), crystax_python_dir)
shprint(sh.cp, '-r', join(python_dir,
'modules'), crystax_python_dir)
shprint(sh.cp, '-r', self.ctx.get_python_install_dir(),
join(crystax_python_dir, 'site-packages'))

info('Renaming .so files to reflect cross-compile')
site_packages_dir = 'crystax_python/crystax_python/site-packages'
filens = shprint(sh.find, site_packages_dir, '-iname', '*.so').stdout.decode(
'utf-8').split('\n')[:-1]
for filen in filens:
parts = filen.split('.')
site_packages_dir = join(crystax_python_dir, "site-packages")
find_ret = shprint(
sh.find, site_packages_dir, '-iname', '*.so')
filenames = find_ret.stdout.decode('utf-8').split('\n')[:-1]
for filename in filenames:
parts = filename.split('.')
if len(parts) <= 2:
continue
shprint(sh.mv, filen, filen.split('.')[0] + '.so')
shprint(sh.mv, filename, filename.split('.')[0] + '.so')
site_packages_dir = join(abspath(curdir),
site_packages_dir)
if 'sqlite3' not in self.ctx.recipe_build_order:
with open('blacklist.txt', 'a') as fileh:
fileh.write('\nsqlite3/*\nlib-dynload/_sqlite3.so\n')


self.strip_libraries(arch)
self.fry_eggs(site_packages_dir)
super(SDL2Bootstrap, self).run_distribute()
super(SDL2GradleBootstrap, self).run_distribute()


bootstrap = SDL2Bootstrap()
bootstrap = SDL2GradleBootstrap()
14 changes: 14 additions & 0 deletions pythonforandroid/bootstraps/sdl2/build/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.gradle
/build/

# Ignore Gradle GUI config
gradle-app.setting

# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar

# Cache of project
.gradletasknamecache

# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898
# gradle/wrapper/gradle-wrapper.properties
4 changes: 4 additions & 0 deletions pythonforandroid/bootstraps/sdl2/build/ant.properties
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@
# The password will be asked during the build when you use the 'release' target.

source.absolute.dir = tmp-src

resource.absolute.dir = src/main/res

asset.absolute.dir = src/main/assets
Loading