Feodoran
Feodoran

Reputation: 1822

loading .so library with cffi

I have some C library I want to access in Python using CFFI. After building the library, I get the 2 files: $HOME/libcint/include/cint.h and $HOME/libcint/lib/libcint.so.

Now for the CFFI API mode I tried:

from cffi import FFI
libcint_dir = os.path.expanduser('~/libcint')
ffibuilder = FFI()
ffibuilder.set_source('_libcint',
  r'#include <include/cint.h>',
  include_dirs = [libcint_dir],
  libraries = ['libcint'],
  library_dirs = [os.path.join(libcint_dir, 'lib')],
)

But it fails to find the libcint.so file:

/usr/bin/ld: cannot find -llibcint

The path in libcint_dir is correct, because I don't get any error message about not finding the header file. Also I managed to successfully interface the library using the ctypes module, so the libcint.so itself should be fine.

What am I doing wrong here?

If I get this right, then there are 3 steps required here. (Please correct me, if I confused something here.)

  1. compiling libcint yielding libcint.so
  2. building the Python wrapper with CFFI
  3. importing the module built in step 2 into the actual Python program

My issue here is about the second step.

Upvotes: 1

Views: 3474

Answers (2)

Armin Rigo
Armin Rigo

Reputation: 12900

You're saying libraries = ['libcint'], which means that the compiler will look for a file called liblibcint.so. What you should write is thus libraries = ['cint'].

Upvotes: 4

Armin Rigo
Armin Rigo

Reputation: 12900

You're probably bitten by the issue of compilation-time versus runtime location of libraries. The path you give to the library is only used at compilation time by GCC. At runtime, it looks for a library with the correct name, but using the system-configured default paths, only. So you need to tell the system where to find that library. You can do one of:

  • move the library to a standard place like /usr/local/lib;

  • run with the environment variable LD_LIBRARY_PATH=/path/to/library;

  • if you want to hard-code the path inside the compiled module, you can use extra_link_args=['-Wl,-rpath=' + path] in the call to set_source().

This is all assuming Linux. On a different platform, all three options are probably available too but the details differ...

Upvotes: 0

Related Questions