Search code examples
pythonlinuxpython-2.7ubuntulinux-mint

Manually built python 2.7.10 on GNU/Linux loads .so of old python2.7.6 installed from packages


I've successfully built from sources and installed python version 2.7.10 into folder /usr/local. And then I have executed /usr/local/bin/python and it has shown that it has version 2.7.6. Which is not correct. Trying to find out what is wrong, I've run ldd /usr/local/bin/python and got the following:

    linux-vdso.so.1 =>  (0x00007fffd5fe4000)
    libpython2.7.so.1.0 => /usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0 (0x00007f2c006f8000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f2c004da000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2c00115000)
    libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f2bffefc000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f2bffcf8000)
    libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007f2bffaf5000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f2bff7ef000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f2c00c5c000)

Which means that manually built python 2.7.10 loads *.so library of python 2.7.6, which was installed by default package manager. Could you help to find out why this happens?

Configuring have been done by the following commands:

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

I am using Linux Mint 17.2 Rafaela KDE edition, which is based on Ubuntu 14.04.3


Solution

  • The reason of that is the algorithm linux uses to select the shared object to load. This procedure allows several versions of the same library to coexist without problem in the same system. Sometimes, something has to be touched first to force it to select an alternative, as now for you.

    I'll explain first the algorithm and then the solution in your case:

    First linux has a binary database indexed by soname(this is a name the dynamic linker uses to select the proper library version) It enters with the so called soname in the library (embedded in the application when it was linked) and gets a file (normally the filename is /usr/lib/soname) the database is constructed by searching a directory list (configured in /etc/ld.so.conf) for all libraries, extracting their sonames, and indexing from soname to actual file. For it to work quickly, libraries have a symbolic link to the soname, and this is the reason you link to the wrong library, the link points to the old version.

    The rest is easy. You'll find a library, for example /usr/lib/libfoo.so.1 (in this case the soname is libfoo.so.1) that has two versions, /usr/lib/libfoo.so.1.3 and /usr/lib/libfoo.so.1.4, and a symbolic link /usr/lib/libfoo.so.1 -> /usr/lib/libfoo.so.1.3. You have to remove this link and construct the right one.

    rm -f /usr/lib/libfoo.so.1
    ln -s libfoo.so.1.3 /usr/lib/libfoo.so.1
    

    After that, it would be nice to reconstruct (I think it's not necessary, as you have it installed, but doesn't hurt) the database with

    /sbin/ldconfig
    

    If you run it with -l it will show you all the shared libs it has in the database. Try ldconfig(8).