149

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?

sans
  • 2,159
  • 4
  • 20
  • 22

10 Answers10

207

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.

Tamás
  • 47,239
  • 12
  • 105
  • 124
  • Is there a way to export it so that it works with eclipse? I've added it to my .profile however then Eclipse is not able to launch gdb. (Note: Adding it to ld.so.conf works however) – Setheron Sep 24 '12 at 18:03
  • so I checked the environment variables eclipse is running with and it does have the proper LD_LIBRARY_PATH. I believe that when it launches GDB it doesn't use any shell and therefore doesn't get any environment variables! Setting the libpython in the debug configuration didn't help neither since that is only for when gdb actually loads (but i need the lib for gdb itself to load) – Setheron Sep 24 '12 at 21:45
  • 1
    Can you debug the application successfully when you run `gdb` from the command line and LD_LIBRARY_PATH is set up properly in the terminal? If not, you will probably have to set up LD_LIBRARY_PATH in your `.gdbinit` file. See this answer for more info: http://stackoverflow.com/a/7041845/156771 – Tamás Sep 25 '12 at 09:29
  • I need the LD_LIBRARY_PATH for launch gdb (python libs) not for the actual debugging of my application. So far I've only managed to fix it by setting it in ldconfig. I can debug the application via CLI because it'll pickup the LD_LIBRARY_PATH from my ZSHRC file however. – Setheron Sep 26 '12 at 21:14
  • 11
    Just a note for anyone trying this: It's just "/usr/local/lib", and not a starting "include" as the original "include ld.so.conf.d/*.conf". – timss Feb 18 '13 at 22:58
  • For someone who is not able to set LD_LIBRARY_PATH for apache this will help http://serverfault.com/questions/424997/how-to-set-ld-library-path-on-vps-red-hat-linux-to-be-visible-by-apache – zengr Oct 16 '14 at 20:21
  • "LD_LIBRARY_PATH=/usr/local/lib /usr/local/bin/python" gives: "bash: /usr/local/bin/python: No such file or directory". I'm on Ubuntu 14.04. – Jonathan Hartley Jan 07 '16 at 17:03
  • The original question is about a Python instance that is installed in `/usr/local`, hence I used that in my answer. If your Python is elsewhere, adjust the paths accordingly. – Tamás Jan 07 '16 at 20:46
  • Adding `export LD_LIBRARY_PATH=/usr/local/lib` to `/etc/profile` and sourcing (`source /etc/profile`) the profile solved my case. Thank you so much. – Phyticist Dec 12 '16 at 18:28
  • Executing ldconfig displays the error ldconfig: /usr/local/lib/libpython2.7.so.1.0 is not an ELF file - it has the wrong magic bytes at the start in step 2 – Arun Feb 03 '17 at 17:57
  • @Tamás I think a 3rd option to 'make changes permanent' is to include the paths you set in `LD_LIBRARY_PATH` as part of the `LDFLAGS` when configuring for `make` – ecoe Sep 06 '18 at 19:24
91

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

bli
  • 7,549
  • 7
  • 48
  • 94
Foosh
  • 1,195
  • 12
  • 16
  • // , This looks like what I'm looking for. Where can I find out more about ways to _"tar the python-version directory and land it anywhere and it will "work" (provided you don't run into libc or libm conflicts)"_? Do you think it's worth making a separate stackoverflow.com question out of this? – Nathan Basanese Sep 08 '15 at 21:50
  • // , Also, how should one set `$PYTHON_VERSION`? – Nathan Basanese Sep 08 '15 at 21:59
  • // , I set `$PYTHON_VERSION` after configuring. Even with the `$PYTHON_VERSION` set, though, the compiler complains about `Python build finished successfully! The necessary bits to build these optional modules were not found: _bz2 _curses _curses_panel _gdbm _lzma _sqlite3 _tkinter readline` – Nathan Basanese Sep 08 '15 at 22:47
  • // , Does this require any modifications to the `make` command and other installation commands? – Nathan Basanese Sep 08 '15 at 22:52
  • // , Also, what if your `Python` application needs system packages like `yum install python-lxml`? – Nathan Basanese Sep 09 '15 at 00:00
  • 1
    @NathanBasanese in the case of the missing bz2, curses, gdbm, lzma, etc you would need to compile each of those first with a prefix of `/apps/python-${PYTHON_VERSION}/extlib` to ensure their libraries and headers are in the proper location for the Python make process to find. As to system level packages, you'd probably be stuck relying on a root user to install those for you beforehand. Or finding an alternative that can be compiled and landed in the `extlib` – Foosh Oct 07 '15 at 20:48
  • When compiling pyhton3.6, I had to put both the `-Wl,--rpath=` and `-L` parts in the `LDFLAGS`. `-Wl,--rpath=` alone was not enough. I would be interested to know when and why `-L` might be required. – bli Feb 15 '18 at 11:55
  • @bil comes down to if you have all of the libraries you need on the host system already in default paths or if you have extra library paths you need to include – Foosh Feb 15 '18 at 22:34
