Plik wykonywalny Pythona nie znajduje udostępnionej biblioteki libpython

143

Instaluję Python 2.7 na CentOS 5. Skompilowałem i zainstalowałem Pythona w następujący sposób

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

Kiedy próbuję uruchomić / usr / local / bin / python, pojawia się ten komunikat o błędzie

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

Kiedy uruchamiam ldd na / usr / local / bin / python, otrzymuję

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)

Jak powiedzieć Pythonowi, gdzie znaleźć libpython?

sans
źródło

Odpowiedzi:

203

Spróbuj wykonać następujące czynności:

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

Zastąp katalogiem, /usr/local/libw którym został zainstalowany, libpython2.7.so.1.0jeśli go nie ma /usr/local/lib.

Jeśli to zadziała i chcesz, aby zmiany były trwałe, masz dwie możliwości:

  1. Dodaj export LD_LIBRARY_PATH=/usr/local/libdo swojego .profilekatalogu domowego (działa to tylko wtedy, gdy używasz powłoki, która ładuje ten plik, gdy uruchamiana jest nowa instancja powłoki). To ustawienie będzie miało wpływ tylko na Twojego użytkownika.

  2. Dodaj /usr/local/libdo /etc/ld.so.confi uruchomić ldconfig. Jest to oczywiście ustawienie obejmujące cały system.

Tamás
źródło
Czy istnieje sposób na wyeksportowanie go, aby działał z zaćmieniem? Dodałem go do mojego .profile, ale wtedy Eclipse nie może uruchomić gdb. (Uwaga: dodanie go do ld.so.conf działa jednak)
Setheron,
więc sprawdziłem zmienne środowiskowe, z którymi działa eclipse i ma odpowiednią LD_LIBRARY_PATH. Uważam, że kiedy uruchamia GDB, nie używa żadnej powłoki i dlatego nie otrzymuje żadnych zmiennych środowiskowych! Ustawienie libpythona w konfiguracji debugowania również nie pomogło, ponieważ jest to tylko wtedy, gdy gdb faktycznie się ładuje (ale potrzebuję biblioteki do samego gdb do załadowania)
Setheron
1
Czy możesz pomyślnie debugować aplikację, jeśli uruchamiasz ją gdbz wiersza poleceń, a LD_LIBRARY_PATH jest poprawnie skonfigurowana w terminalu? Jeśli nie, prawdopodobnie będziesz musiał ustawić LD_LIBRARY_PATH w swoim .gdbinitpliku. Zobacz tę odpowiedź, aby uzyskać więcej informacji: stackoverflow.com/a/7041845/156771
Tamás
Potrzebuję LD_LIBRARY_PATH do uruchomienia gdb (python libs), a nie do faktycznego debugowania mojej aplikacji. Jak dotąd udało mi się to naprawić tylko poprzez ustawienie go w ldconfig. Mogę debugować aplikację przez CLI, ponieważ pobierze ona LD_LIBRARY_PATH z mojego pliku ZSHRC.
Setheron
10
Tylko uwaga dla każdego, kto spróbuje tego: to tylko „/ usr / local / lib”, a nie początkowy „include” jak oryginał „include ld.so.conf.d / *. Conf”.
timss
79

Zakładam kapelusz grabarza ...

Najlepszym sposobem rozwiązania tego problemu jest kompilacja. Ponieważ i tak jesteś jedynym ustawieniem prefiksu, równie dobrze możesz wyraźnie powiedzieć plikowi wykonywalnemu, gdzie znaleźć jego biblioteki współdzielone. W przeciwieństwie do OpenSSL i innych pakietów oprogramowania, Python nie daje ładnych dyrektyw konfiguracyjnych do obsługi alternatywnych ścieżek bibliotek (nie każdy jest rootem, którego znasz ...) W najprostszym przypadku wszystko, czego potrzebujesz, to:

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

Lub jeśli wolisz wersję inną niż Linux:

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

