Existe-t-il un moyen de définir spécifier pendant l'exécution où Python recherche les bibliothèques partagées?
J'ai fontforge.so
situé dans fontforge_bin
et a essayé ce qui suit
os.environ['LD_LIBRARY_PATH']='fontforge_bin'
sys.path.append('fontforge_bin')
import fontforge
et obtenir
ImportError: fontforge_bin/fontforge.so: cannot open shared object file: No such file or directory
Faire ldd
sur fontforge_bin/fontforge.so
donne ce qui suit
linux-vdso.so.1 => (0x00007fff2050c000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00007f10ffdef000)
libc.so.6 => /lib/libc.so.6 (0x00007f10ffa6c000)
/lib64/ld-linux-x86-64.so.2 (0x00007f110022d000)
Votre script peut vérifier l'existence/la propreté de la variable d'environnement avant d'importer votre module, puis le définir dans os.environ s'il est manquant, puis appeler os.execv () pour redémarrer le = python interprète utilisant les mêmes arguments de ligne de commande mais un ensemble mis à jour de variables d'environnement.
Ceci n'est conseillé avant aucune autre importation (autre que os et sys), en raison d'effets secondaires potentiels d'importation de module, comme des descripteurs de fichiers ouverts ou des sockets , qui peut être difficile à clôturer proprement.
Ce code définit LD_LIBRARY_PATH et Oracle_HOME:
#!/usr/bin/python
import os, sys
if 'LD_LIBRARY_PATH' not in os.environ:
os.environ['LD_LIBRARY_PATH'] = '/usr/lib/Oracle/XX.Y/client64/lib'
os.environ['Oracle_HOME'] = '/usr/lib/Oracle/XX.Y/client64'
try:
os.execv(sys.argv[0], sys.argv)
except Exception, exc:
print 'Failed re-exec:', exc
sys.exit(1)
#
# import yourmodule
print 'Success:', os.environ['LD_LIBRARY_PATH']
# your program goes here
Il est probablement plus propre de définir cette variable d'environnement dans le cadre de l'environnement de démarrage (dans le processus parent ou le fichier de travail systemd/etc).
... vous pourriez en quelque sorte charger toutes les bibliothèques à partir d'un dossier de votre choix via des ctypes et ainsi les rendre disponibles pour vous indépendamment du LD_LIBRARY_PATH.
from ctypes import *
lib1 = cdll.LoadLibrary('/home/username/lib/some_library.so')
ou parcourez les fichiers dans ce répertoire ... vous avez l'idée, une fois qu'il est chargé, il est là pour vous [si les dépendances sont également hors du chemin par défaut, vous devez les charger aussi ...].
LD_LIBRARY_PATH
définit le chemin du lieur dynamique; cela ne peut généralement pas être modifié au moment de l'exécution, car il est généralement mis en cache par l'éditeur de liens dynamique.
Ce n'est pas là que Python recherche importations, cependant, y compris les importations de modules. Changer sys.path
est correct.
# ls foo/
_csv.so
# python
Python 2.6.6 (r266:84292, Dec 26 2010, 22:31:48)
>>> import sys
>>> sys.path.insert(0, "foo")
>>> import _csv
>>> _csv.__file__
'foo/_csv.so'
(Soit dit en passant, vous souhaiterez peut-être ldd la bibliothèque pour voir si vous avez des chemins d'importation impairs dans la bibliothèque. "ImportError: fontforge_bin/fontforge.so" semble étrange.)