Distributing a shared library and some C code with a Cython extension module

后端 未结 3 2036
谎友^
谎友^ 2021-01-31 03:23

I\'m trying to take some functions from a large C++ shared library (libbig.so) and expose them to Python via Cython. To do so, I\'ve got a little C++ file (small.cpp) that provi

3条回答
  •  深忆病人
    2021-01-31 03:41

    Here's my tricky solution. The idea is to "hide" the presence of cython until it's installed by the requirements. This can be achieved by lazy evaluation. Here's an example:

    from setuptools import setup, Extension
    
    class lazy_cythonize(list):
        def __init__(self, callback):
            self._list, self.callback = None, callback
        def c_list(self):
            if self._list is None: self._list = self.callback()
            return self._list
        def __iter__(self):
            for e in self.c_list(): yield e
        def __getitem__(self, ii): return self.c_list()[ii]
        def __len__(self): return len(self.c_list())
    
    def extensions():
        from Cython.Build import cythonize
        ext = Extension('native_ext_name', ['your/src/*.pyx'])
        return cythonize([ext])
    
    
    configuration = {
        'name': 'mypackage',
        'packages': ['yourpurepythonpackage'],
        'install_requires': ['cython==0.17'],
        'ext_modules': lazy_cythonize(extensions)
    }
    
    setup(**configuration)
    

    lazy_cythonize is a fake list that generates its internal elements only when someone tries to access to it.
    When it's required, this class imports Cython.Build and generates the list of extensions. This avoids to keep the *.c files in your project, requiring cython to be installed when the module is building.

    Quite tricky, but actually it's working.

提交回复
热议问题