Why can't Python find shared objects that are in directories in sys.path?

user135171 picture user135171 · Jul 8, 2009 · Viewed 201.6k times · Source

I'm trying to import pycurl:

$ python -c "import pycurl"
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: libcurl.so.4: cannot open shared object file: No such file or directory

Now, libcurl.so.4 is in /usr/local/lib. As you can see, this is in sys.path:

$ python -c "import sys; print(sys.path)"
['', '/usr/local/lib/python2.5/site-packages/setuptools-0.6c9-py2.5.egg', 
'/usr/local/lib/python25.zip', '/usr/local/lib/python2.5', 
'/usr/local/lib/python2.5/plat-linux2', '/usr/local/lib/python2.5/lib-tk', 
'/usr/local/lib/python2.5/lib-dynload', 
'/usr/local/lib/python2.5/sitepackages', '/usr/local/lib', 
'/usr/local/lib/python2.5/site-packages']

Any help will be greatly appreciated.

Answer

Vinay Sajip picture Vinay Sajip · Jul 8, 2009

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

Update: 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.