使用distutils分发预编译的python扩展模块

时间:2010-03-15 02:14:42

标签: python python-3.x distutils

今天快点:我正在学习Pythons distutils库的内外版本,我想在我的软件包中加入一个python扩展模块(.pyd)。我当然知道推荐的方法是让distutils在创建包时编译扩展,但这是一个相当复杂的扩展,涵盖了许多源文件并引用了几个外部库,所以它需要一些重要的播放来获取所有内容正常工作。

与此同时,我有一个已知的Visual Studio扩展工作版本,并希望在安装程序中将其用作临时解决方案,以便让我专注于其他问题。但是,我无法将其指定为模块,因为那些显然必须具有明确的.py扩展名。我怎么能在setup.py中指出我想要包含一个预编译的扩展模块?

(Python 3.1,如果重要的话)

4 个答案:

答案 0 :(得分:7)

答案 1 :(得分:6)

我通过覆盖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)

答案 2 :(得分:1)

在使用Python 3.7,CMake 3.15.3和Swig 4.0.1和Visual Studio 2017构建扩展库时,我遇到了同样的问题。构建系统生成三个文件:mymodule.py,_mymodule.lib和_mymodule.pyd 。经过一堆反复的试验,我发现以下组合可以正常工作:

  1. 创建一个“ setup.cfg”文件,该文件指定您正在安装软件包;例如:
    [metadata]
    name = mymodule
    version = 1.0

    [options]
    include_package_data = True
    package_dir=
        =src
    packages=mymodule
    python_requires '>=3.7'

    [options.package_data]
    * = *.pyd
  1. 更改CMake以创建分发目录结构,如下所示:
    setup.py
    setup.cfg
    src/
        mymodule/
                 __init__.py
                 _mymodule.pyd
  1. 然后,“ setup.py”文件变得微不足道:
    setup()

这需要CMake将“ mymodule.py”输出文件重命名为“ init .py”。我是通过CMake中的“安装”命令完成此操作的:


    install (TARGETS ${SWIG_MODULE_${PROJECT_NAME}_REAL_NAME} DESTINATION "${CMAKE_BINARY_DIR}/dist/src/${PROJECT_NAME}")
    install (FILES 
            setup.py
            setup.cfg
            DESTINATION "${CMAKE_BINARY_DIR}/dist"
    )

    install (FILES
            ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.py
            DESTINATION "${CMAKE_BINARY_DIR}/dist/src/${PROJECT_NAME}"
            RENAME "__init__.py"

我相信这项工作的关键秘诀是将构建输出重组为Python软件包,而不是尝试使用默认的Build输出作为Python脚本进行安装。

答案 3 :(得分:0)