Skip to content

Commit ce41723

Browse files
committed
Merge pull request kivy#258 from kived/jb-dlopen
add copylibs option
2 parents b65f355 + 7a60a3a commit ce41723

File tree

3 files changed

+189
-3
lines changed

3 files changed

+189
-3
lines changed

distribute.sh

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ export BIGLINK="$ROOT_PATH/src/tools/biglink"
6363
export PIP=$PIP_NAME
6464
export VIRTUALENV=$VIRTUALENV_NAME
6565

66+
export COPYLIBS=0
67+
6668
MD5SUM=$(which md5sum)
6769
if [ "X$MD5SUM" == "X" ]; then
6870
MD5SUM=$(which md5)
@@ -217,6 +219,7 @@ function push_arm() {
217219
export LD="$TOOLCHAIN_PREFIX-ld"
218220
export STRIP="$TOOLCHAIN_PREFIX-strip --strip-unneeded"
219221
export MAKE="make -j5"
222+
export READELF="$TOOLCHAIN_PREFIX-readelf"
220223

221224
# Use ccache ?
222225
which ccache &>/dev/null
@@ -253,6 +256,10 @@ function usage() {
253256
echo " -f Restart from scratch (remove the current build)"
254257
echo " -x display expanded values (execute 'set -x')"
255258
echo
259+
echo "Advanced:"
260+
echo " -C Copy libraries instead of using biglink"
261+
echo " (may not work before Android 4.3)"
262+
echo
256263
echo "For developers:"
257264
echo " -u 'mod1 mod2' Modules to update (if already compiled)"
258265
echo
@@ -345,6 +352,15 @@ function run_prepare() {
345352
fi
346353
done
347354

355+
if [ "$COPYLIBS" == "1" ]; then
356+
info "Library files will be copied to the distribution (no biglink)"
357+
error "NOTICE: This option is still beta!"
358+
error "\tIf you encounter an error 'Failed to locate needed libraries!' and"
359+
error "\tthe libraries listed are not supposed to be provided by your app or"
360+
error "\tits dependencies, please submit a bug report at"
361+
error "\thttps://github.com/kivy/python-for-android/issues"
362+
fi
363+
348364
info "Distribution will be located at $DIST_PATH"
349365
if [ -e "$DIST_PATH" ]; then
350366
error "The distribution $DIST_PATH already exist"
@@ -763,7 +779,14 @@ function run_distribute() {
763779
debug "Fill private directory"
764780
try cp -a python-install/lib private/
765781
try mkdir -p private/include/python2.7
766-
try mv libs/$ARCH/libpymodules.so private/
782+
783+
if [ "$COPYLIBS" == "1" ]; then
784+
if [ -s "libs/$ARCH/copylibs" ]; then
785+
try sh -c "cat libs/$ARCH/copylibs | xargs -d'\n' cp -t private/"
786+
fi
787+
else
788+
try mv libs/$ARCH/libpymodules.so private/
789+
fi
767790
try cp python-install/include/python2.7/pyconfig.h private/include/python2.7/
768791

769792
debug "Reduce private directory from unwanted files"
@@ -790,7 +813,11 @@ function run_distribute() {
790813

791814
function run_biglink() {
792815
push_arm
793-
try $BIGLINK $LIBS_PATH/libpymodules.so $LIBLINK_PATH
816+
if [ "$COPYLIBS" == "0" ]; then
817+
try $BIGLINK $LIBS_PATH/libpymodules.so $LIBLINK_PATH
818+
else
819+
try $BIGLINK $LIBS_PATH/copylibs $LIBLINK_PATH
820+
fi
794821
pop_arm
795822
}
796823

@@ -832,11 +859,16 @@ function arm_deduplicate() {
832859

833860

834861
# Do the build
835-
while getopts ":hvlfxm:u:d:s" opt; do
862+
while getopts ":hCvlfxm:u:d:s" opt; do
836863
case $opt in
837864
h)
838865
usage
839866
;;
867+
C)
868+
COPYLIBS=1
869+
LIBLINK=${LIBLINK}-jb
870+
BIGLINK=${BIGLINK}-jb
871+
;;
840872
l)
841873
list_modules
842874
;;

src/tools/biglink-jb

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
#!/usr/bin/env python
2+
3+
from __future__ import print_function
4+
import os
5+
import sys
6+
import subprocess
7+
import re
8+
9+
re_needso = re.compile(r'^.*\(NEEDED\)\s+Shared library: \[lib(.*)\.so\]\s*$')
10+
11+
blacklist_libs = (
12+
'c',
13+
'stdc++',
14+
'dl',
15+
'python2.7',
16+
'sdl',
17+
'sdl_image',
18+
'sdl_ttf',
19+
'z',
20+
'm',
21+
'GLESv2',
22+
'jpeg',
23+
'png',
24+
'log',
25+
)
26+
27+
found_libs = []
28+
sofiles = [ ]
29+
30+
for directory in sys.argv[2:]:
31+
32+
for fn in os.listdir(directory):
33+
fn = os.path.join(directory, fn)
34+
35+
if not fn.endswith(".libs"):
36+
continue
37+
38+
dirfn = fn[:-1] + 'dirs'
39+
if not os.path.exists(dirfn):
40+
continue
41+
42+
with open(fn) as f:
43+
needed_libs = [lib for lib in {ln.strip() for ln in f} if lib not in blacklist_libs and lib not in found_libs]
44+
45+
while needed_libs:
46+
print('need libs:\n\t' + '\n\t'.join(needed_libs))
47+
48+
start_needed_libs = needed_libs[:]
49+
found_sofiles = []
50+
51+
with open(dirfn) as f:
52+
for libdir in f:
53+
if not needed_libs:
54+
break
55+
56+
libdir = libdir.strip()
57+
print('scanning %s' % libdir)
58+
for lib in needed_libs[:]:
59+
if lib in found_libs:
60+
continue
61+
62+
if lib.endswith('.a'):
63+
needed_libs.remove(lib)
64+
found_libs.append(lib)
65+
continue
66+
67+
lib_a = 'lib' + lib + '.a'
68+
libpath_a = os.path.join(libdir, lib_a)
69+
lib_so = 'lib' + lib + '.so'
70+
libpath_so = os.path.join(libdir, lib_so)
71+
plain_so = lib + '.so'
72+
plainpath_so = os.path.join(libdir, plain_so)
73+
74+
sopath = None
75+
if os.path.exists(libpath_so):
76+
sopath = libpath_so
77+
elif os.path.exists(plainpath_so):
78+
sopath = plainpath_so
79+
80+
if sopath:
81+
print('found %s in %s' % (lib, libdir))
82+
found_sofiles.append(sopath)
83+
needed_libs.remove(lib)
84+
found_libs.append(lib)
85+
continue
86+
87+
if os.path.exists(libpath_a):
88+
print('found %s (static) in %s' % (lib, libdir))
89+
needed_libs.remove(lib)
90+
found_libs.append(lib)
91+
continue
92+
93+
for sofile in found_sofiles:
94+
print('scanning dependencies for %s' % sofile)
95+
out = subprocess.check_output([os.environ['READELF'], '-d', sofile])
96+
for line in out.splitlines():
97+
needso = re_needso.match(line)
98+
if needso:
99+
lib = needso.group(1)
100+
if lib not in needed_libs and lib not in found_libs and lib not in blacklist_libs:
101+
needed_libs.append(needso.group(1))
102+
103+
sofiles += found_sofiles
104+
105+
if needed_libs == start_needed_libs:
106+
raise RuntimeError('Failed to locate needed libraries!\n\t' + '\n\t'.join(needed_libs))
107+
108+
output = sys.argv[1]
109+
110+
with open(output, 'w') as f:
111+
f.write('\n'.join(sofiles))

src/tools/liblink-jb

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#!/usr/bin/env python
2+
3+
from __future__ import print_function
4+
import sys
5+
import subprocess
6+
from os import environ
7+
from os.path import basename, join
8+
9+
libs = [ ]
10+
libdirs = [ ]
11+
output = None
12+
13+
14+
i = 1
15+
while i < len(sys.argv):
16+
opt = sys.argv[i]
17+
i += 1
18+
19+
if opt == "-o":
20+
output = sys.argv[i]
21+
i ++ 1
22+
continue
23+
24+
if opt.startswith("-l"):
25+
libs.append(opt[2:])
26+
continue
27+
28+
if opt.startswith("-L"):
29+
libdirs.append(opt[2:])
30+
continue
31+
32+
output = join(environ.get('LIBLINK_PATH'), basename(output))
33+
34+
with open(output + ".libs", "w") as f:
35+
f.write("\n".join(libs))
36+
37+
with open(output + ".libdirs", "w") as f:
38+
f.write("\n".join(libdirs))
39+
40+
41+
libargs = ' '.join(["'%s'" % arg for arg in sys.argv[1:]])
42+
cmd = '%s -shared %s %s' % (environ['CC'], environ['LDFLAGS'], libargs)
43+
sys.exit(subprocess.call(cmd, shell=True))

0 commit comments

Comments
 (0)