2009-07-08 14 views
90

sto cercando di importare pycurl:Perché Python non può trovare oggetti condivisi nelle directory in sys.path?

$ python -c "import pycurl" 
Traceback (most recent call last): 
File "<string>", line 1, in <module> 
ImportError: libcurl.so.4: cannot open shared object file: No such file or directory 

Ora, libcurl.so.4 si trova in// local/lib usr. Come potete vedere, questo è in sys.path:

$ python -c "import sys; print sys.path" 
['', '/usr/local/lib/python2.5/site-packages/setuptools-0.6c9-py2.5.egg', 
'/usr/local/lib/python25.zip', '/usr/local/lib/python2.5', 
'/usr/local/lib/python2.5/plat-linux2', '/usr/local/lib/python2.5/lib-tk', 
'/usr/local/lib/python2.5/lib-dynload', 
'/usr/local/lib/python2.5/sitepackages', '/usr/local/lib', 
'/usr/local/lib/python2.5/site-packages'] 

Qualsiasi aiuto sarà molto apprezzato.

+0

Vedere la mia risposta aggiornata, nel caso in cui non si sia impostato correttamente 'LD_LIBRARY_PATH' (ho pensato che il tuo commento avesse i due punti mancanti). –

+1

C'è un link simbolico rotto da qualche parte chiamato libcurl.so.4? Mi sembra che trovi il file ma non riesca ad aprirlo. Se tutto il resto fallisce, cerca l'interprete e cerca la chiamata fallita. –

risposta

124

sys.path viene cercato solo per moduli Python. Per le librerie dinamiche collegate, i percorsi cercati devono essere in LD_LIBRARY_PATH. Verifica se il tuo LD_LIBRARY_PATH include /usr/local/lib e, in caso contrario, aggiungilo e riprova.

Qualche informazione in più (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).

Aggiornamento: per impostare LD_LIBRARY_PATH, utilizzare uno dei seguenti, in posizione ideale nel vostro ~/.bashrc o il file equivalente:

export LD_LIBRARY_PATH=/usr/local/lib 

o

export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH 

Utilizzare il primo modulo se è vuoto (equivalente alla stringa vuota o non presente) e il secondo modulo se non lo è. Notare l'uso di esportazione.

+2

Grazie. mio LD_LIBRARY_PATH non è stato impostato, in modo da: $ LD_LIBRARY_PATH =/usr/local/lib $ LD_LIBRARY_PATH /usr/local/lib Ma ancora ottengo lo stesso errore: $ python -c "import pycurl" Traceback (ultima chiamata ultima): File "", riga 1, in ImportErrore: libcurl.so.4: impossibile aprire il file oggetto condiviso: Nessun file o directory tale –

+1

Ho dovuto anche concedere le autorizzazioni al mio utente per leggere la libreria dopo aver impostato la variabile LD_LIBRARY_PATH. Ora finalmente funziona. –

46

Verificare che il modulo libcurl.so si trovi nel percorso della libreria di sistema, distinto e separato dal percorso della libreria python.

Una "soluzione rapida" consiste nell'aggiungere questo percorso a una variabile LD_LIBRARY_PATH. Tuttavia, l'impostazione di tale sistema (o anche di un ampio account) è IDEA BAD, in quanto è possibile impostarlo in modo tale che alcuni programmi troveranno una libreria che non dovrebbe, o peggio ancora, aprire buchi di sicurezza.

Se le "librerie installate localmente" sono installati in, per esempio,/usr/local/lib, aggiungere questo elenco per /etc/ld.so.conf (si tratta di un file di testo) ed eseguire "ldconfig"

Il comando eseguirà un'utilità di memorizzazione nella cache, ma creerà anche tutti i "collegamenti simbolici" necessari per il funzionamento del sistema di caricamento. È sorprendente che il "make install" per libcurl non lo abbia già fatto, ma è possibile che non lo sia se/usr/local/lib non è già in /etc/ld.so.conf.

PS: è possibile che il file /etc/ld.so.conf contenga solo "include ld.so.conf.d/*. Conf". Puoi ancora aggiungere un percorso di directory dopo di esso, o semplicemente creare un nuovo file all'interno della directory da cui viene incluso. Non dimenticare di eseguire "ldconfig" dopo di esso.

