Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Install and find shared library with conda

I want to build two related conda packages:

  1. A shared object file libfoo.so with compiled code
  2. A Python wrapper around that code, foopy

Upon import, the foopy module needs to locate the libfoo.so file, which it will then use with ctypes:

so_directory = ???
lib = ctypes.cdll.LoadLibrary(os.path.join(so_directory, 'libfoo.so'))

How do I reliably find where the libfoo.so file is located? I'm happy to change either recipe.

like image 866
MRocklin Avatar asked Jan 14 '16 18:01

MRocklin


2 Answers

I would recommend installing the .so to the PREFIX/lib folder - in other words, put it on the default search path.

For Windows/Anaconda, this is PREFIX/Library/bin instead.

EDIT:

PREFIX is just wherever you have Python installed. This might be /usr or /usr/local, or ~/miniconda

Also:

You should remove the os.path.join bit and just pass the filename into the DLL load. It will look in default paths, which as long as you are running the python from PREFIX, will include the paths mentioned above.

like image 92
msarahan Avatar answered Oct 05 '22 03:10

msarahan


I think I would use relative paths.

Here's a bit of a related post. Python ctypes: loading DLL from from a relative path

Let's say we've got a conda env activated at some random location $BAR. I'd definitely put your libfoo.so at $BAR/lib/libfoo.so. To do that, just make sure conda-build puts it at $PREFIX/lib/libfoo.so.

Then let's say we have the foopy project with the standard setup.py and code in foopy/__init__.py. That will get pip- or conda-installed to $BAR/lib/python2.7/site-packages/foopy/__init__.py. (Or python3.x) So the contents of foopy/__init__.py would be something like

import os.path
fourup = '../../../..'
libdir = os.path.normpath(os.path.join(__file__, fourup))

import ctypes
lib = ctypes.CDLL(os.path.join(libdir, 'libfoo.so')
like image 34
kalefranz Avatar answered Oct 05 '22 03:10

kalefranz