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

Solution 1:

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.

Solution 2:

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.

Solution 3:

You can also set LD_RUN_PATH to /usr/local/lib in your user environment when you compile pycurl in the first place. This will embed /usr/local/lib in the RPATH attribute of the C extension module .so so that it automatically knows where to find the library at run time without having to have LD_LIBRARY_PATH set at run time.