8000 Allow local edition of recipes. Recipe replacing standard one is loca… · jb1123/python-for-android@b1d1f1a · GitHub
[go: up one dir, main page]

Skip to content

Commit b1d1f1a

Browse files
committed
Allow local edition of recipes. Recipe replacing standard one is located in a
directory defined in an environment variable P4A_{name}_DIR, where {name} stands for the recipe name. P4A_force_build set (True) forces local recipes rebuild, other (standard download) recipes are reused. On linux P4A downloads and builds are stored in ~/.local/share/python-for-android/ (no change), to initialize p4a build erase the directory. Changes to be committed: modified: pythonforandroid/build.py modified: pythonforandroid/distribution.py modified: pythonforandroid/recipe.py modified: pythonforandroid/toolchain.py
1 parent f5335ed commit b1d1f1a

File tree

4 files changed

+73
-19
lines changed

4 files changed

+73
-19
lines changed

pythonforandroid/build.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ class Context(object):
4747

4848
symlink_java_src = False # If True, will symlink instead of copying during build
4949

50+
P4A_force_build = False # True forces local recipes rebuild, see toolchain.dist_from_args()
51+
5052
@property
5153
def packages_path(self):
5254
'''Where packages are downloaded before being unpacked'''
@@ -539,13 +541,19 @@ def build_recipes(build_order, python_modules, ctx):
539541
# download is arch independent
540542
info_main('# Downloading recipes ')
541543
for recipe in recipes:
544+
if ctx.P4A_force_build and not recipe.force_build:
545+
info_main('recipe {0} not marked for force build, skip download'.format(recipe.name))
546+
continue
542547
recipe.download_if_necessary()
543548

544549
for arch in ctx.archs:
545550
info_main('# Building all recipes for arch {}'.format(arch.arch))
546551

547552
info_main('# Unpacking recipes')
548553
for recipe in recipes:
554+
if ctx.P4A_force_build and not recipe.force_build:
555+
info_main('recipe {0} not marked for force build, skip unpack'.format(recipe.name))
556+
continue
549557
ensure_dir(recipe.get_build_container_dir(arch.arch))
550558
recipe.prepare_build_dir(arch.arch)
551559

