4

So I'm trying to wrap some C code with Cython. I read read applied Cython's tutorials on doing this (1, 2), but these tutorials do not say much on how to compile the code once you have wrapped it with Cython, and so I have an error saying it can't find my C code.

First, my cython script ("calcRMSD.pyx"):

import numpy as np
cimport numpy as np

cdef extern from "rsmd.h":
    double rmsd(int n, double* x, double* y)

#rest of the code ommited

The C code I am trying to wrap ("rmsd.h"):

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

extern "C" {
  // svd from lapack
  void dgesvd_(char*,char*,int*,int*,double*,int*,double*,double*,int*,double*,
           int*,double*,int*,int*);
}

double rmsd(int n, double* x, double* y)
{
   //code omitted
}

Setup.py

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
from Cython.Build import cythonize
import numpy as np


setup(
    ext_modules = cythonize([Extension("calcRMSD", 
                            sources = ["calcRMSD.pyx"],
                            include_dirs = [np.get_include()],
                            libraries = ["dgesvd"]
                            #extra_compile_args = ["-I."],
                            #extra_link_args = ["-L./usr/lib/liblapack.dylib"]
                            )])

) 

My error:

calcRMSD.c:269:10: fatal error: 'rsmd.h' file not found
#include "rsmd.h"

I read this stack overflow thread Using Cython To Link Python To A Shared Library

but following it gives me different errors. If I try to put rmsd.h in sources, it says it doesnt recognize the file type.

How to link custom C (which itself needs special linking options to compile) with Cython?

This looks somewhat promising but im not sure how to use it.

Please help!

Community
  • 1
  • 1
rohanp
  • 610
  • 1
  • 8
  • 20

1 Answers1

4

First of all it has to find the include file, rsmd.h. You need to add the path where this header can be found to the include_dirs parameter. The error about the missing file should disappear.

Then you will additionally need to include the library you get from compiling that C code. If that's librsmd.a you would add 'rsmd' to the libraries parameter. Additionally you might need a library_dirs parameter that contains the path where that library can be found.

sth
  • 222,467
  • 53
  • 283
  • 367
  • rmsd.h is in the same directory as the rest of my files, so i set include_dirs to include_dirs = [np.get_include(), '.'], but I still get the missing file error – rohanp Jul 07 '15 at 22:06
  • Does it work if you specify the complete path? The setup script might compile in a different directory, like a `build/` subdir, maybe that's a problem. – sth Jul 07 '15 at 22:16
  • Changing it to a complete path worked! (I also had to fix a typo). I now have new errors in the compilation of rmsd.h, but I will try to figure those out. thank you! – rohanp Jul 07 '15 at 22:54
  • @sth What should be done with the library file librsmd.a? If I follow what you suggested, it comes up with the error saying that -lrsmd is not a recognized library. – paulinho Mar 22 '18 at 01:50
  • @paulinho: I assume that means it doesn't find the librsmd.a file. You could try to add a `library_dirs = ['/some/dir']` parameter that contains the directory where the `.a` file is. – sth Mar 22 '18 at 12:58
  • @sth But you would keep the statement libraries = ['rsmd']? What purpose does that serve then? – paulinho Mar 22 '18 at 13:32
  • @paulinho `libraries` says what libraries to use, `library_dirs` says in which directories to search for them. – sth Mar 22 '18 at 14:59