J'ai eu besoin de charger une version spécifique d'une bibliothèque dynamique pour un outil python (fonctionnalité non implémentée dans la même bibliothèque installée globalement).

Ma première approche a été de jouer avec les variables LD_PRELOAD et LD_LIBRARY_PATH. Mais pour pouvoir généraliser mon script, j'ai eu besoin que le script python modifie lui-même l'environnement...

Le besoin

J'ai écrit un script python qui utilise gdal/ogr pour calculer des distances. La version installée globalement ne supporte pas geos, nécessaire au calcul des distances, et en plus la version globale de geos est compilée avec les flags O2 et donne des segfaults quand on veut calculer une distance.

J'ai donc recompilé ces 2 bibliothèques. Pour l'instant, il n'est pas question d'installer en global ces versions mises à jour. Je les ai donc placées dans une arborescence perso.

La solution simple

avant de lancer mon outil, il me suffit de précharger les bibliothèques :

LD_PRELOAD=monchemin/libgeos.so:monchemin/libgdal.so monoutil.py

Mais si je veux que d'autres utilisateurs puissent utiliser mon outil, je dois me débarasser de ce LD_PRELOAD. De la même manière qu'il n'est pas prévu d'installer ces 2 libs globalement, il est exclu de rajouter le LD_PRELOAD dans le bash_profile. On peut aussi effectuer ce préchargement dans un enrobage shell, mais écrire un wrapper pour un export, c'est moins "sexy".

On ne peut pas non plus simplement manipuler les variables d'environnement :

os.environ['LD_PRELOAD']="monchemin/libgeos.so:monchemin/libgdal.so"
from osgeo import ogr

Ne fonctionne pas

LA solution

Le module ctypes, permet, lui de charger une bibliothèque dynamique. Le code suivant :

cdll.LoadLibrary(libDir+'/libgeos.so')
cdll.LoadLibrary(libDir+'/libgdal.so')

from osgeo import ogr

permet de précharger les 2 bibliothèques avant l'appel du module, et je calcule mes distances sans souci !

Ajouter un Commentaire


Code de sécurité
Rafraîchir