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

Make Cython work without recipe #1483

Merged
merged 1 commit into from Jan 13, 2019
Merged
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
55 changes: 45 additions & 10 deletions pythonforandroid/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from os.path import (join, realpath, dirname, expanduser, exists,
split, isdir)
from os import environ
import copy
import os
import glob
import sys
Expand All @@ -13,7 +14,7 @@
from pythonforandroid.util import (ensure_dir, current_directory, BuildInterruptingException)
from pythonforandroid.logger import (info, warning, info_notify, info_main, shprint)
from pythonforandroid.archs import ArchARM, ArchARMv7_a, ArchAarch_64, Archx86, Archx86_64
from pythonforandroid.recipe import Recipe
from pythonforandroid.recipe import CythonRecipe, Recipe

DEFAULT_ANDROID_API = 15

Expand Down Expand Up @@ -682,17 +683,51 @@ def run_pymodules_install(ctx, modules):
line = '{}\n'.format(module)
fileh.write(line)

info('Installing Python modules with pip')
info('If this fails with a message about /bin/false, this '
'probably means the package cannot be installed with '
'pip as it needs a compilation recipe.')
base_env = copy.copy(os.environ)
base_env["PYTHONPATH"] = ctx.get_site_packages_dir()

info('Upgrade pip to latest version')
shprint(sh.bash, '-c', (
"source venv/bin/activate && pip install -U pip"
), _env=copy.copy(base_env))

# This bash method is what old-p4a used
# It works but should be replaced with something better
info('Install Cython in case one of the modules needs it to build')
shprint(sh.bash, '-c', (
"venv/bin/pip install Cython"
), _env=copy.copy(base_env))

# Get environment variables for build (with CC/compiler set):
standard_recipe = CythonRecipe()
standard_recipe.ctx = ctx
# (note: following line enables explicit -lpython... linker options)
standard_recipe.call_hostpython_via_targetpython = False
recipe_env = standard_recipe.get_recipe_env(ctx.archs[0])
env = copy.copy(base_env)
env.update(recipe_env)

info('Installing Python modules with pip')
info('IF THIS FAILS, THE MODULES MAY NEED A RECIPE. '
'A reason for this is often modules compiling '
'native code that is unaware of Android cross-compilation '
'and does not work without additional '
'changes / workarounds.')

# Make sure our build package dir is available, and the virtualenv
# site packages come FIRST (for the proper pip version):
env["PYTHONPATH"] += ":" + ctx.get_site_packages_dir()
env["PYTHONPATH"] = os.path.abspath(join(
ctx.build_dir, "venv", "lib",
"python" + ctx.python_recipe.major_minor_version_string,
"site-packages")) + ":" + env["PYTHONPATH"]
shprint(sh.bash, '-c', (
"env CC=/bin/false CXX=/bin/false "
"PYTHONPATH={0} venv/bin/pip install --target '{0}' --no-deps -r requirements.txt"
).format(ctx.get_site_packages_dir()))
"source venv/bin/activate && " +
"pip install -v --target '{0}' --no-deps -r requirements.txt"
).format(ctx.get_site_packages_dir().replace("'", "'\"'\"'")),
_env=copy.copy(env))

# Strip object files after potential Cython or native code builds:
standard_recipe.strip_object_files(ctx.archs[0], env,
build_dir=ctx.build_dir)


def biglink(ctx, arch):
Expand Down
49 changes: 33 additions & 16 deletions pythonforandroid/recipe.py
Original file line number Diff line number Diff line change
Expand Up @@ -779,12 +779,14 @@ def get_recipe_env(self, arch=None, with_flags_in_cc=True):
hppath.append(join(dirname(self.hostpython_location), 'Lib'))
hppath.append(join(hppath[0], 'site-packages'))
builddir = join(dirname(self.hostpython_location), 'build')
hppath += [join(builddir, d) for d in listdir(builddir)
if isdir(join(builddir, d))]
if 'PYTHONPATH' in env:
env['PYTHONPATH'] = ':'.join(hppath + [env['PYTHONPATH']])
else:
env['PYTHONPATH'] = ':'.join(hppath)
if exists(builddir):
hppath += [join(builddir, d) for d in listdir(builddir)
if isdir(join(builddir, d))]
if len(hppath) > 0:
if 'PYTHONPATH' in env:
env['PYTHONPATH'] = ':'.join(hppath + [env['PYTHONPATH']])
else:
env['PYTHONPATH'] = ':'.join(hppath)
return env

def should_build(self, arch):
Expand Down Expand Up @@ -955,16 +957,6 @@ def build_cython_components(self, arch):

env = self.get_recipe_env(arch)

if self.ctx.python_recipe.from_crystax:
command = sh.Command('python{}'.format(self.ctx.python_recipe.version))
site_packages_dirs = command(
'-c', 'import site; print("\\n".join(site.getsitepackages()))')
site_packages_dirs = site_packages_dirs.stdout.decode('utf-8').split('\n')
if 'PYTHONPATH' in env:
env['PYTHONPATH'] = env['PYTHONPATH'] + ':{}'.format(':'.join(site_packages_dirs))
else:
env['PYTHONPATH'] = ':'.join(site_packages_dirs)

with current_directory(self.get_build_dir(arch.arch)):
hostpython = sh.Command(self.ctx.hostpython)
shprint(hostpython, '-c', 'import sys; print(sys.path)', _env=env)
Expand All @@ -989,8 +981,15 @@ def build_cython_components(self, arch):
info('First build appeared to complete correctly, skipping manual'
'cythonising.')

self.strip_object_files(arch, env)

def strip_object_files(self, arch, env, build_dir=None):
if build_dir is None:
build_dir = self.get_build_dir(arch.arch)
with current_directory(build_dir):
info('Stripping object files')
if self.ctx.python_recipe.name == 'python2legacy':
info('Stripping object files')
Copy link
Member

Choose a reason for hiding this comment

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

Minor: isn't this redundant with the one two lines above?

build_lib = glob.glob('./build/lib*')
shprint(sh.find, build_lib[0], '-name', '*.o', '-exec',
env['STRIP'], '{}', ';', _env=env)
Expand Down Expand Up @@ -1055,6 +1054,24 @@ def get_recipe_env(self, arch, with_flags_in_cc=True):
env['LIBLINK_PATH'] = liblink_path
ensure_dir(liblink_path)

# Add crystax-specific site packages:
if self.ctx.python_recipe.from_crystax:
command = sh.Command('python{}'.format(self.ctx.python_recipe.version))
site_packages_dirs = command(
'-c', 'import site; print("\\n".join(site.getsitepackages()))')
site_packages_dirs = site_packages_dirs.stdout.decode('utf-8').split('\n')
if 'PYTHONPATH' in env:
env['PYTHONPATH'] = env['PYTHONPATH'] +\
':{}'.format(':'.join(site_packages_dirs))
else:
env['PYTHONPATH'] = ':'.join(site_packages_dirs)
while env['PYTHONPATH'].find("::") > 0:
env['PYTHONPATH'] = env['PYTHONPATH'].replace("::", ":")
if env['PYTHONPATH'].endswith(":"):
env['PYTHONPATH'] = env['PYTHONPATH'][:-1]
if env['PYTHONPATH'].startswith(":"):
env['PYTHONPATH'] = env['PYTHONPATH'][1:]

return env


Expand Down