8
8
9
9
from pythonforandroid .logger import (warning , shprint , info , logger ,
10
10
debug )
11
- from pythonforandroid .util import (current_directory , ensure_dir ,
12
- temp_directory , which )
11
+ from pythonforandroid .util import (current_directory , ensure_dir , which ,
12
+ temp_directory , BuildInterruptingException )
13
13
from pythonforandroid .recipe import Recipe
14
14
15
15
@@ -36,6 +36,10 @@ def copy_files(src_root, dest_root, override=True):
36
36
class Bootstrap (object ):
37
37
'''An Android project template, containing recipe stuff for
38
38
compilation and templated fields for APK info.
39
+
40
+ .. versionchanged:: 0.6.0
41
+ Adds attribute :attr:`libraries_to_load` and method
42
+ :meth:`collect_libraries_to_load`.
39
43
'''
40
44
name = ''
41
45
jni_subdir = '/jni'
@@ -56,6 +60,11 @@ class Bootstrap(object):
56
60
from Bootstrap.get_bootstrap_from_recipes.
57
61
'''
58
62
63
+ libraries_to_load = []
64
+ '''The list of libraries that should be loaded by android on python's app
65
+ initialization. This list will be dynamically created at
66
+ :meth:`collect_libraries_to_load` depending on the recipes build order.'''
67
+
59
68
# Other things a Bootstrap might need to track (maybe separately):
60
69
# ndk_main.c
61
70
# whitelist.txt
@@ -257,6 +266,83 @@ def _unpack_aar(self, aar, arch):
257
266
for f in so_files :
258
267
shprint (sh .cp , '-a' , f , so_tgt_dir )
259
268
269
+ def collect_libraries_to_load (self , arch ):
270
+ '''
271
+ Collect the shared libraries needed to load when apk initialises and
272
+ returns a list. This list will be used to create a file in our
273
+ distribution's assets folder which will be used by our java loading
274
+ mechanism to load those shared libraries at runtime.
275
+
276
+ .. warning:: the loading order matters, this cannot be arbitrary,
277
+ for example, if some lib has been build against our python, then
278
+ needs to be loaded after the python library has been loaded.
279
+ '''
280
+ info ('Collect compiled shared libraries to load at runtime' )
281
+
282
+ libs_to_load = []
283
+ # Add libs that should be loaded before bootstrap libs (here goes some
284
+ # special shared libs, like stl libs used at compile time or libs that
285
+ # the bootstrap may be dependant).
286
+ # Todo: All the recipes using gnustl_shared should be migrated to use
287
+ # c++_shared because in ndk r18 it will be the only stl available:
288
+ # https://developer.android.com/ndk/guides/cpp-support
289
+ for recipe_name in self .ctx .recipe_build_order :
290
+ recipe = Recipe .get_recipe (recipe_name , self .ctx )
291
+ if recipe .stl_depends is None :
292
+ continue
293
+ if recipe .stl_depends not in ('c++_shared' , 'gnustl_shared' ):
294
+ raise BuildInterruptingException (
295
+ 'You have a non supported value in attribute stl_depends '
296
+ '"{stl_lib}" for recipe "{recipe_name}". The'
297
+ 'value should be one of: "c++_shared" or "gnustl_shared"' .format (
298
+ stl_lib = recipe .stl_depends , recipe_name = recipe .name ))
299
+ if recipe .stl_depends not in libs_to_load :
300
+ libs_to_load .append (recipe .stl_depends )
301
+ if all (lib in libs_to_load for lib in ('c++_shared' , 'gnustl_shared' )):
302
+ break
303
+
304
+ # Add crystax if necessary
305
+ if self .ctx .python_recipe .from_crystax :
306
+ libs_to_load .append ('crystax' )
307
+
308
+ # Add libraries that python depends on
309
+ if 'sqlite3' in self .ctx .recipe_build_order :
310
+ libs_to_load .append ('sqlite3' )
311
+ if 'libffi' in self .ctx .recipe_build_order :
312
+ libs_to_load .append ('ffi' )
313
+ if 'openssl' in self .ctx .recipe_build_order :
314
+ recipe = Recipe .get_recipe ('openssl' , self .ctx )
315
+ libs_to_load .append ('ssl' + recipe .version )
316
+ libs_to_load .append ('crypto' + recipe .version )
317
+
318
+ # Add the bootstrap libs
319
+ [libs_to_load .append (i ) for i in self .libraries_to_load ]
320
+
321
+ # Add the corresponding python lib
322
+ python_version = self .ctx .python_recipe .major_minor_version_string
323
+ if python_version [0 ] == '3' :
324
+ python_version += 'm'
325
+ libs_to_load .append ('python' + python_version )
326
+
327
+ # Add libs that should be loaded after python because depends on it
328
+ if 'boost' in self .ctx .recipe_build_order :
329
+ # Todo: check boost loading dependencies and create a proper
330
+ # loading order. For now it works for libtorrent's recipe, the only
331
+ # recipe that depends on boost...so...for now it's fine, but should
332
+ # be enhanced, maybe using similar method than
333
+ # `pythonforandroid.build.copylibs_function`?
334
+ for l in listdir (self .ctx .get_libs_dir (arch .arch )):
335
+ if l .startswith ('libboost_' ):
336
+ libs_to_load .append (l [3 :- 3 ])
337
+ if 'libtorrent' in self .ctx .recipe_build_order :
338
+ libs_to_load .append ('torrent_rasterbar' )
339
+ if 'libiconv' in self .ctx .recipe_build_order :
340
+ libs_to_load .append ('iconv' )
341
+ if 'libzbar' in self .ctx .recipe_build_order :
342
+ libs_to_load .append ('zbar' )
343
+
344
+ return libs_to_load
345
+
260
346
def strip_libraries (self , arch ):
261
347
info ('Stripping libraries' )
262
348
if self .ctx .python_recipe .from_crystax :
0 commit comments