154 votes

Pourquoi Python ne peut pas trouver les objets partagés qui sont dans des répertoires dans sys.path ?

J'essaie d'importer pycurl :

$ 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 en /usr/local/lib . Comme vous pouvez le voir, c'est en 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.

181voto

Vinay Sajip Points 41286

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

Quelques informations supplémentaires ( source ) :

Sous Linux, la variable d'environnement LD_LIBRARY_PATH est un ensemble de répertoires de répertoires où les bibliothèques doivent être recherchées en premier, avant l'ensemble standard de répertoires ; ceci est utile lors du débogage d'une nouvelle bibliothèque ou l'utilisation d'une bibliothèque non standard pour à des fins particulières. La variable d'environnement LD_PRELOAD liste les bibliothèques partagées avec des fonctions qui remplacent l'ensemble standard, tout comme /etc/ld.so.preload. Ces fonctions sont implémentées par le chargeur /lib/ld-linux.so. Je dois noter que, alors que LD_LIBRARY_PATH fonctionne sur de nombreux systèmes systèmes Unix-like, il ne fonctionne pas sur tous tous ; par exemple, cette fonctionnalité est disponible sur HP-UX mais en tant que variable d'environnement SHLIB_PATH, et sur AIX, cette fonctionnalité passe par la variable LIBPATH (avec la même une liste séparée par deux points).

Mise à jour : pour fixer LD_LIBRARY_PATH utilisez l'un des éléments suivants, idéalement dans votre dossier de candidature. ~/.bashrc ou un fichier équivalent :

export LD_LIBRARY_PATH=/usr/local/lib

o

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

Utilisez la première forme si elle est vide (équivalente à la chaîne vide, ou pas présente du tout), et la seconde forme si elle ne l'est pas. Notez l'utilisation de exporter .

63voto

Ch'marr Points 604

Assurez-vous que votre module libcurl.so se trouve dans le chemin de la bibliothèque système, qui est distinct et séparé du chemin de la bibliothèque python.

Une "solution rapide" consiste à ajouter ce chemin à une variable LD_LIBRARY_PATH. Cependant, définir cette variable à l'échelle du système (ou même à l'échelle du compte) est une MAUVAISE IDÉE, car il est possible de la définir de telle sorte que certains programmes trouvent une bibliothèque qu'ils ne devraient pas trouver, ou pire, qu'ils ouvrent des failles de sécurité.

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

La commande lancera 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 le "make install" pour libcurl ne l'ait pas déjà fait, mais il est possible qu'il ne le fasse pas si /usr/local/lib n'est pas déjà dans /etc/ld.so.conf.

PS : il est possible que votre /etc/ld.so.conf ne contienne rien d'autre 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 d'où il est inclus. N'oubliez pas de lancer "ldconfig" après.

Faites attention. Si vous vous trompez, vous risquez de bousiller votre système.

De plus, assurez-vous que votre module python est compilé avec CETTE version de libcurl. Si vous avez simplement copié des fichiers depuis 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.

24voto

Graham Dumpleton Points 23711

Vous pouvez également définir LD_RUN_PATH à /usr/local/lib dans votre environnement utilisateur lorsque vous compilez pycurl en premier lieu. Ceci incorporera /usr/local/lib dans l'attribut RPATH du module d'extension C .so afin qu'il sache automatiquement où trouver la bibliothèque au moment de l'exécution sans avoir à définir LD_LIBRARY_PATH au moment de l'exécution.

10voto

Matt Points 78

J'ai eu exactement le même problème. J'ai installé curl 7.19 dans /opt/curl/ pour être sûr de ne pas affecter le curl actuel sur nos serveurs de production. Une fois que j'ai lié libcurl.so.4 à /usr/lib :

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

J'ai toujours la même erreur ! Durf.

Mais l'exécution de ldconfig fait le lien pour moi et ça a marché. Pas besoin de définir le LD_RUN_PATH ou le LD_LIBRARY_PATH du tout. Il suffit d'exécuter ldconfig.

10voto

sdaau Points 6262

En complément des réponses ci-dessus, je me heurte à un problème similaire, et je travaille entièrement avec le python installé par défaut.

Lorsque j'appelle l'exemple de la bibliothèque d'objets partagés que je recherche avec LD_LIBRARY_PATH j'obtiens quelque chose comme ça :

$ 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 de l'importation - il se plaint du 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

... J'obtiens immédiatement un message d'erreur plus significatif - à propos d'une dépendance manquante !

J'ai juste pensé que je devais le noter ici - merci !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X