【问题标题】:Compile python extension for different C++ runtime为不同的 C++ 运行时编译 python 扩展
【发布时间】:2019-02-21 10:49:23
【问题描述】:

我正在为 plex 媒体服务器开发一个插件。 Plex 使用 Python 2.7 作为插件系统。我需要使用python-levenshtein包,需要针对不同的系统进行编译。

我找到了 python-Levenshtein 轮子(manylinux、macos、arm、windows),但是使用 VS 2008 编译的 Windows 轮子(msvcr90.dll)。并用VS 2013(msvcr130.dll)编译的plex嵌入python。

在 Windows 10 上如何编译具有不同 VS 运行时的 python 包?

【问题讨论】:

  • 我假设你的意思是 msvcr120.dll,因为 VS 2013 实际上是 12.0 版(从来没有发布过 msvcr130.dll - 版本直接跳到 14.0 并且 CRT 变成了 vcruntime140.dllucrtbase.dll)

标签: python windows visual-c++


【解决方案1】:

注意: Python 团队不支持为官方版本以外的 Python 版本编译扩展,并且必须得到产品(在本例中为 Plex)的支持。因此,假设 Plex 没有提供这样做的方法,那么下面的所有内容都是黑客和解决方法。

此外,如果库开发人员没有进行构建,那么您正在尝试为他们提供帮助,这意味着您基本上处于他们的“级别”,并且需要像他们一样了解他们的代码。欢迎使用开源软件 :)

最后,这仅适用于旧版 Python 2。如果有人在 Python 3.5 或更高版本上阅读本文,只需安装最新的 Visual Studio 并使用最新的编译器 - 整个 14.x 行都兼容并且可以正常使用最近的 Python 版本。


假设您对扩展如何与 C 运行时交互非常小心,那么针对“错误的”C 运行时版本编译扩展通常是安全的。这里需要注意的是:

  • 分配将由 Python 释放的内存
  • 释放由 Python 分配的内存
  • 向/从 Python 传递/获取文件描述符或 FILE* 指针
  • 设置任何全局设置,例如编码或区域设置
  • 写入标准流

如果所有这些都是隔离的,那么您最终只会在内存中拥有两个 C 运行时,并且它们不会尝试交互。


现在,如果由于某种原因无法做到这一点,您可以尝试使用更高版本的工具集来编译扩展。最简单的方法是:

  • 获取源代码(我假设基于setup.py 通过wheel 构建)
  • 打开 VS 2013 开发者命令提示符
  • 运行set DISTUTILS_USE_SDK=1(这将绕过MSVC检测)
  • 运行 set MSSdk=1(还需要绕过旧版 Python 2 上的检测)
  • 运行python setup.py bdist_wheel(您可能需要先将wheel 安装到Python 中)

现在您可以按照通常的方式获取 wheel 文件并安装它,可能是通过提取/复制文件或将完整文件名传递给 pip

一般来说,简单地构建扩展程序不会成功的可能性非常高。在这种情况下,您必须修改源代码才能正常工作 - 在 VC 9.0 和 VC 12.0 之间的三个 MSVC 版本中,很多名称已被弃用和删除,因此您不会看到其中任何一个的弃用警告。

如果库开发人员已经让他们的库与 Python 3 一起工作,那么许多修复应该已经存在,但可能不会被检测到(因为 Python 3 使用了不需要修复的 VC 10.0,或者使用了 VC 14.0)。 x,可能会被检测为_MSC_VER >= 1900,并且不会检测到 VC 12.0)。如果您贡献您所做的任何修复以帮助下一个人,他们可能会很感激,但是许多库开发人员现在正在放弃对 3.5 之前的 Python 版本的支持,因此他们可能对维护旧版支持不感兴趣。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-04
    • 1970-01-01
    • 1970-01-01
    • 2019-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多