find_library is failed to get the sndfile
This issues has observed while importing soundfile module at arm64 target. target runs on Python 3.7.4.
Soundfile.py is unable to get the sndfile but the same /usr/lib/libsndfile.so
linux$ python3 test_imports/test_audio.py
Traceback (most recent call last):
File "test_imports/test_audio.py", line 5, in
So, I tried ctype.CDLL instead of find_library -- _libname = _find_library('sndfile') ++ _libname = ctypes.CDLL('libsndfile.so') ++ print('Library: %s' % _libname)
But it is failing to open the _libname
linux$ python3 test_imports/test_audio.py
Library: <CDLL 'libsndfile.so', handle 3a832320 at 0x7f97cf0b50>
Traceback (most recent call last):
File "test_imports/test_audio.py", line 5, in
Any proper fix for this?
Jagan.
Is libsndfile installed?
@bastibe Yes, it is there in /usr/lib/libsndfile.so
As you found out yourself, _find_library is ctypes.find_library, which is part of Python proper.
So you'll have to figure out why Python can't locate your /usr/lib/libsndfile.so. Perhaps it's missing from some runtime path or library search path, or perhaps Python was compiled with some missing definitions, or for an incompatible runtime or something like that.
You can probably LD_PRELOAD it manually if need be, but that's not fixing the underlying problem.
@bastibe I have a buildroot environment, as per as compilation is concern I did a clean build to make sure nothing missed in-terms of dependencies.
I don't have any LD_LIBRARY_PATH on my shell env, since the systems is pretty much a rootfs rather than a distro.
As a first step, try LD_PRELOADing libsndfile.so and see whether that fixes your issue. If that works, you know your libsndfile is compatible and works as intended. Then you can figure out why Python isn't finding it.
@bastibe not sure I have used it properly, would you please check the below syntax and correct me If I'm wrong.
linux$ car test.py
import soundfile
linux$ LD_PRELOAD=/usr/lib/libsndfile.so python3 test.py
Traceback (most recent call last):
File "test.py", line 1, in
linux$ LD_PRELOAD=/usr/lib/libsndfile.so python3 -c "import soundfile"
Traceback (most recent call last):
File "
That looks correct.
I'd say that either your libsndfile is somehow incompatible with your Python (different compiler, different glibc, or something like that), or your Python installation is somehow misconfigured.
I'd recommend playing around with ctypes.find_library, and see if you can make it find your libsndfile somehow. Perhaps by passing the full path to it, or "libsndfile" instead of "sndfile". Perhaps by copying the libsndfile to a different location. Usually, it should pick up these differences on its own, but on a non-standard platform, you never know.
I've had to deal with issues like this in a different project. Perhaps the following function can help: https://github.com/bastibe/transplant/blob/master/transplant/transplant_master.py#L654
I know it sound improper, but I can went through by explicitly mention the path like below. --- a/soundfile.py +++ b/soundfile.py @@ -13,7 +13,7 @@ version = "0.10.3" import os as _os import sys as _sys from os import SEEK_SET, SEEK_CUR, SEEK_END --from ctypes.util import find_library as _find_library ++from ctypes import cdll from _soundfile import ffi as _ffi
try: @@ -137,10 +137,10 @@ _ffi_types = { }
try: -- _libname = _find_library('sndfile') ++ _libname = cdll.LoadLibrary('libsndfile.so') if _libname is None: raise OSError('sndfile library not found') -- _snd = _ffi.dlopen(_libname) ++ _snd = _ffi.dlopen("/usr/lib/libsndfile.so") except OSError: if _sys.platform == 'darwin': _libname = 'libsndfile.dylib'
I tried to find the way to get the libsndfile.so in the system via some os.path.abspath or similar but none can give the desired path of libsndfile.so. @bastibe any clue on this might help to get through this work around atleast for now. thanks!
Does the _ffi.dlopen('/usr/lib/libsndfile.so') work?
If so, you'll have to either
- figure out what is misconfigured in your system that prevents
ctypes.util.find_libraryfrom finding libraries in /usr/lib/, or - live with your workaround.
If not, the library is probably incompatible in some way and can't be loaded. Then you'll have to figure out how they differ, or how to get compatible versions of Python and the library.
Weirdly yes! _ffi.dlopen('/usr/lib/libsndfile.so') seems to work in a buildroot embedded image with python 3.9 and libsndfile.
So, in a kind've wild turn of events, this appears to be a bug in python, that at least pyusb solved with a custom load override. I recently ran into this while making a Rhasspy satellite image in Buildroot, and started looking around. Apparently it's an issue with buildroot not having a library finding mechanism that python can use for find_library.
For now I'm planning on using a slightly modified soundfile.py. I know this is a really niche subset of folks using python-soundfile on embedded systems, so I'm just letting you know mostly for awareness (and for anyone else who comes across this) as testing something like this on a real system is not easy.
Thanks for the work on python-soundfile btw - it's used in a lot of places far and wide!
Thank you!
If you'd like, I'd be grateful for an addition to the README, perhaps under the Known Issues header, to help other users who might be experiencing the same issue.
Yeah, I can make that happen!