0

I often cimport C libraries for use in my own Cython modules. Good recent examples are MPFR and GSL. I am however confused how Cython handles *.pxd files, and how I have to comp/link the Cython modules.

Let's say I have someImports.pxd which looks like this

cdef extern from "mpfr.h":
    ctypedef unsigned int mpfr_prec_t
    void mpfr_set_default_prec(mpfr_prec_t prec) nogil

To be able to use this in other modules, the other modules have to comp/link with the MPFR library. If I write a tiny wrapper function (even inline!) in someImports.pyx, then I don't have to do this. I'm talking about basically the extra_compile_args and extra_link_args in my setup.py.

extensions = [Extension("someImports", ["someImports.pyx"],
                        extra_compile_args = ['-lmpfr','-lgmp'],
                        extra_link_args = ['-lmpfr','-lgmp']
                        ),
              Extension("useImports", ["useImports.pyx"],
                        extra_compile_args = ['-lmpfr','-lgmp'], # Need this when no wrapper function in someImports.pyx
                        extra_link_args = ['-lmpfr','-lgmp'] # Need this when no wrapper function in someImports.pyx
                        )
              ]

In useImports.pyx I just cimport the someImports and well, call the functions. Seems to me this is slightly weird behavior, so I think I might be missing something.

The "full" test example can be found in a github https://github.com/oliverhaas/cython_lib_import

oli
  • 659
  • 1
  • 6
  • 18
  • Very related: https://stackoverflow.com/a/58162089/5769463. Your first variant translates more or less to a simple include (and then you need to link library otherwise the definition of the declared functions isn't available, case B in the linked answer) when you wrap the function in pyx-file and use its pxd, you actually postpone the name-resolution until runtime and use the Cython-maschinery for that (case D in the linked answer). – ead Jul 08 '20 at 17:49
  • Thanks for the comment (again, we met like 4 times now I think in the last weeks :) ). I only half understand your linked post for now, but it's nice to know how it works. As a rule of thumb: I probably should try to use case D if possible; small "wrappers" are useful anyway if something needs to be changed. Does this sound right to you, or would you recommend anything else? – oli Jul 08 '20 at 18:01
  • I would recommend to wrap the functionality in a pyx file and expose it in pxd-file to be used other cython-extensions. This might be tedious, but makes the usage of the resulting wrapper very easy. Another thing you should keep in mind: linking static libraries to different extensions is problematic, as singletons are no longer singletons in this case, see for example https://stackoverflow.com/a/45372319/5769463 – ead Jul 08 '20 at 18:21

0 Answers0