web-dev-qa-db-fra.com

Définition de LD_LIBRARY_PATH de l'intérieur Python

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)
24
Yaroslav Bulatov

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).

19
Will Pierce

... 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 ...].

11
pawelmech

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.)

6
Glenn Maynard