I'm trying to get some open source academic code working (the project home is here). It is a big C++ codebase with a (very) thin python wrapper which uses CDLL
to load the C++ and call some C functions that are available to allow primitive python scripting of the code.
However, the initial import code crashes because it can't find the .so files sitting next to it in site-packages:
in the installed file:
from ctypes import *
try:
self.lib = CDLL("_lammps.so")
except:
try:
self.lib = CDLL("_lammps_serial.so")
except:
raise OSError,"Could not load LAMMPS dynamic library"
and in a script or the interpreter:
from lammps import lammps
l = lammps()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "lammps.py", line 42, in __init__
raise OSError,"Could not load LAMMPS dynamic library"
OSError: Could not load LAMMPS dynamic library
Other answers might seem to have this covered, but this only works if CDLL()
is called within the script actually invoked (or the working directory of the prompt that ran the interpreter) - i.e. if the 'relative path' is in user-space, rather than python-library-space.
How do we reliably install for import a C/C++ library that we built ourselves? Short of polluting the system library locations like /usr/lib
, which isn't very pythonic, I can't see an easy solution.
(EDIT: corrected function names, unclear refactoring unhelpful! sorry!)
You could use the
__file__
variable in the package that is doing the importing. Just use the various functions ofos.path
to extract the full, absolute directory path from__file__
, and then join it to your library filename. Something like:You might also want to try various variations of your core filename (i.e., with
.dll
or.dylib
instead of.so
, and with and without alib
prefix, and perhaps even with version numbers appended) if you want to be platform-independent, and your build system could possibly produce such stuff. You could then either try several versions, or just useglob.glob
to help you find an acceptable one.I've got to say I think it's odd that no such function exists in the standard library. The
ctypes.util.find_library
isn't quite flexible (or thorough) enough for this kind of use (which I would think was widespread). Even just a function that searched throughPYTHONPATH
for the file would have been quite useful (though not hard to write).Then again, it seems that if you just add the right directory to
LD_LIBRARY_PATH
, you should be able to load it.