使用调试Python安装在Windows上构建Python-C-Extension [英] Building a Python-C-Extension on Windows with a debug Python installation

查看:329
本文介绍了使用调试Python安装在Windows上构建Python-C-Extension的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我从Windows上的源代码构建CPython,则当我想通过点子安装包含C-Extension的软件包时会遇到问题.似乎在链接库时发生了错误.

If I build CPython from source on Windows I encounter problems when I want to pip install a package that contains a C-Extension. It seems like the error happens while linking the libraries.

例如,在安装cython时(但在其他C扩展程序包上也会崩溃,并出现相同的错误):

For example when installing cython (but it also crashes with the same error on other C extension packages):

LINK:致命错误LNK1104:无法打开文件"python38.lib"

LINK : fatal error LNK1104: cannot open file 'python38.lib'

错误:命令'C:\ Program Files(x86)\ Microsoft Visual Studio \ 2019 \ Enterprise \ VC \ Tools \ MSVC \ 14.23.28105 \ bin \ HostX86 \ x86 \ link.exe'失败,退出状态为1104

error: command 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.23.28105\bin\HostX86\x86\link.exe' failed with exit status 1104

无法打开"python38.lib"的原因.是因为".lib"调试模式下的文件称为"python38_d.lib".

The reason why it cannot open the "python38.lib" is because the ".lib" file in debug mode is called "python38_d.lib".

基于 CPython开发人员指南:

git clone --branch v3.8.0 https://github.com/python/cpython.git
cd cpython
git checkout v3.8.0
.\PCbuild\build.bat -e -d
.\PCbuild\win32\python_d.exe -m ensurepip
.\PCbuild\win32\python_d.exe -m pip install pip --upgrade -vv
.\PCbuild\win32\python_d.exe -m pip install setuptools --upgrade -vv
.\PCbuild\win32\python_d.exe -m pip install cython -vv

结果distutils.sysconfig.get_config_vars()为:

{'BINDIR': '...\\cpython\\PCbuild\\win32',
 'BINLIBDEST': ...\\cpython\\Lib',
 'EXE': '.exe',
 'EXT_SUFFIX': '_d.cp38-win32.pyd',
 'INCLUDEPY': '...\\cpython\\include;...\\cpython\\PC',
 'LIBDEST': '...\\cpython\\Lib',
 'SO': '_d.cp38-win32.pyd',
 'VERSION': '38',
 'exec_prefix': '...\\cpython',
 'prefix': '...\\cpython',
 'srcdir': '...\\cpython'}

有什么我想念的吗?是否完全不支持在Windows上的Python调试版本上构建C-Extensions?如果支持,我该怎么办?

Is there something I'm missing? Is building C-Extensions on Python-debug builds on Windows simply not supported? If it is supported: how would I do it?

推荐答案

在Windows上,与pythonXY.lib的链接有些偷偷摸摸.当您查看用于链接的命令行时,您会看到没有python库传递给链接器,即'link.exe'.注意:在Linux上也是如此,但在Linux上则不必这样做,因为所需的符号将由python-executable提供.

Linking against pythonXY.lib is a little bit sneaky on Windows. When you look at the command line for linking, you will see that no python-library is passed to the linker, i.e. 'link.exe`. Note: This is also the case for Linux, but on Linux one doesn't have to because the needed symbols will be provided by the python-executable.

但是,通过 dumpbin /dependents resulting.pyd进行检查很容易,因为它依赖于pythonXY.dll在扩展名定义中添加extra_link_args = ["/VERBOSE:LIB"]并触发链接器的详细模式将显示该链接器使用pythonXY.lib.

However, it is easy to check via dumpbin /dependents resulting.pyd, that there is a dependency on pythonXY.dll, also adding extra_link_args = ["/VERBOSE:LIB"] to extension-definition and triggering verbose-mode of the linker will show that the linker uses pythonXY.lib.

偷偷摸摸的部分:Microsoft Compler具有便利的用法 #pragma comment(lib, ...) 可自动触发库链接,还用于在Python标头中:

The sneaky part: Microsoft Compler has a convinience-pragma #pragma comment(lib, ...) to automatically trigger linking of a library, which is also used in Python-headers:

#               if defined(_MSC_VER)
                        /* So MSVC users need not specify the .lib
                        file in their Makefile (other compilers are
                        generally taken care of by distutils.) */
#                       if defined(_DEBUG)
#                               pragma comment(lib,"python39_d.lib")
#                       elif defined(Py_LIMITED_API)
#                               pragma comment(lib,"python3.lib")
#                       else
#                               pragma comment(lib,"python39.lib")
#                       endif /* _DEBUG */
#               endif /* _MSC_VER */

如您所见,要链接到调试版本,需要定义_DEBUG.

As you can see, to link against the debug version, one needs to define _DEBUG.

,则

_DEBUG由Windows上的distutils自动定义.

_DEBUG is automatically defined by distutils on Windows, if build_ext is called with options --debug, e.g.

python setup.py build_ext -i --debug

可以转换为pip

pip install --global-option build --global-option --debug XXXXX

可以大致解释为:在安装之前,使用选项--debug触发build命令(还包括build_ext -command).

which can be interpreted roughly as: trigger build command (which also includes build_ext-command) with option --debug prior to installing.

构建调试C扩展时的另一种实用性,有在Windows上还有更多功能:

Another subtility when building debug C-extensions, there is more to it on Windows:

#ifdef _DEBUG
#       define Py_DEBUG
#endif

已定义Py_DEBUG宏意味着不可分割的ABI

Having defined Py_DEBUG macro meant incompartible ABIs until Python3.8, because it also assumed Py_TRACE_REFS which leads to different memory layout of PyObject and some additional functionality missing in the release-mode.

但是,从Python3.8开始,也许可以通过提供缺少的pythonXY_d.lib/pythonYX.lib作为链接到另一个版本的符号链接来摆脱它.

However, since Python3.8, one probably can get away with it by providing the missing pythonXY_d.lib/pythonYX.lib as a symlink linking to another version.

这篇关于使用调试Python安装在Windows上构建Python-C-Extension的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