22

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.

Omer Dagan
  • 14,868
  • 16
  • 44
  • 60
7

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.

Nagev
  • 10,835
  • 4
  • 58
  • 69
  • 1
    You could have saved yourself some trouble by going to /etc/profile.d and creating a file with the following in it: `#!/bin/bash` and `source scl_source enable rh-python35` in it. https://access.redhat.com/solutions/527703 – Doug Sep 26 '17 at 22:10
4

This worked for me...

$ sudo apt-get install python2.7-dev
Kyle Anderson
  • 1,820
  • 5
  • 21
  • 29
  • Hi this is not the correct solution, because after this, your custom build python binary is using the .so from the one you installed from apt-get. This may cause problems while they have same version, or if you modified the python source code, it will be not take efforts. – Azusa Nakano May 08 '18 at 08:08
4

On Solaris 11

Use LD_LIBRARY_PATH_64 to resolve symlink to python libs.

In my case for python3.6 LD_LIBRARY_PATH didn't work but LD_LIBRARY_PATH_64 did.

Hope this helps.
Regards

Roy Scheffers
  • 3,832
  • 11
  • 31
  • 36
basy
  • 41
  • 1
1

This answer would be helpful to those who have limited auth access on the server.

I had a similar problem for python3.5 in HostGator's shared hosting. Python3.5 had to be enabled every single damn time after login. Here are my 10 steps for resolution:

  1. Enable the python through scl script python_enable_3.5 or scl enable rh-python35 bash.

  2. Verify that it's enabled by executing python3.5 --version. This should give you your python version.

  3. Execute which python3.5 to get its path. In my case, it was /opt/rh/rh-python35/root/usr/bin/python3.5. You can use this path get the version again (just to verify that this path is working for you.)

  4. Awesome, now please exit out of current shell by scl.

  5. Now, lets get the version again through this complete python3.5 path /opt/rh/rh-python35/root/usr/bin/python3.5 --version.

    It won't give you the version but an error. In my case, it was

/opt/rh/rh-python35/root/usr/bin/python3.5: error while loading shared libraries: libpython3.5m.so.rh-python35-1.0: cannot open shared object file: No such file or directory
  1. As mentioned in Tamas' answer, we gotta find that so file. locate doesn't work in shared hosting and you can't install that too.

    Use the following command to find where that file is located:

find /opt/rh/rh-python35 -name "libpython3.5m.so.rh-python35-1.0"
  1. Above command would print the complete path (second line) of the file once located. In my case, output was
find: `/opt/rh/rh-python35/root/root': Permission denied
/opt/rh/rh-python35/root/usr/lib64/libpython3.5m.so.rh-python35-1.0
  1. Here is the complete command for the python3.5 to work in such shared hosting which would give the version,
LD_LIBRARY_PATH=/opt/rh/rh-python35/root/usr/lib64 /opt/rh/rh-python35/root/usr/bin/python3.5 --version
  1. Finally, for shorthand, append the following alias in your ~/.bashrc
alias python351='LD_LIBRARY_PATH=/opt/rh/rh-python35/root/usr/lib64 /opt/rh/rh-python35/root/usr/bin/python3.5'
  1. For verification, reload the .bashrc by source ~/.bashrc and execute python351 --version.

Well, there you go, now whenever you login again, you have got python351 to welcome you.

This is not just limited to python3.5, but can be helpful in case of other scl installed softwares.

sam
  • 931
  • 2
  • 13
  • 26
0

I installed using the command:

./configure --prefix=/usr       \
            --enable-shared     \
            --with-system-expat \
            --with-system-ffi   \
            --enable-unicode=ucs4 &&

make

Now, as the root user:

make install &&
chmod -v 755 /usr/lib/libpython2.7.so.1.0

Then I tried to execute python and got the error:

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

Then, I logged out from root user and again tried to execute the Python and it worked successfully.

Baris Demiray
  • 1,539
  • 24
  • 35
Pankaj
  • 615
  • 5
  • 9
0

All it needs is the installation of libpython [3 or 2] dev files installation.

-1

just install python-lib. (python27-lib). It will install libpython2.7.so1.0. We don't require to manually set anything.

chintan-p-bhatt
  • 111
  • 1
  • 10
  • 4
    // , And if you're on, say, CEntOS 6.3? This doesn't work, there, and usually people are compiling Python to deal with a case where the system Python is a weird version, broken, unreliable, or some other desire not to touch the overall system. – Nathan Basanese Sep 08 '15 at 21:51