@@ -560,7 +568,7 @@ def build_recipes(build_order, python_modules, ctx):
560568
info_main('# Building recipes')
561569
for recipe in recipes:
562570
info_main('Building {} for {}'.format(recipe.name, arch.arch))
563-
if recipe.should_build(arch):
571+
if recipe.force_build or recipe.should_build(arch):
564572
recipe.build_arch(arch)
565573
else:
566574
info('{} said it is already built, skipping'

pythonforandroid/distribution.py

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import os
12
from os.path import exists, join
23
import glob
34
import json
@@ -29,6 +30,12 @@ class Distribution(object):
2930

3031
description = '' # A long description
3132

33+
P4A_force_build = False
34+
'''P4A_force_build True if distribution build forced by environmental variables:
35+
P4A_{name}_DIR - pointing to local repository
36+
P4A_force_build - request build for local recipies
37+
'''
38+
3239
def __init__(self, ctx):
3340
self.ctx = ctx
3441

@@ -102,15 +109,20 @@ def get_distribution(cls, ctx, name=None, recipes=[],
102109
info('No existing dists meet the given requirements!')
103110

104111
# If any dist has perfect recipes, return it
112+
P4A_force_build = False
105113
for dist in possible_dists:
106-
if force_build:
107-
continue
108114
if (set(dist.recipes) == set(recipes) or
109115
(set(recipes).issubset(set(dist.recipes)) and
110116
not require_perfect_match)):
111-
info_notify('{} has compatible recipes, using this one'
112-
.format(dist.name))
113-
return dist
117+
if force_build:
118+
# distribution exists, rebuild forced
119+
P4A_force_build = True
120+
continue
121+
else:
122+
# existing distribution returned, no build required
123+
info_notify('{} has compatible recipes, using this one'
124+
.format(dist.name))
125+
return dist
114126

115127
assert len(possible_dists) < 2
116128

@@ -145,6 +157,11 @@ def get_distribution(cls, ctx, name=None, recipes=[],
145157
# If we got this far, we need to build a new dist
146158
dist = Distribution(ctx)
147159
dist.needs_build = True
160+
"""Locally modified recipes will be forced to build, others are reused
161+
environmental variable P4A_{recipe_name}_DIR points to local recipe
162+
P4A_force_build affects all local recipes"""
163+
164+
dist.P4A_force_build = P4A_force_build and os.environ.get('P4A_force_build')
148165

149166
if not name:
150167
filen = 'unnamed_dist_{}'

pythonforandroid/recipe.py

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,21 @@ class Recipe(with_metaclass(RecipeMeta)):
103103

104104
archs = ['armeabi'] # Not currently implemented properly
105105

106+
@property
107+
def user_dir(self):
108+
# user source directory overriding standard location defined in recipe
109+
key = 'P4A_{0}_DIR'.format(self.name)
110+
# for easier debug
111+
v = environ.get(key)
112+
return v
113+
114+
@property
115+
def force_build(self):
116+
# if True forces recipe build see build.py build_recipes()
117+
fb = bool(environ.get('P4A_force_build'))
118+
v = bool(fb and self.user_dir)
119+
return v
120+
106121
@property
107122
def version(self):
108123
key = 'VERSION_' + self.name
@@ -336,8 +351,8 @@ def get_recipe_dir(self):
336351

337352
def download_if_necessary(self):
338353
info_main('Downloading {}'.format(self.name))
339-
user_dir = environ.get('P4A_{}_DIR'.format(self.name.lower()))
340-
if user_dir is not None:
354+
# user_dir is a property
355+
if self.user_dir is not None:
341356
info('P4A_{}_DIR is set, skipping download for {}'.format(
342357
self.name, self.name))
343358
return
@@ -400,20 +415,24 @@ def unpack(self, arch):
400415

401416
build_dir = self.get_build_container_dir(arch)
402417

403-
user_dir = environ.get('P4A_{}_DIR'.format(self.name.lower()))
404-
if user_dir is not None:
418+
# user_dir = environ.get('P4A_{}_DIR'.format(self.name.lower()))
419+
if self.user_dir is not None:
405420
info('P4A_{}_DIR exists, symlinking instead'.format(
406421
self.name.lower()))
407422
# AND: Currently there's something wrong if I use ln, fix this
408423
warning('Using cp -a instead of symlink...fix this!')
409-
if exists(self.get_build_dir(arch)):
424+
if exists(self.get_build_dir(arch)) and not self.force_build:
425+
info('copy in place skipping cp {0}'.format(self.user_dir))
426+
return
427+
else:
428+
info('clening dirs')
429+
shprint(sh.rm, '-rf', build_dir)
430+
shprint(sh.mkdir, '-p', build_dir)
431+
shprint(sh.rmdir, build_dir)
432+
ensure_dir(build_dir)
433+
info('starting cp {0}'.format(self.user_dir))
434+
shprint(sh.cp, '-a', self.user_dir, self.get_build_dir(arch))
410435
return
411-
shprint(sh.rm, '-rf', build_dir)
412-
shprint(sh.mkdir, '-p', build_dir)
413-
shprint(sh.rmdir, build_dir)
414-
ensure_dir(build_dir)
415-
shprint(sh.cp, '-a', user_dir, self.get_build_dir(arch))
416-
return
417436

418437
if self.url is None:
419438
info('Skipping {} unpack as no URL is set'.format(self.name))

pythonforandroid/toolchain.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,13 +153,20 @@ def dist_from_args(ctx, args):
153153
'''Parses out any distribution-related arguments, and uses them to
154154
obtain a Distribution class instance for the build.
155155
'''
156-
return Distribution.get_distribution(
156+
# check if distribution force build requested
157+
force_build = bool( os.environ.get('P4A_force_build') ) or args.force_build
158+
dist = Distribution.get_distribution(
157159
ctx,
158160
name=args.dist_name,
159161
recipes=split_argument_list(args.requirements),
162+
force_build=force_build,
160163
extra_dist_dirs=split_argument_list(args.extra_dist_dirs),
161164
require_perfect_match=args.require_perfect_match)
162165

166+
# for distribution where user requested local recipe rebuild P4A_force_build set tue
167+
ctx.P4A_force_build = dist.P4A_force_build # see Distribution.get_distribution()
168+
return dist
169+
163170

164171
def build_dist_from_args(ctx, dist, args):
165172
'''Parses out any bootstrap related arguments, and uses them to build
@@ -505,7 +512,10 @@ def add_parser(subparsers, *args, **kwargs):
505512
self.ctx.copy_libs = args.copy_libs
506513

507514
# Each subparser corresponds to a method
508-
getattr(self, args.subparser_name.replace('-', '_'))(args)
515+
# make executed command starts build, let's make it more visible
516+
# getattr(self, args.subparser_name.replace('-', '_'))(args)
517+
cmd = args.subparser_name.replace('-', '_')
518+
getattr(self, cmd)(args)
509519

510520
def hook(self, name):
511521
if not self.args.hook:

0 commit comments

Comments
 (0)
0