简体   繁体   English

使用distutils / setuptools配置扩展模块

[英]Configuring extension modules with distutils/setuptools

I have a Python project with mutiple extension modules written in C, which talk to a third-party library. 我有一个Python项目,其中包含用C编写的多个扩展模块,它们与第三方库进行通信。 However, depending on the user's environment and options some modules should not be built, and some compiler flags should be enabled/disabled. 但是,根据用户的环境和选项,不应构建某些模块,并且应启用/禁用某些编译器标志。 The problem is that I have to build the list of extension modules before I call setup(), and ideally I'd like to use a distutils.Command subclass to handle the user options. 问题是我必须在调用setup()之前构建扩展模块列表,理想情况下我想使用distutils.Command子类来处理用户选项。 Right now I have a few options: 现在我有几个选择:

  1. Require a "python setup.py configure" command be run before building the modules, store the information in a pickle file, and use it to generate the extensions list next time the script runs. 在构建模块之前需要运行“python setup.py configure”命令,将信息存储在pickle文件中,并在下次运行脚本时使用它来生成扩展列表。 This is how my project currently works, which seems quite silly. 这就是我的项目目前的工作方式,这看起来很愚蠢。

  2. Manually scrape options out of sys.argv and use them to build the list. 手动从sys.argv中删除选项并使用它们来构建列表。 This is not a long-term solution because I will eventually want to run some scripts to check the settings before building. 这不是一个长期的解决方案,因为我最终会想要在构建之前运行一些脚本来检查设置。

  3. Subclass build_ext from distutils, do my configuration in the beginning of the run() method (possibly also using options sent via (2)) and directly modify self.distribution.ext_modules before building. 来自distutils的子类build_ext,在run()方法的开头做我的配置(可能还使用通过(2)发送的选项)并在构建之前直接修改self.distribution.ext_modules。 I'm afraid this may confuse setuptools, however, as it may assume the list of extension modules is fixed when setup() is called. 但是,我担心这可能会混淆setuptools,因为它可能会在调用setup()时修复扩展模块列表。 It also means that when setup() is called with a command other than build_ext the list of extension modules is empty. 这也意味着当使用除build_ext之外的命令调用setup()时,扩展模块列表为空。

Is there a preferred way to do this? 有没有一种首选的方法呢?

Is there a preferred way to do this? 有没有一种首选的方法呢?

From my experience working with other people's modules, I can say there is certainly not consensus on the right way to do this. 根据我与其他人的模块合作的经验,我可以说在正确的方法上肯定没有达成共识。

I have tried and rejected subclassing bits of distutils -- I found it fragile and difficult to get working across different Python versions and different systems. 我已经尝试并拒绝了子类的distutils - 我发现它很脆弱,难以在不同的Python版本和不同的系统中工作。

For our code, after trying the types of things you are considering, I have settled on doing detection and configuration right in setup.py before the main call to setup() . 对于我们的代码,尝试类型的你正在考虑的事情后,我已经在主调用前做检测和配置权setup.py入驻setup() This is admittedly a bit ugly, but it means that someone trying compile your stuff has one place to figure out eg why the include path is wrong. 这无疑是有点难看,但这意味着有人尝试编译你的东西有一个地方可以弄清楚为什么包含路径是错误的。 (And they certainly don't need to be experts on distutils internals). (他们当然不需要成为distutils内部的专家)。

My own experience with changing distutils has been weak and shaky, so all I can offer are pointers. 我自己改变distutils的经验一直很弱而且不稳定,所以我能提供的只是指针。 Take a look at numpy. 看看numpy。 That has an entire submodule (numpy.distutils) with ways to work with (or work around) distutils. 这有一个完整的子模块(numpy.distutils),有方法可以处理(或解决)distutils。 Otherwise, ask the distutils mailing list. 否则,请询问distutils邮件列表。

I would subclass distutils.core.Distribution and pass it with distutils.core.setup(distclass=CustomDistribution) - this gives you access to the command-line parameters in the same way that the normal setup has them, and you can do things like adjusting the extensions list in the CustomDistribution.__init__ method. 我会将distutils.core.Distribution子类化并使用distutils.core.setup(distclass=CustomDistribution)传递它 - 这使您可以像正常设置一样访问命令行参数,并且可以执行类似的操作调整CustomDistribution.__init__方法中的扩展名列表。 But I agree with dalke, the way of distutils is full of pain... 但我同意达尔克的说法,因为苦恼的方式充满痛苦......

config命令设计为子类,并由具有类似要求的项目使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM