@@ -74,15 +74,19 @@ int main(int argc, char *argv[]) {
74
74
int ret = 0 ;
75
75
FILE * fd ;
76
76
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" );
81
80
env_argument = getenv ("ANDROID_ARGUMENT" );
82
81
setenv ("ANDROID_APP_PATH" , env_argument , 1 );
83
82
env_entrypoint = getenv ("ANDROID_ENTRYPOINT" );
84
83
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
+
86
90
if (env_logname == NULL ) {
87
91
env_logname = "python" ;
88
92
setenv ("PYTHON_NAME" , "python" , 1 );
@@ -102,34 +106,52 @@ int main(int argc, char *argv[]) {
102
106
103
107
LOGP ("Preparing to initialize python" );
104
108
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
+
113
133
LOGP ("calculated paths to be..." );
114
134
LOGP (paths );
115
135
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
124
140
125
- LOGP ("set wchar paths..." );
141
+ LOGP ("set wchar paths..." );
126
142
} 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" );
128
147
}
129
148
130
149
Py_Initialize ();
131
150
132
151
#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 );
133
155
PySys_SetArgv (argc , argv );
134
156
#endif
135
157
@@ -151,24 +173,25 @@ int main(int argc, char *argv[]) {
151
173
* replace sys.path with our path
152
174
*/
153
175
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" );
165
189
}
166
190
167
- if (dir_exists ("crystax_python" )) {
168
- char add_site_packages_dir [256 ];
191
+ if (dir_exists (python_bundle_dir )) {
169
192
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 );
172
195
173
196
PyRun_SimpleString ("import sys\n"
174
197
"sys.argv = ['notaninterpreterreally']\n"
@@ -307,6 +330,7 @@ JNIEXPORT void JNICALL Java_org_kivy_android_PythonService_nativeStart(
307
330
setenv ("PYTHONHOME" , python_home , 1 );
308
331
setenv ("PYTHONPATH" , python_path , 1 );
309
332
setenv ("PYTHON_SERVICE_ARGUMENT" , arg , 1 );
333
+ setenv ("P4A_BOOTSTRAP" , "SERVICE" , 1 );
310
334
311
335
char * argv [] = {"." };
312
336
/* ANDROID_ARGUMENT points to service subdir,
@@ -315,4 +339,39 @@ JNIEXPORT void JNICALL Java_org_kivy_android_PythonService_nativeStart(
315
339
main (1 , argv );
316
340
}
317
341
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
+
318
377
#endif
0 commit comments