setup.py: run build_ext before anything else

时光怂恿深爱的人放手 提交于 2019-11-27 06:17:33

问题


I'm working with a setup.py that creates a whole bunch of SWIG interface files during the build_ext step. This needs to run first, because subsequent build steps need a full list of the python files to work properly (like copying the python files to the package directory, creating the egg, creating the sources list, etc.).

This is what currently happens when you do setup.py install:

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

The build_py step tries to copy all the python files that it finds to the build directory. Those files don't exist until build_ext runs (swig creates a bunch of .py files).

This answer recommends changing sub_commands but that didn't appear to do anything.

I tried just subclassing the install command class like this to run build_ext before anything else:

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

..and then working it in to setup with cmdclass:

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

But that didn't work because super doesn't work with old-style classes and install apparently doesn't inherit from object.

How do I do build_ext first?


回答1:


For fear of posting on a 2 year old post. I think the correct way to solve this would be to fix it during the "build" phase:

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},
)

That way it works for bdist_wheel as well as install (haven't tested other stuff).

Note the super syntax is a bit different in Python 2:

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



回答2:


It appears the old way of doing super() is forwards-compatible so I just did that:

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}
)


来源:https://stackoverflow.com/questions/29477298/setup-py-run-build-ext-before-anything-else

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!