Skip to content

SDL2/Gradle bootstrap #1042

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

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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: 15 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 @@ -190,20 +190,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 Expand Up @@ -271,6 +272,15 @@ def fry_eggs(self, sitepackages):
shprint(sh.mv, '-t', sitepackages, *files)
shprint(sh.rm, '-rf', d)

def apk(self, build_mode, env):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this function actually get called from somewhere? I see the ant/gradle build stuff is handled elsewhere.

try:
ant = sh.Command('ant')
except sh.CommandNotFound:
error('Could not find ant binary, please install it and make '
'sure it is in your $PATH.')
exit(1)
return shprint(ant, build_mode, _tail=20, _critical=True, _env=env)


def expand_dependencies(recipes):
recipe_lists = [[]]
Expand Down
156 changes: 156 additions & 0 deletions pythonforandroid/bootstraps/sdl2_gradle/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# coding=utf-8
"""
Bootstrap for SDL2, using gradlew for building
==============================================

.. warning:: Experimental

Good point:
- automatic dependencies management
- no need to unpack aar

TODO:
- test with crystax
- hardcoded -lpython2.7 in build/jni/src/Android.mk
- Android.mk require both -I, otherwise it fail in different points

"""

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


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 ({})".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)

# 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))

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

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 from_crystax:
try:
shprint(hostpython, '-OO', '-m', 'compileall',
python_install_dir,
_tail=10, _filterout="^Listing")
except sh.ErrorReturnCode:
pass
if not exists('python-install'):
shprint(
sh.cp, '-a', python_install_dir, './python-install')

self.distribute_libs(arch, [self.ctx.get_libs_dir(arch.arch)],
dest_dir=join("src", "main", "jniLibs"))
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
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'))
shprint(sh.rm, '-rf', join('private', 'lib', 'pkgconfig'))

libdir = join(self.dist_dir, 'private', 'lib', 'python2.7')
site_packages_dir = join(libdir, 'site-packages')
with current_directory(libdir):
removes = []
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', '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')

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_dir)
shprint(sh.cp, '-r', join(python_dir,
'modules'), crystax_python_dir)
shprint(sh.cp, '-r', self.ctx.get_python_install_dir(),
crystax_python_dir)

info('Renaming .so files to reflect cross-compile')
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, 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(SDL2GradleBootstrap, self).run_distribute()


bootstrap = SDL2GradleBootstrap()
14 changes: 14 additions & 0 deletions pythonforandroid/bootstraps/sdl2_gradle/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
83 changes: 83 additions & 0 deletions pythonforandroid/bootstraps/sdl2_gradle/build/blacklist.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# prevent user to include invalid extensions
*.apk
*.pxd

# eggs
*.egg-info

# unit test
unittest/*

# python config
config/makesetup

# unused kivy files (platform specific)
kivy/input/providers/wm_*
kivy/input/providers/mactouch*
kivy/input/providers/probesysfs*
kivy/input/providers/mtdev*
kivy/input/providers/hidinput*
kivy/core/camera/camera_videocapture*
kivy/core/spelling/*osx*
kivy/core/video/video_pyglet*
kivy/tools
kivy/tests/*
kivy/*/*.h
kivy/*/*.pxi

# unused encodings
lib-dynload/*codec*
encodings/cp*.pyo
encodings/tis*
encodings/shift*
encodings/bz2*
encodings/iso*
encodings/undefined*
encodings/johab*
encodings/p*
encodings/m*
encodings/euc*
encodings/k*
encodings/unicode_internal*
encodings/quo*
encodings/gb*
encodings/big5*
encodings/hp*
encodings/hz*

# unused python modules
bsddb/*
wsgiref/*
hotshot/*
pydoc_data/*
tty.pyo
anydbm.pyo
nturl2path.pyo
LICENCE.txt
macurl2path.pyo
dummy_threading.pyo
audiodev.pyo
antigravity.pyo
dumbdbm.pyo
sndhdr.pyo
__phello__.foo.pyo
sunaudio.pyo
os2emxpath.pyo
multiprocessing/dummy*

# unused binaries python modules
lib-dynload/termios.so
lib-dynload/_lsprof.so
lib-dynload/*audioop.so
lib-dynload/mmap.so
lib-dynload/_hotshot.so
lib-dynload/_heapq.so
lib-dynload/_json.so
lib-dynload/grp.so
lib-dynload/resource.so
lib-dynload/pyexpat.so
lib-dynload/_ctypes_test.so
lib-dynload/_testcapi.so

# odd files
plat-linux3/regen
Loading