Attempting to build a cython extension to a python

2019-07-17 06:33发布

问题:

I have attempted to use the answer here to add the building of a cython extension into my package. It currently cythonizes the code to produce a .c file from the .pyx file but doesn't create a shared object .so file, as such when I try to import the package, and one of the modules attempts to import the shared object file it cannot find it.

My setup.py file (this is slightly cut-down) is like so:

from setuptools import setup
from setuptools.extension import Extension
import os
import numpy
from Cython.Build import cythonize

mypackage_root_dir = os.path.dirname(__file__)
with open(os.path.join(mypackage_root_dir, 'requirements.txt')) as requirements_file:
    requirements = requirements_file.read().splitlines()

extensions = [Extension(
    name="package.submodule.foo",
    sources=["package/submodule/foo.pyx"],
    include_dirs=[numpy.get_include()],
    )
]

setup(name='package',
      version=0.1,
      description='...',
      author='my name',
      author_email='my email',
      url="...",

      include_package_data=True,
      packages=['package',
                'package.submodule1',
                'package.submodule2',
                'package.submodule', # the one that uses the pyx file
      ],
      ext_modules = cythonize(extensions),
      install_requires=requirements,
)

How can I fix this such that I can get the setup.py file to build the shared object file when python setup.py install is run?

回答1:

The code in my question was working and building the .so file inside the package/subpackage directory in the install location, however, when I tried to import the package it couldn't find the file. However when I manually moved the file to the location of the root install directory of the package it worked.

It appears to therefore require that the shared object file be in the root directory of the package rather than the submodule directory.

I am able to achieve this by changing the extension definition like so:

extensions = [Extension(
        name="foo",
        sources=["package/submodule/foo.pyx"],
        include_dirs=[numpy.get_include()],
        )
    ]

This puts the .so file in the root install directory.

However I'm not sure why it requires this shared object file to be in the root of the package rather than the subpackage directory as is the case with normal python files.