使用distutils/setuptools配置扩展模块

6 投票
4 回答
2149 浏览
提问于 2025-04-15 17:11

我有一个用Python写的项目,里面有多个用C语言写的扩展模块,这些模块需要和一个第三方库进行沟通。不过,根据用户的环境和选项,有些模块可能不需要构建,还有一些编译选项需要开启或关闭。问题是,我必须在调用setup()之前先准备好扩展模块的列表,理想情况下,我想用distutils.Command的子类来处理用户的选项。目前我有几个选择:

  1. 要求用户在构建模块之前先运行“python setup.py configure”命令,把信息存储在一个pickle文件里,下次脚本运行时用这个文件生成扩展模块的列表。这是我项目现在的做法,感觉有点傻。

  2. 手动从sys.argv中提取选项,然后用这些选项来构建列表。这不是一个长久之计,因为我最终会想运行一些脚本来检查设置,然后再进行构建。

  3. 从distutils中继承build_ext,在run()方法开始时进行配置(可能还会使用第二种方法传来的选项),然后在构建之前直接修改self.distribution.ext_modules。我担心这样会让setuptools感到困惑,因为它可能会认为在调用setup()时扩展模块的列表是固定的。而且这也意味着如果调用setup()时不是build_ext命令,扩展模块的列表会是空的。

有没有更好的方法来解决这个问题呢?

4 个回答

0

我自己在修改distutils方面的经验不太丰富,所以只能给一些建议。你可以看看numpy。它里面有一个专门的子模块(numpy.distutils),提供了处理(或者绕过)distutils的方法。如果还有问题,可以去问distutils的邮件列表。

0

我会创建一个叫做CustomDistribution的子类,继承自distutils.core.Distribution,然后用distutils.core.setup(distclass=CustomDistribution)来调用它。这样你就可以像正常的设置那样,使用命令行参数了。你还可以在CustomDistribution.__init__方法里调整扩展列表。不过我同意dalke的看法,使用distutils的过程确实很麻烦...

1

有没有什么推荐的方法来做这个?

根据我和其他人的模块合作的经验,我可以说,大家对怎么做这件事并没有统一的看法。

我尝试过从distutils中继承一些功能,但发现这样做很脆弱,而且在不同的Python版本和系统上都很难搞定。

对于我们的代码,在尝试了你考虑的那些方法后,我决定在setup.py文件中直接进行检测和配置,放在调用setup()之前。虽然这样做有点丑陋,但这意味着想要编译你代码的人只需在一个地方就能搞清楚,比如为什么包含路径不对。(而且他们根本不需要对distutils的内部工作有深入了解。)

撰写回答