Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting LD_LIBRARY_PATH from inside Python

Is there a way to set specify during runtime where Python looks for shared libraries?

I have fontforge.so located in fontforge_bin and tried the following

os.environ['LD_LIBRARY_PATH']='fontforge_bin' sys.path.append('fontforge_bin') import fontforge 

and get

ImportError: fontforge_bin/fontforge.so: cannot open shared object file: No such file or directory 

Doing ldd on fontforge_bin/fontforge.so gives the following

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) 
like image 491
Yaroslav Bulatov Avatar asked Jul 01 '11 05:07

Yaroslav Bulatov


People also ask

What is LD_LIBRARY_PATH Python?

Python, when gets the values of environment variables as in os. environ['LD_LIBRARY_PATH'] or os. environ['PATH'] , it copies the values, into a dictionary, from it's parent process's environment, generally bash (bash process's environment get's carried to the child process, the python running instance).

What should be in LD_LIBRARY_PATH?

Set the LD_LIBRARY_PATH to include the directory or directories that contain your libraries.

What is the difference between path and LD_LIBRARY_PATH?

PATH is for specifying directories of executable programs. LD_LIBRARY_PATH is used to specify directories of libraries. From other point of view, PATH is used primarily by the shell, while LD_LIBRARY_PATH is used by the dynamic loader (usually ld-linux.so ).


2 Answers

Your script can check for the existence/properness of the environment variable before you import your module, then set it in os.environ if it is missing, and then call os.execv() to restart the python interpreter using the same command line arguments but an updated set of environment variables.

This is only advisable before any other imports (other than os and sys), because of potential module-import side-effects, like opened file descriptors or sockets, which may be challenging to close cleanly.

This code sets LD_LIBRARY_PATH and 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 

It's probably cleaner to set that environment variable as part of the starting environment (in the parent process or systemd/etc job file).

like image 92
Will Pierce Avatar answered Sep 29 '22 13:09

Will Pierce


...well sort of you could load all libraries from some folder of your choosing via ctypes and thus make them available for you regardless of the LD_LIBRARY_PATH.

from ctypes import * lib1 = cdll.LoadLibrary('/home/username/lib/some_library.so') 

or iterate through the files in that dir... you get the idea, once it is loaded it is there for you [if the dependencies are also out of the default path you should load them too...].

like image 26
pawel lukaszewicz Avatar answered Sep 29 '22 13:09

pawel lukaszewicz