fix builtin module conflict
Now all the cythonized modules are rewrite with a mangled name of package + module name. This avoid symbol conflict if you have the same module.so as another library (for example, audiostream.sources.thread and python thread.so was in conflict). Then, a custom builtin importer is loaded before the application start, and when you will want to import audiostream.sources.thread, if will import builtin audiostream_sources_thread. kivy/ios/lxml/audiostream recipes are impacted. A full rebuild is needed.
This commit is contained in:
parent
d539c90474
commit
92f38fe2d7
6 changed files with 94 additions and 4 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -4,6 +4,7 @@ Python-*
|
||||||
freetype-*
|
freetype-*
|
||||||
build/*
|
build/*
|
||||||
src/SDL/Xcode-iPhoneOS/SDL/build/
|
src/SDL/Xcode-iPhoneOS/SDL/build/
|
||||||
|
src/SDL/Xcode-iOS/SDL/build/
|
||||||
tmp/*
|
tmp/*
|
||||||
kivy/*
|
kivy/*
|
||||||
libtremor/*
|
libtremor/*
|
||||||
|
|
|
@ -13,10 +13,10 @@ export LDSHARED="$KIVYIOSROOT/tools/liblink"
|
||||||
|
|
||||||
try pushd $KIVYIOSROOT/src/ios
|
try pushd $KIVYIOSROOT/src/ios
|
||||||
HOSTPYTHON=$TMPROOT/Python-$PYTHON_VERSION/hostpython
|
HOSTPYTHON=$TMPROOT/Python-$PYTHON_VERSION/hostpython
|
||||||
try cython *.pyx
|
try $KIVYIOSROOT/tools/cythonize.py *.pyx
|
||||||
try $HOSTPYTHON setup.py build_ext
|
try $HOSTPYTHON setup.py build_ext
|
||||||
try $HOSTPYTHON setup.py install -O2 --root iosbuild
|
try $HOSTPYTHON setup.py install -O2 --root iosbuild
|
||||||
try find iosbuild | grep -E '*\.(py|pyc|so\.o|so\.a|so\.libs)$$' | xargs rm
|
try find iosbuild | grep -E '.*\.(py|pyc|so\.o|so\.a|so\.libs)$$' | xargs rm
|
||||||
try rm -rdf "$BUILDROOT/python/lib/python2.7/site-packages/ios*"
|
try rm -rdf "$BUILDROOT/python/lib/python2.7/site-packages/ios*"
|
||||||
try cp iosbuild/usr/local/lib/python2.7/site-packages/ios.so "$BUILDROOT/python/lib/python2.7/site-packages"
|
try cp iosbuild/usr/local/lib/python2.7/site-packages/ios.so "$BUILDROOT/python/lib/python2.7/site-packages"
|
||||||
popd
|
popd
|
||||||
|
|
|
@ -21,7 +21,27 @@ OLD_CFLAGS="$CFLAGS"
|
||||||
OLD_LDSHARED="$LDSHARED"
|
OLD_LDSHARED="$LDSHARED"
|
||||||
export LDSHARED="$KIVYIOSROOT/tools/liblink"
|
export LDSHARED="$KIVYIOSROOT/tools/liblink"
|
||||||
export CFLAGS="$ARM_CFLAGS"
|
export CFLAGS="$ARM_CFLAGS"
|
||||||
try make ios
|
|
||||||
|
ln -s $KIVYIOSROOT/Python-$PYTHON_VERSION/python
|
||||||
|
ln -s $KIVYIOSROOT/Python-$PYTHON_VERSION/python.exe
|
||||||
|
|
||||||
|
rm -rdf iosbuild/
|
||||||
|
try mkdir iosbuild
|
||||||
|
|
||||||
|
echo "First build ========================================"
|
||||||
|
HOSTPYTHON=$TMPROOT/Python-$PYTHON_VERSION/hostpython
|
||||||
|
$HOSTPYTHON setup.py build_ext -g
|
||||||
|
echo "cythoning =========================================="
|
||||||
|
find . -name *.pyx -exec $KIVYIOSROOT/tools/cythonize.py {} \;
|
||||||
|
echo "Second build ======================================="
|
||||||
|
$HOSTPYTHON setup.py build_ext -g
|
||||||
|
$HOSTPYTHON setup.py install -O2 --root iosbuild
|
||||||
|
# Strip away the large stuff
|
||||||
|
find iosbuild/ | grep -E '.*\.(py|pyc|so\.o|so\.a|so\.libs)$$' | xargs rm
|
||||||
|
rm -rdf "$BUILDROOT/python/lib/python2.7/site-packages/kivy"
|
||||||
|
# Copy to python for iOS installation
|
||||||
|
cp -R "iosbuild/usr/local/lib/python2.7/site-packages/kivy" "$BUILDROOT/python/lib/python2.7/site-packages"
|
||||||
|
|
||||||
export LDSHARED="$OLD_LDSHARED"
|
export LDSHARED="$OLD_LDSHARED"
|
||||||
export CFLAGS="$OLD_CFLAGS"
|
export CFLAGS="$OLD_CFLAGS"
|
||||||
popd
|
popd
|
||||||
|
|
|
@ -100,7 +100,7 @@ pushd $TMPROOT/lxml-$LXML_VERSION
|
||||||
HOSTPYTHON=$TMPROOT/Python-$PYTHON_VERSION/hostpython
|
HOSTPYTHON=$TMPROOT/Python-$PYTHON_VERSION/hostpython
|
||||||
XML2_CONFIG=$PREFIX/bin/xml2-config
|
XML2_CONFIG=$PREFIX/bin/xml2-config
|
||||||
XSLT_CONFIG=$PREFIX/bin/xslt-config
|
XSLT_CONFIG=$PREFIX/bin/xslt-config
|
||||||
find . -name *.pyx -exec cython -t {} \;
|
find . -name *.pyx -exec $KIVYIOSROOT/tools/cythonize.py -t {} \;
|
||||||
try $HOSTPYTHON setup.py build_ext
|
try $HOSTPYTHON setup.py build_ext
|
||||||
try $HOSTPYTHON setup.py install -O2 --root iosbuild
|
try $HOSTPYTHON setup.py install -O2 --root iosbuild
|
||||||
|
|
||||||
|
|
41
tools/cythonize.py
Executable file
41
tools/cythonize.py
Executable file
|
@ -0,0 +1,41 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
def do(fn):
|
||||||
|
print 'cythonize:', fn
|
||||||
|
parts = fn.split('/')
|
||||||
|
assert(parts[-1].endswith('.pyx'))
|
||||||
|
if parts[0] == '.':
|
||||||
|
parts.pop(0)
|
||||||
|
modname = parts[-1][:-4]
|
||||||
|
package = '_'.join(parts[:-1])
|
||||||
|
|
||||||
|
# cythonize
|
||||||
|
subprocess.Popen(['cython', fn]).communicate()
|
||||||
|
|
||||||
|
if not package:
|
||||||
|
print 'no need to rewrite', fn
|
||||||
|
else:
|
||||||
|
# get the .c, and change the initXXX
|
||||||
|
fn_c = fn[:-3] + 'c'
|
||||||
|
with open(fn_c) as fd:
|
||||||
|
data = fd.read()
|
||||||
|
pat1 = 'init{}(void)'.format(modname)
|
||||||
|
sub1 = 'init{}_{}(void)'.format(package, modname)
|
||||||
|
pat2 = 'PyInit_{}(void)'.format(modname)
|
||||||
|
sub2 = 'PyInit{}_{}(void)'.format(package, modname)
|
||||||
|
pat3 = 'Pyx_NAMESTR("{}")'.format(modname)
|
||||||
|
sub3 = 'Pyx_NAMESTR("{}_{}")'.format(package, modname)
|
||||||
|
data = data.replace(pat1, sub1)
|
||||||
|
data = data.replace(pat2, sub2)
|
||||||
|
data = data.replace(pat3, sub3)
|
||||||
|
|
||||||
|
print 'rewrite', fn_c
|
||||||
|
with open(fn_c, 'w') as fd:
|
||||||
|
fd.write(data)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
for fn in sys.argv[1:]:
|
||||||
|
do(fn)
|
|
@ -50,6 +50,9 @@ int main(int argc, char *argv[]) {
|
||||||
// If other modules are using thread, we need to initialize them before.
|
// If other modules are using thread, we need to initialize them before.
|
||||||
PyEval_InitThreads();
|
PyEval_InitThreads();
|
||||||
|
|
||||||
|
// Add an importer for builtin modules
|
||||||
|
load_custom_builtin_importer();
|
||||||
|
|
||||||
// Search and start main.py
|
// Search and start main.py
|
||||||
const char * prog = [
|
const char * prog = [
|
||||||
[[NSBundle mainBundle] pathForResource:@"YourApp/main" ofType:@"pyo"] cStringUsingEncoding:
|
[[NSBundle mainBundle] pathForResource:@"YourApp/main" ofType:@"pyo"] cStringUsingEncoding:
|
||||||
|
@ -94,3 +97,28 @@ void export_orientation() {
|
||||||
//NSLog(@"Available orientation: %@", result);
|
//NSLog(@"Available orientation: %@", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void load_custom_builtin_importer() {
|
||||||
|
static const char *custom_builtin_importer = \
|
||||||
|
"import sys, imp\n" \
|
||||||
|
"from os.path import exists, join\n" \
|
||||||
|
"class CustomBuiltinImporter(object):\n" \
|
||||||
|
" def find_module(self, fullname, mpath=None):\n" \
|
||||||
|
" if '.' not in fullname:\n" \
|
||||||
|
" return\n" \
|
||||||
|
" if mpath is None:\n" \
|
||||||
|
" return\n" \
|
||||||
|
" part = fullname.rsplit('.')[-1]\n" \
|
||||||
|
" fn = join(mpath[0], '{}.so'.format(part))\n" \
|
||||||
|
" if exists(fn):\n" \
|
||||||
|
" return self\n" \
|
||||||
|
" return\n" \
|
||||||
|
" def load_module(self, fullname):\n" \
|
||||||
|
" f = fullname.replace('.', '_')\n" \
|
||||||
|
" mod = sys.modules.get(f)\n" \
|
||||||
|
" if mod is None:\n" \
|
||||||
|
" mod = imp.load_dynamic(f, f)\n" \
|
||||||
|
" return mod\n" \
|
||||||
|
" return mod\n" \
|
||||||
|
"sys.meta_path.append(RewriteImporter())";
|
||||||
|
PyRun_SimpleString(custom_builtin_importer);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue