Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

find_library is failed to get the sndfile #258

Open
openedev opened this issue Feb 15, 2020 · 12 comments
Open

find_library is failed to get the sndfile #258

openedev opened this issue Feb 15, 2020 · 12 comments

Comments

@openedev
Copy link

openedev commented Feb 15, 2020

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
import soundfile
File "usr/lib/python3.7/site-packages/soundfile.py", line 142, in
OSError: sndfile library not found

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
import soundfile
File "usr/lib/python3.7/site-packages/soundfile.py", line 147, in
TypeError: load_library() argument 1 must be str, bytes or bytearray, not CDLL

Any proper fix for this?

Jagan.

@bastibe
Copy link
Owner

bastibe commented Feb 17, 2020

Is libsndfile installed?

@openedev
Copy link
Author

@bastibe
Yes, it is there in /usr/lib/libsndfile.so

@bastibe
Copy link
Owner

bastibe commented Feb 17, 2020

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.

@openedev
Copy link
Author

@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.

@bastibe
Copy link
Owner

bastibe commented Feb 18, 2020

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.

@openedev
Copy link
Author

@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
import soundfile
File "/usr/lib/python3.7/site-packages/soundfile.py", line 142, in
raise OSError('sndfile library not found')
OSError: sndfile library not found

linux$ LD_PRELOAD=/usr/lib/libsndfile.so python3 -c "import soundfile"
Traceback (most recent call last):
File "", line 1, in
File "/usr/lib/python3.7/site-packages/soundfile.py", line 142, in
raise OSError('sndfile library not found')
OSError: sndfile library not found

@bastibe
Copy link
Owner

bastibe commented Feb 18, 2020

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

@openedev
Copy link
Author

openedev commented Feb 19, 2020

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!

@bastibe
Copy link
Owner

bastibe commented Feb 19, 2020

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_library from 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.

@JarvyJ
Copy link
Contributor

JarvyJ commented Oct 22, 2021

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!

@bastibe
Copy link
Owner

bastibe commented Oct 22, 2021

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.

@JarvyJ
Copy link
Contributor

JarvyJ commented Oct 25, 2021

Yeah, I can make that happen!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants