Skip to content

Commit b5019c2

Browse files
committed
Add bootstrap backend for Android Library project
1 parent 982469a commit b5019c2

File tree

28 files changed

+1995
-13
lines changed

28 files changed

+1995
-13
lines changed

pythonforandroid/bootstraps/common/build/build.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ def compile_dir(dfn, optimize_python=True):
274274
def make_package(args):
275275
# If no launcher is specified, require a main.py/main.pyo:
276276
if (get_bootstrap_name() != "sdl" or args.launcher is None) and \
277-
get_bootstrap_name() != "webview":
277+
get_bootstrap_name() not in ["webview", "library"]:
278278
# (webview doesn't need an entrypoint, apparently)
279279
if args.private is None or (
280280
not exists(join(realpath(args.private), 'main.py')) and
@@ -509,8 +509,9 @@ def make_package(args):
509509
aars=aars,
510510
jars=jars,
511511
android_api=android_api,
512-
build_tools_version=build_tools_version
513-
)
512+
build_tools_version=build_tools_version,
513+
is_library=get_bootstrap_name() == 'library',
514+
)
514515

515516
# ant build templates
516517
render(

pythonforandroid/bootstraps/common/build/templates/build.tmpl.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@ allprojects {
1919
}
2020
}
2121

22+
{% if is_library %}
23+
apply plugin: 'com.android.library'
24+
{% else %}
2225
apply plugin: 'com.android.application'
26+
{% endif %}
2327