Flaga " rpath" mówi Pythonowi, że ma biblioteki uruchomieniowe, których potrzebuje w tej konkretnej ścieżce. Możesz rozwinąć ten pomysł, aby obsłużyć zależności zainstalowane w innej lokalizacji niż standardowe lokalizacje systemu. Na przykład w moich systemach, ponieważ nie mam uprawnień administratora i muszę wykonywać prawie całkowicie samodzielne instalacje Pythona, moja linia konfiguracji wygląda następująco:

./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"

W tym przypadku jestem kompilacji bibliotek że używa python (jak ffi, readlineitp) w jego extlibkatalogu w drzewie katalogów samego Pythona. W ten sposób mogę tarować katalog python - $ {PYTHON_VERSION} i wylądować w dowolnym miejscu, a to będzie „działać” (pod warunkiem, że nie napotkasz libcani nie wystąpią libmkonflikty). Pomaga to również, gdy próbujesz uruchomić wiele wersji Pythona na tym samym pudełku, ponieważ nie musisz ciągle zmieniać swojego LD_LIBRARY_PATHlub martwić się o wybranie niewłaściwej wersji biblioteki Pythona.

Edycja: Zapomniałem wspomnieć, że kompilacja będzie narzekać, jeśli nie ustawisz PYTHONPATHzmiennej środowiskowej na to, czego używasz jako prefiksu i nie uda ci się skompilować niektórych modułów, np. Aby rozszerzyć powyższy przykład, ustaw PYTHONPATHprzedrostek użyty w powyższym przykład zexport PYTHONPATH=/apps/python-${PYTHON_VERSION} ...

Foosh
źródło
//, To wygląda na to, czego szukam. Gdzie mogę dowiedzieć się więcej o sposobach "tarowania katalogu wersji pythona i umieszczania go w dowolnym miejscu, a to będzie" działać "(pod warunkiem, że nie napotkasz konfliktów libc lub libm)" ? Czy uważasz, że warto zadać z tego osobne pytanie dotyczące stackoverflow.com?
Nathan Basanese
//, Poza tym, jak należy ustawić $PYTHON_VERSION?
Nathan Basanese
//, ustawiam $PYTHON_VERSIONpo skonfigurowaniu. $PYTHON_VERSIONJednak nawet z zestawem kompilator narzekaPython 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
//, Czy wymaga to jakichkolwiek modyfikacji makepolecenia i innych poleceń instalacyjnych?
Nathan Basanese
1
@NathanBasanese w przypadku brakujących plików bz2, curses, gdbm, lzma itp. Musiałbyś najpierw skompilować każdy z nich z przedrostkiem, /apps/python-${PYTHON_VERSION}/extlibaby upewnić się, że ich biblioteki i nagłówki znajdują się we właściwej lokalizacji do znalezienia przez proces tworzenia w Pythonie. Jeśli chodzi o pakiety na poziomie systemu, prawdopodobnie utkniesz, polegając na użytkowniku root, który zainstaluje je wcześniej. Lub znalezienie alternatywy, którą można skompilować i wylądować wextlib
Foosh
21

Miałem ten sam problem i rozwiązałem go w ten sposób:

Jeśli wiesz, gdzie znajduje się libpython, przypuszczałem, że tak będzie /usr/local/lib/libpython2.7.so.1.0w twoim przypadku, możesz po prostu utworzyć symboliczne łącze do niego:

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

Następnie spróbuj lddponownie uruchomić i sprawdź, czy zadziałało.

Omer Dagan
źródło
6

Zainstalowałem Python 3.5 firmy Software Collections na minimalnym systemie CentOS 7. Wszystko działało dobrze, ale widziałem błąd biblioteki współdzielonej wspomniany w tym pytaniu, gdy próbowałem uruchomić prosty skrypt CGI:

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

