Skip to content

Commit 0c25898

Browse files
committed
bootstrap: copy all the .so into lib with libpy_ prefix. Detect this prefix and load it with a custom importer.
1 parent ec82f56 commit 0c25898

File tree

3 files changed

+57
-3
lines changed

3 files changed

+57
-3
lines changed

bootstrap/common/build.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#!/usr/bin/env python2.7
22

3-
from os.path import dirname, join, isfile, realpath, relpath, split, exists
3+
from os.path import dirname, join, isfile, realpath, relpath, split, exists, \
4+
basename
45
from zipfile import ZipFile
56
import sys
67
sys.path.insert(0, 'buildlib/jinja2.egg')
@@ -224,7 +225,17 @@ def copy_to_assets(source_dirs, ignore_path=[]):
224225
print 'copy_to_assets()', source_dirs, ignore_path
225226
for fn, afn in iterate_sources(source_dirs, ignore_path):
226227
print '{}: {}'.format(fn, afn)
227-
dest_fn = join('assets', afn)
228+
229+
if afn.endswith(".so"):
230+
# copy to libs instead
231+
afn_dirname = dirname(afn)
232+
if "python2.7" in afn_dirname:
233+
# python lib, strip the directory
234+
afn_dirname = ""
235+
dest_fn = join("libs", "armeabi", "libpy_{}".format(
236+
afn_dirname.replace("/", "_").replace(".", "") + basename(afn)))
237+
else:
238+
dest_fn = join('assets', afn)
228239
dest_dir = dirname(dest_fn)
229240
if not exists(dest_dir):
230241
os.makedirs(dest_dir)

bootstrap/minimal/assets/_bootstrap.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,39 @@ def flush(self):
8383
sysconfig.get_config_h_filename = lambda: pyconfig_fn
8484

8585

86+
#
87+
# Step 4: install a custom importer
88+
#
89+
90+
import imp
91+
from os.path import join, exists
92+
93+
ANDROID_LIB_PATH = posix.environ["ANDROID_LIB_PATH"]
94+
95+
96+
class CustomBuiltinImporter(object):
97+
def find_module(self, fullname, mpath=None):
98+
modname = "libpy_{}.so".format(fullname.replace(".", "_"))
99+
modfn = join(ANDROID_LIB_PATH, modname)
100+
if exists(modfn):
101+
return self
102+
103+
def load_module(self, fullname):
104+
fn = fullname.replace(".", "_")
105+
mod = sys.modules.get(fn)
106+
if mod is None:
107+
try:
108+
mod = imp.load_dynamic(
109+
fn,
110+
join(ANDROID_LIB_PATH, "libpy_{}.so".format(fn)))
111+
except ImportError:
112+
# untested part, similar to iOS custom importer.
113+
mod = imp.load_dynamic(fullname, fullname)
114+
return mod
115+
116+
sys.meta_path.append(CustomBuiltinImporter())
117+
118+
86119
#
87120
# Step 4: bootstrap the application !
88121
#

bootstrap/minimal/jni/main.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,20 @@ void android_main(struct android_app* state) {
117117
jboolean isCopy;
118118
str = (*env)->GetStringUTFChars(env, (jstring)result, &isCopy);
119119
LOGI("Looked up package code path: %s", str);
120+
setenv("ANDROID_APK_FN", str, 1);
121+
122+
methodID = (*env)->GetMethodID(env, clazz, "getApplicationInfo", "()Landroid/content/pm/ApplicationInfo;");
123+
jobject appInfo = (*env)->CallObjectMethod(env, activity->clazz, methodID);
124+
jfieldID fieldID = (*env)->GetFieldID(env,
125+
(*env)->GetObjectClass(env, appInfo), "nativeLibraryDir", "Ljava/lang/String;");
126+
result = (*env)->GetObjectField(env, appInfo, fieldID);
127+
str = (*env)->GetStringUTFChars(env, (jstring)result, &isCopy);
128+
LOGI("Looked up library code path: %s", str);
129+
setenv("ANDROID_LIB_PATH", str, 1);
130+
120131
(*activity->vm)->DetachCurrentThread(activity->vm);
121132

122133
// set some envs
123-
setenv("ANDROID_APK_FN", str, 1);
124134
setenv("ANDROID_INTERNAL_DATA_PATH", state->activity->internalDataPath, 1);
125135
setenv("ANDROID_EXTERNAL_DATA_PATH", state->activity->externalDataPath, 1);
126136
LOGI("Internal data path is: %s", state->activity->internalDataPath);

0 commit comments

Comments
 (0)