sys.path is only searched for Python modules. For dynamic linked libraries, the paths searched must be in LD_LIBRARY_PATH. Check if your LD_LIBRARY_PATH includes /usr/local/lib, and if it doesn't, add it and try again.
Some more information (source):
In Linux, the environment variable LD_LIBRARY_PATH is a colon-separated set of directories where libraries should be searched for first, before the standard set of directories; this is useful when debugging a new library or using a nonstandard library for special purposes. The environment variable LD_PRELOAD lists shared libraries with functions that override the standard set, just as /etc/ld.so.preload does. These are implemented by the loader /lib/ld-linux.so. I should note that, while LD_LIBRARY_PATH works on many Unix-like systems, it doesn't work on all; for example, this functionality is available on HP-UX but as the environment variable SHLIB_PATH, and on AIX this functionality is through the variable LIBPATH (with the same syntax, a colon-separated list).
To set LD_LIBRARY_PATH, use one of the following, ideally in your ~/.bashrc
or equivalent file:
export LD_LIBRARY_PATH=/usr/local/lib
or
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
Use the first form if it's empty (equivalent to the empty string, or not present at all), and the second form if it isn't. Note the use of export.
Answer from Vinay Sajip on Stack Overflowsys.path is only searched for Python modules. For dynamic linked libraries, the paths searched must be in LD_LIBRARY_PATH. Check if your LD_LIBRARY_PATH includes /usr/local/lib, and if it doesn't, add it and try again.
Some more information (source):
In Linux, the environment variable LD_LIBRARY_PATH is a colon-separated set of directories where libraries should be searched for first, before the standard set of directories; this is useful when debugging a new library or using a nonstandard library for special purposes. The environment variable LD_PRELOAD lists shared libraries with functions that override the standard set, just as /etc/ld.so.preload does. These are implemented by the loader /lib/ld-linux.so. I should note that, while LD_LIBRARY_PATH works on many Unix-like systems, it doesn't work on all; for example, this functionality is available on HP-UX but as the environment variable SHLIB_PATH, and on AIX this functionality is through the variable LIBPATH (with the same syntax, a colon-separated list).
To set LD_LIBRARY_PATH, use one of the following, ideally in your ~/.bashrc
or equivalent file:
export LD_LIBRARY_PATH=/usr/local/lib
or
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
Use the first form if it's empty (equivalent to the empty string, or not present at all), and the second form if it isn't. Note the use of export.
Ensure your libcurl.so module is in the system library path, which is distinct and separate from the python library path.
A "quick fix" is to add this path to a LD_LIBRARY_PATH variable. However, setting that system wide (or even account wide) is a BAD IDEA, as it is possible to set it in such a way that some programs will find a library it shouldn't, or even worse, open up security holes.
If your "locally installed libraries" are installed in, for example, /usr/local/lib, add this directory to /etc/ld.so.conf (it's a text file) and run ldconfig
The command will run a caching utility, but will also create all the necessary "symbolic links" required for the loader system to function. It is surprising that the make install for libcurl did not do this already, but it's possible it could not if /usr/local/lib is not in /etc/ld.so.conf already.
PS: it's possible that your /etc/ld.so.conf contains nothing but include ld.so.conf.d/*.conf. You can still add a directory path after it, or just create a new file inside the directory it's being included from. Dont forget to run ldconfig after it.
Be careful. Getting this wrong can screw up your system.
Additionally: make sure your python module is compiled against THAT version of libcurl. If you just copied some files over from another system, this wont always work. If in doubt, compile your modules on the system you intend to run them on.
Python ImportError: libstdc++.so.6: cannot open shared object file: No such file or directory
python 2.x - cannot open shared object file: No such file or directory - Raspberry Pi Stack Exchange
python - OSError: cannot open shared object file: No such file or directory even though file is in the folder - Stack Overflow
python - ImportError: libxxx: cannot open shared object file: No such file or directory - Stack Overflow
hi all, i'm trying to figure out what's wrong with the code for pytest ...
would appreciate your help (it seems adding the name of a string into the path..unknown why..
hereby the code
import sys
import pytest
import platform
from pathlib import Path
sys.path.append(r"./")
from mvpy_rest_server import NucRestRunner # noqa
import MvxGraph # noqa
DEFAULT_LIB_PATH = r"libc"
DEFAULT_MEMPOOL = 1000
MAX_STR = 256
DEFAULT_PORT = "7500"
current_dir = ""
@pytest.fixture
def nuc_rest_runner(pytestconfig):
global current_dir
current_dir = lib = pytestconfig.getoption("lib")
if not lib:
current_dir = lib = DEFAULT_LIB_PATH
return NucRestRunner(lib, DEFAULT_MEMPOOL, DEFAULT_PORT)
@pytest.fixture()
def client(nuc_rest_runner):
return nuc_rest_runner.app.test_client()hereby the error:
ERROR tests/test_mvpy_rest_server.py::test_nuc_rest_runner_init - ValueError: ('Failed to init MvxGraphCore, due to exception:', OSError('libc/libMvxGraphCore.so: cannot open shared object file: No such file or directory'))
now the files are there .
the current path for the file:
"libc/MvxGraphCore"
, but if u an see it adds the name "lib" into the path 'libc**/lib**
and i can't figure out why.
Change your code so that you print os.environ right before that exception occurs. That way you will see whether the Python process has the correct environment set or not. The other obvious thing to check are whether your Python process has sufficient permission to open and read libyaafe-python.so. Note that sudo by default limits the environment of the invoked command, for security reasons (see here, for instance).
I know this post is old, but if you cannot modify (or do not want to modify) LD_LIBRARY_PATH and you still need a way to load the shared object into memory in Python, then you can use this general approach.
import ctypes
ctypes.CDLL('/usr/local/lib/library.version.so', mode=ctypes.RTLD_GLOBAL)
For you, the call might look like:
import ctypes
ctypes.CDLL('/usr/local/lib/libyaafe-python.so', mode=ctypes.RTLD_GLOBAL)
And if you don't know the path beforehand, I've put together the following function that can recursively search a set of library paths for a specified library name (and version). Hope this helps!
# Given a library name, try to locate the library and load it in
# global mode as a CDLL so that it is accessible to all code.
def load_library(libname, version=None, paths=("/usr/lib","/usr/local/lib",),
extensions=(".so",), prefixes=("","lib",),
recursive=True):
import os, ctypes
# This code will find all possible matches for the library,
# and pick the first lexicographically.
versions = set()
for directory in paths:
# Enumerate all files at that path (depending on "resursive" option).
if recursive:
file_paths = sum((
[os.path.join(dirpath, f) for f in filenames]
for (dirpath, dirnames, filenames) in os.walk(directory)
), [])
else:
file_paths = [
os.path.join(directory,f) for f in os.listdir(directory)
if not os.path.isdir(f)
]
# Iterate over the files looking for the specified library.
for path in file_paths:
filename = os.path.basename(path)
# Verify the file extension is allowed.
ext = filename[len(filename)-filename[::-1].find('.')-1:]
# Examples of the value for 'ext' given a 'filename':
# "foo.bar" -> ".bar", "foobar" -> ""
if (ext not in extensions): continue
# Check that the library name is in file name.
if (libname not in filename): continue
# Check that the version is in the name (if it is specified).
file_version = ".".join(filename.split('.')[1:-1])
if ((version is not None) and (version != file_version)): continue
# Extract the file name and check for matches against prefixes.
name = filename[:(filename+'.').find('.')]
for p in prefixes:
if (p+libname == name): break
else: continue
# Now this filename matches the required:
# name preceding the first ".",
# file extension including last ".",
# version between first and last "." if that was specified,
# and it exists in one of the provided paths.
versions.add(path)
# Uncomment the following line to see the considered libraries.
# print([path, filename, name, file_version, ext, os.path.islink(path)])
# Raise an error if no versions could be found.
if (len(versions) == 0):
raise(FileNotFoundError(f"No library file found for '{libname}'{'' if version is None else ' version '+version}."))
# Get the library path as the first element of the set of discovered versions.
library_path = sorted(versions)[0]
# Load the library globally (so it is accessible to later codes) and return its path.
ctypes.CDLL(library_path, mode=ctypes.RTLD_GLOBAL)
return library_path
And for your specific example the call to the function would look like:
load_library("yaafe-python")
As long as you called this before importing whatever module was failing to load, everything should work.
WARNINGS
- This is written for POSIX systems (Ubuntu, macOS, ...)
- This loads the library into the global C namespace, so I am not sure how it will handle duplicate declarations if something already exists and it might cause unexpected downstream consequences if a loaded library is overwritten.
From ldd, it is clear that prime is a 32bit/i386 build. It requires dependencies from same architecture. We may confirm too using:
file ./prime
We search for each missing library file using apt-file (if installed, be aware it downloads large indexes) or https://packages.ubuntu.com for corresponding package then install it.
sudo apt install libsigsegv2:i386 \
libsdl1.2debian:i386 libsdl-image1.2:i386 liblua5.1-0:i386 \
libsdl-mixer1.2:i386 libsdl-net1.2:i386
For a so called 64-bit application prime needs a bunch i386 libaries. sudo dpkg --add-architecture i386 afterwards sudo apt update
Make sure the not founding libaries are installed for 64-bit and 32-bit.
You can found the relevant packages with apt-file search missing file.
maybe you have to install it sudo apt install apt-file and sudo apt-file update

How to use apt-file
Add the following lines to your Dockerfile:
CopyRUN apt-get update && apt-get install ffmpeg libsm6 libxext6 -y
These commands install the cv2 dependencies that are normally present on the local machine, but might be missing in your Docker container causing the issue.
[minor update on 20 Jan 2022: as Docker recommends, never put RUN apt-get update alone, causing cache issue]
Even though the above solutions work. But their package sizes are quite big.
libGL.so.1 is provided by package libgl1. So the following code is sufficient.
Copyapt-get update && apt-get install libgl1
Try adding the python3.4's lib path to the $LD_LIBRARY_PATH environment variable.
First find out the lib path of python3.4 (depends on how you installed python3.4)
For me it was: /opt/python361/lib, then add it to environment variable like so:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/python361/lib
P.S.
I came across a similar problem while using virtualenv with python3.6, and I fixed it like so:
- First, append
include <lib path of python3.x>to/etc/ld.so.conf(Something like:include /opt/python361/liborinclude /usr/local/lib) - Then, activate the new configuration by running
sudo /sbin/ldconfig -v.
Another way is adding LDFLAGS="-Wl,-rpath /usr/local/lib" in configure, for example
./configure --prefix=/usr/local --enable-shared LDFLAGS="-Wl,-rpath /usr/local/lib"
/usr/local/lib is the path where libpython3.*.so files are in
Try to find file libpython2.7.so.1.0:
locate libpython2.7.so.1.0
In my case, it show out put:
/opt/rh/python27/root/usr/lib64/libpython2.7.so.1.0
Then paste line /opt/rh/python27/root/usr/lib64 to file /etc/ld.so.conf
And run ldconfig.
It solved my problem. Goodluck!
For some reason these two have worked perfectly for me:
apt-get install libpython2.7
sudo apt-get install libatlas3-base
I found them here and here
This fixed the problem by having it as the first two lines of the script:
!pip install opencv-python
!apt update && apt install -y libsm6 libxext6
!apt-get install -y libxrender-dev
You need to add sudo . I did the following to get it installed :
sudo apt-get install libsm6 libxrender1 libfontconfig1
and then did that (optional! maybe you won't need it)
sudo python3 -m pip install opencv-contrib-python
FINALLY got it done !