Chciałem mieć trwałe rozwiązanie systemowe, działające dla wszystkich użytkowników, wykluczające dodawanie instrukcji eksportu do plików .profile lub .bashrc. Istnieje rozwiązanie jednowierszowe, oparte na stronie rozwiązań Red Hat . Dziękuję za komentarz, który na to wskazuje:

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

Po ponownym uruchomieniu wszystko działa dobrze w powłoce, ale czasami mój serwer sieciowy nadal narzeka. Istnieje inne podejście, które zawsze działało zarówno dla powłoki, jak i serwera, i jest bardziej ogólne. Widziałem tutaj rozwiązanie , a potem zdałem sobie sprawę, że tak naprawdę jest wspomniane w jednej z odpowiedzi tutaj! W każdym razie w CentOS 7 są to kroki:

 vim /etc/ld.so.conf

Który na moim komputerze właśnie miał:

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

Więc utworzyłem nowy plik:

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

I dodał:

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

Aby ręcznie odbudować pamięć podręczną:

sudo ldconfig

To wszystko, skrypty działają dobrze!

To było tymczasowe rozwiązanie, które nie działało po ponownym uruchomieniu:

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

Opcja -v (gadatliwa) służyła tylko do sprawdzenia, co się dzieje. Widziałem, że tak: / 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

Ten konkretny błąd zniknął. Nawiasem mówiąc, musiałem chownapache użytkownika, aby pozbyć się błędu uprawnień po tym.

Zauważ, że użyłem find do zlokalizowania katalogu biblioteki. Możesz też:

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

Który na mojej maszynie wirtualnej zwraca:

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

Którą ścieżkę muszę podać ldconfig, jak pokazano powyżej.

Nagev
źródło
1
Mogłeś zaoszczędzić sobie kłopotów, przechodząc do /etc/profile.d i tworząc plik zawierający: #!/bin/bashi source scl_source enable rh-python35w nim. access.redhat.com/solutions/527703
Doug
2

W systemie Solaris 11

Służy LD_LIBRARY_PATH_64do rozwiązywania dowiązań symbolicznych do bibliotek Python.

W moim przypadku python3.6 LD_LIBRARY_PATHnie działał, aleLD_LIBRARY_PATH_64 .

Mam nadzieję że to pomoże.
pozdrowienia

basy
źródło
1

To zadziałało dla mnie ...

$ sudo apt-get install python2.7-dev
Kyle Anderson
źródło
Cześć, to nie jest poprawne rozwiązanie, ponieważ po tym niestandardowy plik binarny Pythona używa pliku .so z tego, który zainstalowałeś z apt-get. Może to powodować problemy, gdy mają tę samą wersję, lub jeśli zmodyfikowałeś kod źródłowy Pythona, nie będzie to wymagało wysiłku.
Azusa Nakano
0

Zainstalowałem za pomocą polecenia:

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

make

Teraz jako użytkownik root:

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

Następnie próbowałem uruchomić Pythona i otrzymałem błąd:

/ usr / local / bin / python: błąd podczas ładowania współdzielonych bibliotek: libpython2.7.so.1.0: nie można otworzyć współdzielonego pliku obiektu: nie ma takiego pliku lub katalogu

Następnie wylogowałem się z użytkownika root i ponownie spróbowałem uruchomić Pythona i zadziałało pomyślnie.

Pankaj
źródło
0

Wszystko czego potrzebuje to instalacja libpython [3 lub 2]. Instalacja plików dev.


źródło
-1

po prostu zainstaluj python-lib. (python27-lib). Zainstaluje libpython2.7.so1.0. Nie wymagamy ręcznego ustawiania czegokolwiek.

chintan-p-bhatt
źródło
4
//, A jeśli jesteś włączony, powiedzmy, CEntOS 6.3? To nie działa, i zazwyczaj ludzie kompilują Pythona, aby poradzić sobie z przypadkiem, w którym system Python jest dziwną wersją, zepsutą, zawodną lub inną chęcią nie dotykania całego systemu.
Nathan Basanese