Skip to content

Commit 024e0c9

Browse files
committed
Adapt service_only's bootstrap c/java code to new python build system
Also add some files because we need it because of the changes made in PythonService.java. Those files add the classes PythonActivity, AssetExtract and ResourceManager (those two lasts are pure copies from the ones in sdl2 bootstrap). Note: All this work is based on previous work done on sdl2 bootstrap
1 parent 98506aa commit 024e0c9

File tree

6 files changed

+772
-82
lines changed

6 files changed

+772
-82
lines changed

pythonforandroid/bootstraps/service_only/build/jni/application/src/start.c

Lines changed: 97 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,19 @@ int main(int argc, char *argv[]) {
7474
int ret = 0;
7575
FILE *fd;
7676

77-
/* AND: Several filepaths are hardcoded here, these must be made
78-
configurable */
79-
/* AND: P4A uses env vars...not sure what's best */
80-
LOGP("Initialize Python for Android");
77+
setenv("P4A_BOOTSTRAP", "SERVICE", 1); // env var to identify p4a to applications
78+
79+
LOGP("Initializing Python for Android");
8180
env_argument = getenv("ANDROID_ARGUMENT");
8281
setenv("ANDROID_APP_PATH", env_argument, 1);
8382
env_entrypoint = getenv("ANDROID_ENTRYPOINT");
8483
env_logname = getenv("PYTHON_NAME");
85-
84+
85+
if (!getenv("ANDROID_UNPACK")) {
86+
/* ANDROID_UNPACK currently isn't set in services */
87+
setenv("ANDROID_UNPACK", env_argument, 1);
88+
}
89+
8690
if (env_logname == NULL) {
8791
env_logname = "python";
8892
setenv("PYTHON_NAME", "python", 1);
@@ -102,34 +106,52 @@ int main(int argc, char *argv[]) {
102106

103107
LOGP("Preparing to initialize python");
104108

105-
if (dir_exists("crystax_python/")) {
106-
LOGP("crystax_python exists");
107-
char paths[256];
108-
snprintf(paths, 256,
109-
"%s/crystax_python/stdlib.zip:%s/crystax_python/modules",
110-
env_argument, env_argument);
111-
/* snprintf(paths, 256, "%s/stdlib.zip:%s/modules", env_argument,
112-
* env_argument); */
109+
// Set up the python path
110+
char paths[256];
111+
112+
char crystax_python_dir[256];
113+
snprintf(crystax_python_dir, 256,
114+
"%s/crystax_python", getenv("ANDROID_UNPACK"));
115+
char python_bundle_dir[256];
116+
snprintf(python_bundle_dir, 256,
117+
"%s/_python_bundle", getenv("ANDROID_UNPACK"));
118+
if (dir_exists(crystax_python_dir) || dir_exists(python_bundle_dir)) {
119+
if (dir_exists(crystax_python_dir)) {
120+
LOGP("crystax_python exists");
121+
snprintf(paths, 256,
122+
"%s/stdlib.zip:%s/modules",
123+
crystax_python_dir, crystax_python_dir);
124+
}
125+
126+
if (dir_exists(python_bundle_dir)) {
127+
LOGP("_python_bundle dir exists");
128+
snprintf(paths, 256,
129+
"%s/stdlib.zip:%s/modules",
130+
python_bundle_dir, python_bundle_dir);
131+
}
132+
113133
LOGP("calculated paths to be...");
114134
LOGP(paths);
115135

116-
#if PY_MAJOR_VERSION >= 3
117-
wchar_t *wchar_paths = Py_DecodeLocale(paths, NULL);
118-
Py_SetPath(wchar_paths);
119-
#else
120-
char *wchar_paths = paths;
121-
LOGP("Can't Py_SetPath in python2, so crystax python2 doesn't work yet");
122-
exit(1);
123-
#endif
136+
#if PY_MAJOR_VERSION >= 3
137+
wchar_t *wchar_paths = Py_DecodeLocale(paths, NULL);
138+
Py_SetPath(wchar_paths);
139+
#endif
124140

125-
LOGP("set wchar paths...");
141+
LOGP("set wchar paths...");
126142
} else {
127-
LOGP("crystax_python does not exist");
143+
// We do not expect to see crystax_python any more, so no point
144+
// reminding the user about it. If it does exist, we'll have
145+
// logged it earlier.
146+
LOGP("_python_bundle does not exist");
128147
}
129148

130149
Py_Initialize();
131150

132151
#if PY_MAJOR_VERSION < 3
152+
// Can't Py_SetPath in python2 but we can set PySys_SetPath, which must
153+
// be applied after Py_Initialize rather than before like Py_SetPath
154+
PySys_SetPath(paths);
133155
PySys_SetArgv(argc, argv);
134156
#endif
135157

@@ -151,24 +173,25 @@ int main(int argc, char *argv[]) {
151173
* replace sys.path with our path
152174
*/
153175
PyRun_SimpleString("import sys, posix\n");
154-
if (dir_exists("lib")) {
155-
/* If we built our own python, set up the paths correctly */
156-
LOGP("Setting up python from ANDROID_PRIVATE");
157-
PyRun_SimpleString("private = posix.environ['ANDROID_PRIVATE']\n"
158-
"argument = posix.environ['ANDROID_ARGUMENT']\n"
159-
"sys.path[:] = [ \n"
160-
" private + '/lib/python27.zip', \n"
161-
" private + '/lib/python2.7/', \n"
162-
" private + '/lib/python2.7/lib-dynload/', \n"
163-
" private + '/lib/python2.7/site-packages/', \n"
164-
" argument ]\n");
176+
177+
char add_site_packages_dir[256];
178+
if (dir_exists(crystax_python_dir)) {
179+
snprintf(add_site_packages_dir, 256,
180+
"sys.path.append('%s/site-packages')",
181+
crystax_python_dir);
182+
183+
PyRun_SimpleString("import sys\n"
184+
"sys.argv = ['notaninterpreterreally']\n"
185+
"from os.path import realpath, join, dirname");
186+
PyRun_SimpleString(add_site_packages_dir);
187+
/* "sys.path.append(join(dirname(realpath(__file__)), 'site-packages'))") */
188+
PyRun_SimpleString("sys.path = ['.'] + sys.path");
165189
}
166190

167-
if (dir_exists("crystax_python")) {
168-
char add_site_packages_dir[256];
191+
if (dir_exists(python_bundle_dir)) {
169192
snprintf(add_site_packages_dir, 256,
170-
"sys.path.append('%s/crystax_python/site-packages')",
171-
env_argument);
193+
"sys.path.append('%s/site-packages')",
194+
python_bundle_dir);
172195

173196
PyRun_SimpleString("import sys\n"
174197
"sys.argv = ['notaninterpreterreally']\n"
@@ -307,6 +330,7 @@ JNIEXPORT void JNICALL Java_org_kivy_android_PythonService_nativeStart(
307330
setenv("PYTHONHOME", python_home, 1);
308331
setenv("PYTHONPATH", python_path, 1);
309332
setenv("PYTHON_SERVICE_ARGUMENT", arg, 1);
333+
setenv("P4A_BOOTSTRAP", "SERVICE", 1);
310334

311335
char *argv[] = {"."};
312336
/* ANDROID_ARGUMENT points to service subdir,
@@ -315,4 +339,39 @@ JNIEXPORT void JNICALL Java_org_kivy_android_PythonService_nativeStart(
315339
main(1, argv);
316340
}
317341

342+
void Java_org_kivy_android_PythonActivity_nativeSetEnv(
343+
JNIEnv* env, jclass jcls,
344+
jstring j_name, jstring j_value)
345+
{
346+
jboolean iscopy;
347+
const char *name = (*env)->GetStringUTFChars(env, j_name, &iscopy);
348+
const char *value = (*env)->GetStringUTFChars(env, j_value, &iscopy);
349+
setenv(name, value, 1);
350+
(*env)->ReleaseStringUTFChars(env, j_name, name);
351+
(*env)->ReleaseStringUTFChars(env, j_value, value);
352+
}
353+
354+
355+
void Java_org_kivy_android_PythonActivity_nativeInit(JNIEnv* env, jclass cls, jobject obj)
356+
{
357+
/* This nativeInit follows SDL2 */
358+
359+
/* This interface could expand with ABI negotiation, callbacks, etc. */
360+
/* SDL_Android_Init(env, cls); */
361+
362+
/* SDL_SetMainReady(); */
363+
364+
/* Run the application code! */
365+
int status;
366+
char *argv[2];
367+
argv[0] = "Python_app";
368+
argv[1] = NULL;
369+
/* status = SDL_main(1, argv); */
370+
371+
main(1, argv);
372+
373+
/* Do not issue an exit or the whole application will terminate instead of just the SDL thread */
374+
/* exit(status); */
375+
}
376+
318377
#endif

0 commit comments

Comments
 (0)