web-dev-qa-db-fra.com

Pourquoi Python ne trouve-t-il pas les objets partagés qui se trouvent dans les répertoires de 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 se trouve dans/usr/local/lib. Comme vous pouvez le voir, cela se trouve 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 fortement appréciée.

113
user135171

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

Quelques informations supplémentaires ( source ):

Sous Linux, la variable d’environnement LD_LIBRARY_PATH est un ensemble de répertoires séparés par des deux-points dans lesquels les bibliothèques doivent être recherchées en premier, avant le jeu standard de répertoires; Ceci est utile lors du débogage d'une nouvelle bibliothèque ou de l'utilisation d'une bibliothèque non standard à des fins spéciales. La variable d’environnement LD_PRELOAD répertorie les bibliothèques partagées avec des fonctions remplaçant le jeu standard, à l’instar de /etc/ld.so.preload. Celles-ci sont implémentées par le chargeur /lib/ld-linux.so. Je dois noter que, bien que LD_LIBRARY_PATH fonctionne sur de nombreux systèmes de type Unix, il ne fonctionne pas sur tous; Par exemple, cette fonctionnalité est disponible sur HP-UX, mais sous la forme de la variable d'environnement SHLIB_PATH, et sous AIX, elle utilise la variable LIBPATH (avec la même syntaxe, une liste séparée par deux-points).

Mise à jour: pour définir LD_LIBRARY_PATH, utilisez l’un des éléments suivants, idéalement dans votre ~/.bashrc ou 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 s'il n'est pas présent du tout) et le second formulaire s'il ne l'est pas. Notez l'utilisation de export.

149
Vinay Sajip

Assurez-vous que votre module libcurl.so figure dans le chemin de la bibliothèque système, distinct et distinct du chemin de la bibliothèque python).

Une solution rapide consiste à ajouter ce chemin à une variable LD_LIBRARY_PATH. Cependant, définir ce système à l'échelle (ou même à l'ensemble du compte) est une mauvaise idée, car il est possible de le configurer de manière à ce que certains programmes trouvent une bibliothèque qu'il ne devrait pas, ou même pire, à créer des failles de sécurité.

Si vos "bibliothèques installées localement" sont installées, par exemple, dans/usr/local/lib, ajoutez ce répertoire à /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 le "make install" de libcurl ne l'ait pas déjà fait, mais il est possible que cela ne soit pas possible 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 celui-ci ou simplement créer un nouveau fichier dans le répertoire à partir duquel il est inclus. N'oubliez pas de lancer "ldconfig" après.

Faites attention. Se tromper peut gâcher votre système.

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

55
Ch'marr

Vous pouvez également définir LD_RUN_PATH sur/usr/local/lib dans votre environnement utilisateur lorsque vous compilez pycurl. Cela 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.

24
Graham Dumpleton

A eu exactement le même problème. J'ai installé curl 7.19 dans/opt/curl/pour m'assurer que je n'affecterais pas 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 exécuter ldconfig crée le lien pour moi et cela a fonctionné. Pas besoin de définir LD_RUN_PATH ou LD_LIBRARY_PATH du tout. Juste besoin de lancer ldconfig.

10
Matt

En complément des réponses ci-dessus, je me heurte à un problème similaire et travaille complètement 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, Je reçois 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

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

Je pensais que je pourrais noter ça ici - Bravo!

8
sdaau

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 voir les explications de -R et -I

0
ScutterKey