setup.py:在其他任何事情之前运行build_ext

时间:2015-04-06 18:32:56

标签: python swig setuptools distutils setup.py

我正在使用setup.py,它在build_ext步骤中创建了一大堆SWIG接口文件。这需要先运行,因为后续的构建步骤需要一个完整的python文件列表才能正常工作(比如将python文件复制到包目录,创建egg,创建源列表等)。

当您执行setup.py install时,这是当前发生的事情:

running install
running bdist_egg
running egg_info
running install_lib
running build_py
running build_ext

build_py步骤尝试将找到的所有python文件复制到构建目录。这些文件在build_ext运行之前不存在(swig会创建一堆.py文件)。

This answer建议更改sub_commands,但似乎没有做任何事情。

我试着像这样继承install命令类,在其他任何事情之前运行build_ext

class Build_ext_first(setuptools.command.install.install):
    def run(self):
        self.run_command("build_ext")
        super(Build_ext_first, self).run()

..然后使用cmdclass进行设置:

setup(
    ...
    cmdclass = {'install' : Build_ext_first}
)

但这不起作用,因为super不适用于旧式课程,install显然不会从object继承。

我如何先build_ext

2 个答案:

答案 0 :(得分:5)

担心发布在2岁的帖子上。我认为解决这个问题的正确方法是在“构建”阶段修复它:

from setuptools import setup, find_packages, Extension
from setuptools.command.build_py import build_py as _build_py    

class build_py(_build_py):
    def run(self):
        self.run_command("build_ext")
        return super().run()

setup(...,
    cmdclass = {'build_py' : build_py},
)

这样它适用于bdist_wheel以及安装(尚未测试其他东西)。

注意{2}中的super语法略有不同:

class build_py(_build_py):
    def run(self):
        self.run_command("build_ext")
        return _build_py.run(self)

答案 1 :(得分:4)

看起来执行super()的旧方法是向前兼容所以我只是这样做了:

class Build_ext_first(setuptools.command.install.install):
    def run(self):
        self.run_command("build_ext")
        return setuptools.command.install.install.run(self)


setup(
    ...,
    cmdclass = {'install' : Build_ext_first}
)