Fare attenzione. Sbagliare questo può rovinare il tuo sistema.

Inoltre: assicurati che il tuo modulo python sia compilato con quella versione di libcurl. Se hai appena copiato alcuni file da un altro sistema, questo non funzionerà sempre. In caso di dubbi, compilare i moduli sul sistema su cui si intende eseguirli.

+0

Grazie - ha funzionato. Mi chiedo perché la mia "correzione rapida" precedentemente tentata non abbia modificato la variabile LD_LIBRARY_PATH. –

+1

dipende da molti fattori. Ecco una possibilità: il tuo codice è stato eseguito da apache o cron. Questi programmi tipicamente "ripuliscono" l'ambiente, quindi devi fare cose extra per ottenere le variabili d'ambiente. Ad esempio, "SetEnv" in apache, o impostando la variabile direttamente nel file crontab per cron. Le possibilità di errori sono infinite! –

+0

Ottima risposta, grazie – glarrain

22

È anche possibile impostare LD_RUN_PATH in/usr/local/lib nel proprio ambiente utente quando si compila pycurl in primo luogo. Questo incorporerà/usr/local/lib nell'attributo RPATH del modulo di estensione C.in modo che sappia automaticamente dove trovare la libreria in fase di esecuzione senza dover impostare LD_LIBRARY_PATH in fase di esecuzione.

+0

+1 proprio quello che stavo cercando. Grazie! –

+3

In alternativa, usare 'python setup.py build_ext --rpath =/usr/local/lib' quando si costruisce il modulo di estensione per cuocere nel * rpath * – kynan

+0

Questa dovrebbe essere la risposta accettata –

8

Aveva lo stesso identico problema. Ho installato curl 7.19 su/opt/curl/per assicurarmi che non influenzi l'attuale arricciatura sui nostri server di produzione. Una volta ho collegato libcurl.so.4 a/usr/lib:

sudo ln -s /opt/curl/lib/libcurl.so /usr/lib/libcurl.so.4

ho ancora ricevuto lo stesso errore! Durf.

Ma eseguire ldconfig crea il collegamento per me e questo ha funzionato. Non è necessario impostare LD_RUN_PATH o LD_LIBRARY_PATH. Ho solo bisogno di eseguire ldconfig.

+0

+1 per l'esecuzione di 'ldconfig', tutti gli errori corretti –

+0

Cosa fare se non lo faccio avere un privilegio sudo? Non riesco a eseguire ldconfig? C'è un modo per cancellare l'errore sopra allora? – SPRajagopal

+1

@SPRajagopal: se non si dispone dei privilegi per modificare gli attributi di sistema, è necessario utilizzare il metodo di variabile di ambiente 'LD_LIBRARY_PATH' descritto in precedenza. Se non vuoi impostarlo in ~ ~/.bashrc' (aggiungendo che l'impostazione non è una buona idea IMO) puoi scrivere uno script di shell che imposta questa variabile quindi esegue python, quindi chiama lo script. – MadScientist

7

Come supplemento alle risposte di cui sopra - Sto solo imbattendo in un problema simile, e lavorando completamente del python installato di default.

Quando chiamo l'esempio della libreria di oggetti condiviso Sto cercando con LD_LIBRARY_PATH, ottengo qualcosa di simile:

$ LD_LIBRARY_PATH=/path/to/mysodir:$LD_LIBRARY_PATH python example-so-user.py 
python: can't open file 'example-so-user.py': [Errno 2] No such file or directory 

In particolare, non ha nemmeno lamenta l'importazione - si lamenta il file sorgente!

Ma se io forza di carico dell'oggetto utilizzando LD_PRELOAD:

$ LD_PRELOAD=/path/to/mysodir/mypyobj.so python example-so-user.py 
python: error while loading shared libraries: libtiff.so.5: cannot open shared object file: No such file or directory 

... Ho subito un messaggio di errore più significativo - di una dipendenza mancante!

Ho solo pensato di buttar giù qui - evviva!

+0

Sei sicuro che non si sia verificato un nuovo errore prima dell'errore di OP? –

0

Io uso python setup.py build_ext -R/usr/local/lib -I/usr/local/include/libcalg-1.0 e il file .so compilato si trova nella cartella di generazione. è possibile digitare python setup.py --help build_ext per vedere le spiegazioni di -R e -I