python distutils不包括SWIG生成的模块

mic*_*oo8 18 c++ python swig distutils rpm

我正在使用distutils从我的项目中创建一个rpm.我有这个目录树:

project/
        my_module/
                 data/file.dat
                 my_module1.py
                 my_module2.py
        src/
            header1.h
            header2.h
            ext_module1.cpp
            ext_module2.cpp
            swig_module.i
        setup.py
        MANIFEST.in
        MANIFEST
Run Code Online (Sandbox Code Playgroud)

我的setup.py:

from distutils.core import setup, Extension

module1 = Extension('my_module._module',
                sources=['src/ext_module1.cpp',
                         'src/ext_module2.cpp',
                         'src/swig_module.i'],
                swig_opts=['-c++', '-py3'],
                include_dirs=[...],
                runtime_library_dirs=[...],
                libraries=[...],
                extra_compile_args=['-Wno-write-strings'])

setup(  name            = 'my_module',
        version         = '0.6',
        author          = 'microo8',
        author_email    = 'magyarvladimir@gmail.com',
        description     = '',
        license         = 'GPLv3',
        url             = '',
        platforms       = ['x86_64'],
        ext_modules     = [module1],
        packages        = ['my_module'],
        package_dir     = {'my_module': 'my_module'},
        package_data    = {'my_module': ['data/*.dat']} )
Run Code Online (Sandbox Code Playgroud)

我的MANIFEST.in档案:

include src/header1.h
include src/header2.h
Run Code Online (Sandbox Code Playgroud)

MANIFEST文件由python3 setup.py sdist.自动生成.当我运行python3 setup.py bdist_rpm它编译并创建正确的rpm包.但问题是,当我在C++源代码上运行SWIG时,它会创建一个module.py包装二进制_module.cpython32-mu.so文件的文件,它是用module_wrap.cpp文件创建的,并且它不会被复制到my_module目录中.

我必须写什么setup.py来自动复制SWIG生成的python模块?

我还有另一个问题:当我安装rpm包时,我希望在一个/usr/bin或多个中创建一个可执行文件来运行应用程序(例如,如果它my_module/my_module1.py是应用程序的启动脚本,那么我可以在bash中运行:$ my_module1).

Mat*_*ain 11

问题是build_py(将python源复制到构建目录)之前build_ext,它运行SWIG.

您可以轻松地对构建命令进行子类化并在订单周围进行交换,因此在尝试复制之前build_ext会生成.module1.pybuild_py

from distutils.command.build import build

class CustomBuild(build):
    sub_commands = [
        ('build_ext', build.has_ext_modules), 
        ('build_py', build.has_pure_modules),
        ('build_clib', build.has_c_libraries), 
        ('build_scripts', build.has_scripts),
    ]

module1 = Extension('_module1', etc...)

setup(
    cmdclass={'build': CustomBuild},
    py_modules=['module1'],
    ext_modules=[module1]
)
Run Code Online (Sandbox Code Playgroud)

但是,这有一个问题:如果您使用的是setuptools,而不仅仅是简单的distutils,则运行python setup.py install将不会运行自定义生成命令.这是因为setuptools install命令实际上并不首先运行build命令,它运行egg_info,然后运行install_lib,它直接运行build_py和build_ext.

所以可能更好的解决方案是继承构建和安装命令,并确保build_ext在两者的开头运行.

from distutils.command.build import build
from setuptools.command.install import install

class CustomBuild(build):
    def run(self):
        self.run_command('build_ext')
        build.run(self)


class CustomInstall(install):
    def run(self):
        self.run_command('build_ext')
        self.do_egg_install()

setup(
    cmdclass={'build': CustomBuild, 'install': CustomInstall},
    py_modules=['module1'],
    ext_modules=[module1]
)
Run Code Online (Sandbox Code Playgroud)

看起来你不必担心build_ext会运行两次.