2009-07-08 10 views
90

Je suis en train d'importer pycurl:Pourquoi Python ne trouve-t-il pas les objets partagés qui se trouvent dans les répertoires de 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 

Maintenant, libcurl.so.4 est dans/usr/local/lib. Comme vous pouvez le voir, ceci est dans 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'] 

Toute aide sera grandement appréciée.

+0

Voir ma réponse mise à jour, dans le cas où vous n'avez pas défini 'LD_LIBRARY_PATH' correctement (je pensais que votre commentaire avait un deux-points manquant). –

+1

Existe-t-il un lien symbolique brisé nommé libcurl.so.4? Il me semble que c'est trouver le fichier mais incapable de l'ouvrir. Si tout le reste échoue, approchez l'interprète et recherchez l'appel qui a échoué. –

Répondre

124

sys.path est uniquement recherchée pour les modules Python. Pour les bibliothèques liées dynamiques, les chemins recherchés doivent être au LD_LIBRARY_PATH. Vérifiez si votre LD_LIBRARY_PATH inclut /usr/local/lib, et si ce n'est pas le cas, ajoutez-le et réessayez.

Quelques informations supplémentaires (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).

Mise à jour: pour définir LD_LIBRARY_PATH, utilisez une des options suivantes, idéalement dans votre ~/.bashrc ou d'un fichier équivalent:

export LD_LIBRARY_PATH=/usr/local/lib 

ou

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

Utilisez le premier formulaire s'il est vide (équivalent à la chaîne vide, ou pas du tout) et le deuxième formulaire s'il ne l'est pas. Notez l'utilisation de exporter.

+2

Merci. Mon LD_LIBRARY_PATH n'a pas été défini, donc: $ LD_LIBRARY_PATH =/usr/local/lib $ LD_LIBRARY_PATH /usr/local/lib Mais je reçois toujours la même erreur: $ python -c "pycurl import" Traceback (dernier appel en dernier): Fichier "", ligne 1, en ImportError: libcurl.so.4: impossible d'ouvrir le fichier d'objet partagé: aucun fichier ou répertoire de ce type –

+1

Je devais également autoriser l'utilisateur à lire la bibliothèque après avoir défini la variable LD_LIBRARY_PATH. Maintenant ça marche finalement. –

46

Assurez-vous que votre module libcurl.so est dans le chemin de la bibliothèque système, qui est distinct et distinct du chemin de la bibliothèque python. Un "quick fix" consiste à ajouter ce chemin à une variable LD_LIBRARY_PATH. Cependant, définir ce système à l'échelle (ou même au compte large) est une BAD IDEA, car il est possible de le configurer de telle sorte que certains programmes trouveront une bibliothèque qu'il ne devrait pas, ou pire, ouvrir des failles de sécurité.

Si vos « bibliothèques installées localement » sont installés, par exemple,/usr/local/lib, ajoutez ce répertoire dans /etc/ld.so.conf (c'est un fichier texte) et exécutez « ldconfig »

La commande exécutera un utilitaire de mise en cache, mais créera également tous les «liens symboliques» nécessaires au fonctionnement du système de chargement. Il est surprenant que "make install" pour libcurl ne l'ait pas déjà fait, mais il est possible qu'il ne le soit pas si/usr/local/lib n'est pas déjà dans /etc/ld.so.conf. PS: il est possible que votre fichier /etc/ld.so.conf ne contienne que "include ld.so.conf.d/*. Conf". Vous pouvez toujours ajouter un chemin de répertoire après, ou simplement créer un nouveau fichier dans le répertoire à partir duquel il est inclus. N'oubliez pas de lancer "ldconfig" après.

Soyez prudent. Cela peut fausser votre système.

De plus: assurez-vous que votre module python est compilé avec cette version de libcurl. Si vous venez de copier certains fichiers d'un autre système, cela ne fonctionnera pas toujours. En cas de doute, compilez vos modules sur le système sur lequel vous avez l'intention de les exécuter.

+0

Merci - cela a fonctionné. Je me demande pourquoi mon "correctif rapide" précédemment tenté de modifier la variable LD_LIBRARY_PATH n'a pas. –

+1

Cela dépend de beaucoup de facteurs. Voici une possibilité: votre code était lancé depuis Apache ou Cron. Ces programmes "nettoient" généralement l'environnement, vous devez donc faire des choses supplémentaires pour obtenir les variables d'environnement. Par exemple, "SetEnv" dans apache, ou en définissant la variable directement dans le fichier crontab pour cron. Les possibilités d'erreurs sont infinies! –

+0

Bonne réponse, merci – glarrain

22

Vous pouvez également définir LD_RUN_PATH sur/usr/local/lib dans votre environnement utilisateur lorsque vous compilez pycurl en premier lieu. Cela va intégrer/usr/local/lib dans l'attribut RPATH du module d'extension C.Ainsi, il sait automatiquement où trouver la bibliothèque lors de l'exécution sans que LD_LIBRARY_PATH ne soit défini lors de l'exécution.

+0

+1 juste ce que je cherchais. Merci! –

+3

Vous pouvez également utiliser 'setup python.py build_ext --rpath =/usr/local/lib' lors de la construction du module d'extension pour faire cuire dans le * rpath * – kynan

+0

Merci cela devrait être la réponse acceptée –

8

Avait le même problème. J'ai installé curl 7.19 dans/opt/curl/pour m'assurer que je n'affecterais pas la boucle courante sur nos serveurs de production. Une fois que je lié libcurl.so.4/usr/lib:

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

J'ai encore la même erreur! Durf. Mais ldconfig en cours d'exécution ldconfig faire le lien pour moi et cela a fonctionné. Pas besoin de définir le LD_RUN_PATH ou LD_LIBRARY_PATH du tout. Juste besoin de lancer ldconfig.

+0

+1 pour exécuter 'ldconfig', toutes les erreurs ont été corrigées –

+0

Que faire si je ne fais pas pas avoir le privilège sudo? Je ne peux pas lancer ldconfig? Y at-il un moyen d'effacer l'erreur ci-dessus alors? – SPRajagopal

+1

@SPRajagopal: si vous n'avez pas les privilèges pour modifier les attributs du système, vous devez utiliser la méthode de variable d'environnement 'LD_LIBRARY_PATH' décrite ci-dessus. Si vous ne voulez pas le définir dans votre '~/.bashrc' (en ajoutant que ce paramètre n'est pas une bonne idée IMO), vous pouvez écrire un script shell qui définit cette variable puis lance python, puis appelle ce script. – MadScientist

7

En complément des réponses ci-dessus - Je suis juste en train de tomber sur un problème similaire, et de travailler complètement sur le python installé par défaut.

Quand j'appelle l'exemple de la bibliothèque d'objets partagés Je cherche avec LD_LIBRARY_PATH, je reçois quelque chose comme ceci:

$ 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 

Notamment, il ne se plaint même pas l'importation - il se plaint le fichier source!

Mais si je force le chargement de l'objet en utilisant 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 

... Je reçois immédiatement un message d'erreur plus significatif - sur une dépendance manquante!

Je pensais juste que je noterais cela ici - bravo!

+0

Etes-vous sûr que ce n'est pas une nouvelle erreur qui se produit avant l'erreur de l'OP? –

0

J'utilise python setup.py build_ext -R/usr/local/lib -I/usr/local/include/libcalg-1.0 et le fichier .so compilé se trouve dans le dossier de construction. vous pouvez taper python setup.py --help build_ext pour voir les explications de -R et -I