2428
android {
2529
compileSdkVersion {{ android_api }}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from pythonforandroid.bootstraps.service_only import ServiceOnlyBootstrap
2+
3+
4+
class LibraryBootstrap(ServiceOnlyBootstrap):
5+
6+
name = 'library'
7+
8+
9+
bootstrap = LibraryBootstrap()
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# prevent user to include invalid extensions
2+
*.apk
3+
*.pxd
4+
5+
# eggs
6+
*.egg-info
7+
8+
# unit test
9+
unittest/*
10+
11+
# python config
12+
config/makesetup
13+
14+
# unused kivy files (platform specific)
15+
kivy/input/providers/wm_*
16+
kivy/input/providers/mactouch*
17+
kivy/input/providers/probesysfs*
18+
kivy/input/providers/mtdev*
19+
kivy/input/providers/hidinput*
20+
kivy/core/camera/camera_videocapture*
21+
kivy/core/spelling/*osx*
22+
kivy/core/video/video_pyglet*
23+
kivy/tools
24+
kivy/tests/*
25+
kivy/*/*.h
26+
kivy/*/*.pxi
27+
28+
# unused encodings
29+
lib-dynload/*codec*
30+
encodings/cp*.pyo
31+
encodings/tis*
32+
encodings/shift*
33+
encodings/bz2*
34+
encodings/iso*
35+
encodings/undefined*
36+
encodings/johab*
37+
encodings/p*
38+
encodings/m*
39+
encodings/euc*
40+
encodings/k*
41+
encodings/unicode_internal*
42+
encodings/quo*
43+
encodings/gb*
44+
encodings/big5*
45+
encodings/hp*
46+
encodings/hz*
47+
48+
# unused python modules
49+
bsddb/*
50+
wsgiref/*
51+
hotshot/*
52+
pydoc_data/*
53+
tty.pyo
54+
anydbm.pyo
55+
nturl2path.pyo
56+
LICENCE.txt
57+
macurl2path.pyo
58+
dummy_threading.pyo
59+
audiodev.pyo
60+
antigravity.pyo
61+
dumbdbm.pyo
62+
sndhdr.pyo
63+
__phello__.foo.pyo
64+
sunaudio.pyo
65+
os2emxpath.pyo
66+
multiprocessing/dummy*
67+
68+
# unused binaries python modules
69+
lib-dynload/termios.so
70+
lib-dynload/_lsprof.so
71+
lib-dynload/*audioop.so
72+
lib-dynload/_hotshot.so
73+
lib-dynload/_heapq.so
74+
lib-dynload/_json.so
75+
lib-dynload/grp.so
76+
lib-dynload/resource.so
77+
lib-dynload/pyexpat.so
78+
lib-dynload/_ctypes_test.so
79+
lib-dynload/_testcapi.so
80+
81+
# odd files
82+
plat-linux3/regen
83+
84+
#>sqlite3
85+
# conditionnal include depending if some recipes are included or not.
86+
sqlite3/*
87+
lib-dynload/_sqlite3.so
88+
#<sqlite3
89+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
include $(call all-subdir-makefiles)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
# Uncomment this if you're using STL in your project
3+
# See CPLUSPLUS-SUPPORT.html in the NDK documentation for more information
4+
# APP_STL := stlport_static
5+
6+
# APP_ABI := armeabi armeabi-v7a x86
7+
APP_ABI := $(ARCH)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
LOCAL_PATH := $(call my-dir)
2+
3+
include $(CLEAR_VARS)
4+
5+
LOCAL_MODULE := main
6+
7+
# Add your application source files here...
8+
LOCAL_SRC_FILES := start.c pyjniusjni.c
9+
10+
LOCAL_CFLAGS += -I$(PYTHON_INCLUDE_ROOT) $(EXTRA_CFLAGS)
11+
12+
LOCAL_SHARED_LIBRARIES := python_shared
13+
14+
LOCAL_LDLIBS := -llog $(EXTRA_LDLIBS)
15+
16+
LOCAL_LDFLAGS += -L$(PYTHON_LINK_ROOT) $(APPLICATION_ADDITIONAL_LDFLAGS)
17+
18+
include $(BUILD_SHARED_LIBRARY)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
LOCAL_PATH := $(call my-dir)
2+
3+
include $(CLEAR_VARS)
4+
5+
LOCAL_MODULE := main
6+
7+
LOCAL_SRC_FILES := YourSourceHere.c
8+
9+
include $(BUILD_SHARED_LIBRARY)
10+
$(call import-module,SDL)LOCAL_PATH := $(call my-dir)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
#define BOOTSTRAP_NAME_LIBRARY
3+
#define BOOTSTRAP_USES_NO_SDL_HEADERS
4+
5+
const char bootstrap_name[] = "library";
6+
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
2+
#include <pthread.h>
3+
#include <jni.h>
4+
5+
#define LOGI(...) do {} while (0)
6+
#define LOGE(...) do {} while (0)
7+
8+
#include "android/log.h"
9+
10+
/* These JNI management functions are taken from SDL2, but modified to refer to pyjnius */
11+
12+
/* #define LOG(n, x) __android_log_write(ANDROID_LOG_INFO, (n), (x)) */
13+
/* #define LOGP(x) LOG("python", (x)) */
14+
#define LOG_TAG "Python_android"
15+
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
16+
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
17+
18+
19+
/* Function headers */
20+
JNIEnv* Android_JNI_GetEnv(void);
21+
static void Android_JNI_ThreadDestroyed(void*);
22+
23+
static pthread_key_t mThreadKey;
24+
static JavaVM* mJavaVM;
25+
26+
int Android_JNI_SetupThread(void)
27+
{
28+
Android_JNI_GetEnv();
29+
return 1;
30+
}
31+
32+
/* Library init */
33+
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved)
34+
{
35+
JNIEnv *env;
36+
mJavaVM = vm;
37+
LOGI("JNI_OnLoad called");
38+
if ((*mJavaVM)->GetEnv(mJavaVM, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
39+
LOGE("Failed to get the environment using GetEnv()");
40+
return -1;
41+
}
42+
/*
43+
* Create mThreadKey so we can keep track of the JNIEnv assigned to each thread
44+
* Refer to http://developer.android.com/guide/practices/design/jni.html for the rationale behind this
45+
*/
46+
if (pthread_key_create(&mThreadKey, Android_JNI_ThreadDestroyed) != 0) {
47+
48+
__android_log_print(ANDROID_LOG_ERROR, "pyjniusjni", "Error initializing pthread key");
49+
}
50+
Android_JNI_SetupThread();
51+
52+
return JNI_VERSION_1_4;
53+
}
54+
55+
JNIEnv* Android_JNI_GetEnv(void)
56+
{
57+
/* From http://developer.android.com/guide/practices/jni.html
58+
* All threads are Linux threads, scheduled by the kernel.
59+
* They're usually started from managed code (using Thread.start), but they can also be created elsewhere and then
60+
* attached to the JavaVM. For example, a thread started with pthread_create can be attached with the
61+
* JNI AttachCurrentThread or AttachCurrentThreadAsDaemon functions. Until a thread is attached, it has no JNIEnv,
62+
* and cannot make JNI calls.
63+
* Attaching a natively-created thread causes a java.lang.Thread object to be constructed and added to the "main"
64+
* ThreadGroup, making it visible to the debugger. Calling AttachCurrentThread on an already-attached thread
65+
* is a no-op.
66+
* Note: You can call this function any number of times for the same thread, there's no harm in it
67+
*/
68+
69+
JNIEnv *env;
70+
int status = (*mJavaVM)->AttachCurrentThread(mJavaVM, &env, NULL);
71+
if(status < 0) {
72+
LOGE("failed to attach current thread");
73+
return 0;
74+
}
75+
76+
/* From http://developer.android.com/guide/practices/jni.html
77+
* Threads attached through JNI must call DetachCurrentThread before they exit. If coding this directly is awkward,
78+
* in Android 2.0 (Eclair) and higher you can use pthread_key_create to define a destructor function that will be
79+
* called before the thread exits, and call DetachCurrentThread from there. (Use that key with pthread_setspecific
80+
* to store the JNIEnv in thread-local-storage; that way it'll be passed into your destructor as the argument.)
81+
* Note: The destructor is not called unless the stored value is != NULL
82+
* Note: You can call this function any number of times for the same thread, there's no harm in it
83+
* (except for some lost CPU cycles)
84+
*/
85+
pthread_setspecific(mThreadKey, (void*) env);
86+
87+
return env;
88+
}
89+
90+
static void Android_JNI_ThreadDestroyed(void* value)
91+
{
92+
/* The thread is being destroyed, detach it from the Java VM and set the mThreadKey value to NULL as required */
93+
JNIEnv *env = (JNIEnv*) value;
94+
if (env != NULL) {
95+
(*mJavaVM)->DetachCurrentThread(mJavaVM);
96+
pthread_setspecific(mThreadKey, NULL);
97+
}
98+
}
99+
100+
void *WebView_AndroidGetJNIEnv()
101+
{
102+
return Android_JNI_GetEnv();
103+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy