Python executable not finding libpython shared library

I am installing Python 2.7 on CentOS 5. I built and installed Python as follows

./configure --enable-shared --prefix=/usr/local
make
make install

When I try to run /usr/local/bin/python, I get this error message

/usr/local/bin/python: error while loading shared libraries: libpython2.7.so.1.0: cannot open shared object file: No such file or directory

When I run ldd on /usr/local/bin/python, I get

ldd /usr/local/bin/python
    libpython2.7.so.1.0 => not found
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00000030e9a00000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00000030e9200000)
    libutil.so.1 => /lib64/libutil.so.1 (0x00000030fa200000)
    libm.so.6 => /lib64/libm.so.6 (0x00000030e9600000)
    libc.so.6 => /lib64/libc.so.6 (0x00000030e8e00000)
    /lib64/ld-linux-x86-64.so.2 (0x00000030e8a00000)

How do I tell Python where to find libpython?


Try the following:

LD_LIBRARY_PATH=/usr/local/lib /usr/local/bin/python

Replace /usr/local/lib with the folder where you have installed libpython2.7.so.1.0 if it is not in /usr/local/lib.

If this works and you want to make the changes permanent, you have two options:

  1. Add export LD_LIBRARY_PATH=/usr/local/lib to your .profile in your home directory (this works only if you are using a shell which loads this file when a new shell instance is started). This setting will affect your user only.

  2. Add /usr/local/lib to /etc/ld.so.conf and run ldconfig. This is a system-wide setting of course.


Putting on my gravedigger hat...

The best way I've found to address this is at compile time. Since you're the one setting prefix anyway might as well tell the executable explicitly where to find its shared libraries. Unlike OpenSSL and other software packages, Python doesn't give you nice configure directives to handle alternate library paths (not everyone is root you know...) In the simplest case all you need is the following:

./configure --enable-shared \
            --prefix=/usr/local \
            LDFLAGS="-Wl,--rpath=/usr/local/lib"

Or if you prefer the non-linux version:

./configure --enable-shared \
            --prefix=/usr/local \
            LDFLAGS="-R/usr/local/lib"

The "rpath" flag tells python it has runtime libraries it needs in that particular path. You can take this idea further to handle dependencies installed to a different location than the standard system locations. For example, on my systems since I don't have root access and need to make almost completely self-contained Python installs, my configure line looks like this:

./configure --enable-shared \
            --with-system-ffi \
            --with-system-expat \
            --enable-unicode=ucs4 \
            --prefix=/apps/python-${PYTHON_VERSION} \
            LDFLAGS="-L/apps/python-${PYTHON_VERSION}/extlib/lib -Wl,--rpath=/apps/python-${PYTHON_VERSION}/lib -Wl,--rpath=/apps/python-${PYTHON_VERSION}/extlib/lib" \
            CPPFLAGS="-I/apps/python-${PYTHON_VERSION}/extlib/include"

In this case I am compiling the libraries that python uses (like ffi, readline, etc) into an extlib directory within the python directory tree itself. This way I can tar the python-${PYTHON_VERSION} directory and land it anywhere and it will "work" (provided you don't run into libc or libm conflicts). This also helps when trying to run multiple versions of Python on the same box, as you don't need to keep changing your LD_LIBRARY_PATH or worry about picking up the wrong version of the Python library.

Edit: Forgot to mention, the compile will complain if you don't set the PYTHONPATH environment variable to what you use as your prefix and fail to compile some modules, e.g., to extend the above example, set the PYTHONPATH to the prefix used in the above example with export PYTHONPATH=/apps/python-${PYTHON_VERSION}...


I had the same problem and I solved it this way:

If you know where libpython resides at, I supposed it would be /usr/local/lib/libpython2.7.so.1.0 in your case, you can just create a symbolic link to it:

sudo ln -s /usr/local/lib/libpython2.7.so.1.0 /usr/lib/libpython2.7.so.1.0

Then try running ldd again and see if it worked.


I installed Python 3.5 by Software Collections on CentOS 7 minimal. It all worked fine on its own, but I saw the shared library error mentioned in this question when I tried running a simple CGI script:

tail /var/log/httpd/error_log
AH01215: /opt/rh/rh-python35/root/usr/bin/python: error while loading shared libraries: libpython3.5m.so.rh-python35-1.0: cannot open shared object file: No such file or directory

I wanted a systemwide permanent solution that works for all users, so that excluded adding export statements to .profile or .bashrc files. There is a one-line solution, based on the Red Hat solutions page. Thanks for the comment that points it out:

echo 'source scl_source enable rh-python35' | sudo tee --append /etc/profile.d/python35.sh

After a restart, it's all good on the shell, but sometimes my web server still complains. There's another approach that always worked for both the shell and the server, and is more generic. I saw the solution here and then realized it's actually mentioned in one of the answers here as well! Anyway, on CentOS 7, these are the steps:

 vim /etc/ld.so.conf

Which on my machine just had:

include ld.so.conf.d/*.conf

So I created a new file:

vim /etc/ld.so.conf.d/rh-python35.conf

And added:

/opt/rh/rh-python35/root/usr/lib64/

And to manually rebuild the cache:

sudo ldconfig

That's it, scripts work fine!

This was a temporary solution, which didn't work across reboots:

sudo ldconfig /opt/rh/rh-python35/root/usr/lib64/ -v

The -v (verbose) option was just to see what was going on. I saw that it did: /opt/rh/rh-python35/root/usr/lib64: libpython3.so.rh-python35 -> libpython3.so.rh-python35 libpython3.5m.so.rh-python35-1.0 -> libpython3.5m.so.rh-python35-1.0

This particular error went away. Incidentally, I had to chown the user to apache to get rid of a permission error after that.

Note that I used find to locate the directory for the library. You could also do:

sudo yum install mlocate
sudo updatedb
locate libpython3.5m.so.rh-python35-1.0

Which on my VM returns:

/opt/rh/rh-python35/root/usr/lib64/libpython3.5m.so.rh-python35-1.0

Which is the path I need to give to ldconfig, as shown above.