Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Distribute pre-compiled python extension module with distutils

Quick one today: I'm learning the in's and out's of Pythons distutils library, and I would like to include a python extension module (.pyd) with my package. I know of course that the recommended way is to have distutils compile the extension at the time the package is created, but this is a fairly complex extension spanning many source files and referencing several external libs so it's going to take some significant playing to get everything working right.

In the meantime I have a known working build of the extension coming out of Visual Studio, and would like to use it in the installer as a temporary solution to allow me to focus on other issues. I can't specify it as a module, however, since those apparently must have an explicit .py extension. How could I indicate in my setup.py that I want to include a pre-compiled extension module?

(Python 3.1, if it matters)

like image 685
Toji Avatar asked Mar 15 '10 02:03

Toji


People also ask

Is Distutils deprecated?

distutils has been deprecated in NumPy 1.23. 0 . It will be removed for Python 3.12; for Python <= 3.11 it will not be removed until 2 years after the Python 3.12 release (Oct 2025).

What does Distutils mean in python?

The distutils package provides support for building and installing additional modules into a Python installation. The new modules may be either 100%-pure Python, or may be extension modules written in C, or may be collections of Python packages which include modules coded in both Python and C.

Does python come with setuptools?

Usually, Yes. the setuptools is not part of the python vanilla codebase, hence not a vanilla modules. python.org installers or mac homebrew will install it for you, but if someone compile the python by himself or install it on some linux distribution he may not get it and will need to install it by himself.


2 Answers

Try a manifest template:

http://docs.python.org/distutils/sourcedist.html#specifying-the-files-to-distribute

like image 195
lunixbochs Avatar answered Oct 01 '22 16:10

lunixbochs


I solved this by overriding Extension.build_extension:

setup_args = { ... }
if platform.system() == 'Windows':
    class my_build_ext(build_ext):
        def build_extension(self, ext):
            ''' Copies the already-compiled pyd
            '''
            import shutil
            import os.path
            try:
                os.makedirs(os.path.dirname(self.get_ext_fullpath(ext.name)))
            except WindowsError, e:
                if e.winerror != 183: # already exists
                    raise


            shutil.copyfile(os.path.join(this_dir, r'..\..\bin\Python%d%d\my.pyd' % sys.version_info[0:2]), self.get_ext_fullpath(ext.name))

    setup_args['cmdclass'] = {'build_ext': my_build_ext }

setup(**setup_args)
like image 40
Kevin Smyth Avatar answered Oct 01 '22 18:10

Kevin Smyth