使用调试Python安装在Windows上构建Python-C-Extension [英] Building a Python-C-Extension on Windows with a debug Python installation
问题描述
如果我从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 Py_TRACE_REFS
,这导致PyObject
的内存布局不同,并且释放模式中缺少一些其他功能.
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屋!