【问题标题】:Configuring extension modules with distutils/setuptools使用 distutils/setuptools 配置扩展模块
【发布时间】:2010-12-28 04:53:18
【问题描述】:
我有一个 Python 项目,其中包含多个用 C 编写的扩展模块,它们与第三方库通信。但是,根据用户的环境和选项,不应构建某些模块,并且应启用/禁用某些编译器标志。问题是我必须在调用 setup() 之前构建扩展模块列表,理想情况下我想使用 distutils.Command 子类来处理用户选项。现在我有几个选择:
需要在构建模块之前运行“python setup.py configure”命令,将信息存储在 pickle 文件中,并在脚本下次运行时使用它来生成扩展列表。这就是我的项目目前的工作方式,看起来很傻。
从 sys.argv 中手动抓取选项并使用它们来构建列表。这不是一个长期的解决方案,因为我最终会想在构建之前运行一些脚本来检查设置。
distutils 的子类 build_ext,在 run() 方法的开头进行配置(可能还使用通过 (2) 发送的选项)并在构建之前直接修改 self.distribution.ext_modules。但是,我担心这可能会使 setuptools 混淆,因为它可能假定在调用 setup() 时扩展模块列表是固定的。这也意味着当使用 build_ext 以外的命令调用 setup() 时,扩展模块列表为空。
有没有首选的方法来做到这一点?
【问题讨论】:
标签:
python
setuptools
distutils
【解决方案1】:
有没有首选的方法来做到这一点?
根据我使用其他人的模块的经验,我可以说,对于正确的做法,肯定没有共识。
我已经尝试并拒绝了 distutils 的子类化——我发现它很脆弱,很难在不同的 Python 版本和不同的系统中工作。
对于我们的代码,在尝试了您正在考虑的类型之后,我决定在 setup.py 中进行检测和配置,然后再调用
setup()。诚然,这有点难看,但这意味着尝试编译您的东西的人有一个地方可以弄清楚,例如为什么包含路径是错误的。 (而且他们当然不需要成为 distutils 内部的专家)。
【解决方案2】:
我自己在更改 distutils 方面的经验很弱且不稳定,所以我能提供的只是指点。看看numpy。它有一个完整的子模块(numpy.distutils),其中包含使用(或解决)distutils 的方法。否则,请询问 distutils 邮件列表。
【解决方案3】:
我会将distutils.core.Distribution 子类化并使用distutils.core.setup(distclass=CustomDistribution) 传递它 - 这使您可以像正常设置一样访问命令行参数,并且您可以执行诸如调整扩展列表中的操作CustomDistribution.__init__ 方法。但我同意dalke,distutils的方式充满痛苦......
【解决方案4】:
config 命令被设计为子类化并供具有您这样需求的项目使用。