buildozer + Cython + C++ library: dlopen failed: cannot locate symbol symbol-name referenced by module.so

1

phase_engine.so tries to use _ZTINSt6__ndk18ios_base7failureE and can't find it:

11-08 19:59:00.629 25777 25823 I python  :  Traceback (most recent call last):
11-08 19:59:00.629 25777 25823 I python  :    File "/home/sonoflilit/phase/phase/.buildozer/android/app/main.py", line 14, in <module>
11-08 19:59:00.629 25777 25823 I python  :  ImportError: dlopen failed: cannot locate symbol "_ZTINSt6__ndk18ios_base7failureE" referenced by "/data/data/il.co.loris.phase/files/app/_python_bundle/site-packages/phase_engine.so"...
11-08 19:59:00.630 25777 25823 I python  : Python for android ended.

It exists in libc++_shared.so:

apk$ readelf -s --wide lib/armeabi-v7a/libc++_shared.so | grep _ZTINSt6__ndk18ios_base7failureE
   690: 000885c0    12 OBJECT  GLOBAL DEFAULT   17 _ZTINSt6__ndk18ios_base7failureE

Which is not dynamically linked by phase_engine.so

apk/assets$ readelf -a _python_bundle/site-packages/phase_engine.so | grep lib
 0x00000001 (NEEDED)                     Shared library: [libpython3.8m.so]
 0x00000001 (NEEDED)                     Shared library: [libdl.so]
 0x00000001 (NEEDED)                     Shared library: [libc.so]
  000000: Rev: 1  Flags: BASE  Index: 1  Cnt: 1  Name: build/lib.linux-x86_64-3.8/phase_engine.cpython-38-x86_64-linux-gnu.so
  000000: Version: 1  File: libc.so  Cnt: 1
  0x0020: Version: 1  File: libdl.so  Cnt: 1

Despite me asking nicely with libraries = ['c++'], in setup.py (which definitely runs):

from setuptools import setup, Extension
from Cython.Build import cythonize

setup(
    name = 'phase-engine',
    version = '0.1',
    ext_modules = cythonize([Extension("phase_engine",
        ["phase_engine.pyx"] + ['music-synthesizer-for-android/src/' + p for p in [
            ..., 'synth_unit.cc'
        ]],
        include_path = ['music-synthesizer-for-android/src/'],
        language = 'c++',
        libraries = ['c++'],
    )])
)

What am I doing wrong?

c++
cython
buildozer
python-for-android
asked on Stack Overflow Nov 9, 2020 by Aur Saraf

1 Answer

0

First of all, that c++ should of course be c++_shared, because the library is called libc++_shared.so.

Second, I couldn't get it to work with setup.py, but it's easy to just add compiler flags to the environment through the recipe and that's how the numpy recipe does it:

class MyRecipe(IncludedFilesBehaviour, CppCompiledComponentsPythonRecipe):
    version = 'stable'
    src_filename = "../../../phase-engine"
    name = 'phase-engine'

    depends = ['setuptools']

    call_hostpython_via_targetpython = False
    install_in_hostpython = True

    def get_recipe_env(self, arch):
        env = super().get_recipe_env(arch)
        env['LDFLAGS'] += ' -lc++_shared'
        return env

recipe = MyRecipe()
answered on Stack Overflow Nov 9, 2020 by Aur Saraf

User contributions licensed under CC BY-SA 3.0