在Windows上构建Python C扩展

时间:2018-12-15 16:23:44

标签: python c windows pip setuptools

我正在尝试在C中构建一个小的Python模块。它只是一个.C文件,其中包括一个标头文件并链接一个静态库。

在Linux上一切正常,但是我们的团队成员之一使用Windows,因此我也希望为Windows构建此模块。

我正在使用Windows 10并安装了Visual Studio Build Tools 2017,包括用于桌面的VC ++ 2015.3 v14.00(v140)工具集。我正在使用Python 3.6。

from setuptools import setup, Extension

drone_logger_module = Extension('DroneLogger',
                                include_dirs=['Output\\include'],
                                libraries=['DroneLoggerWindows'],
                                library_dirs=['x64\\Release'],
                                sources=['Output\\src\\DroneLogger.py.c'])

setup([...],
      ext_modules=[drone_logger_module])

运行python setup.py bdist_wininst时,得到以下输出:

running bdist_wininst
running build
running build_ext
building 'DroneLogger' extension
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\x86_amd64\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -IOutput\include -IC:\Users\piete\AppData\Local\Programs\Python\Python36\include -IC:\Users\piete\AppData\Local\Programs\Python\Python36\include "-IC:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE" "-IC:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\ATLMFC\INCLUDE" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\include\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\shared" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.17763.0\winrt" /TcOutput\src\DroneLogger.py.c /Fobuild\temp.win-amd64-3.6\Release\Output\src\DroneLogger.py.obj
DroneLogger.py.c
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\x86_amd64\link.exe /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH:x64\Release /LIBPATH:C:\Users\piete\AppData\Local\Programs\Python\Python36\libs /LIBPATH:C:\Users\piete\AppData\Local\Programs\Python\Python36\PCbuild\amd64 "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\LIB\amd64" "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\ATLMFC\LIB\amd64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.17763.0\ucrt\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\lib\um\x64" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.17763.0\um\x64" DroneLoggerWindows.lib /EXPORT:PyInit_DroneLogger build\temp.win-amd64-3.6\Release\Output\src\DroneLogger.py.obj /OUT:build\lib.win-amd64-3.6\DroneLogger.cp36-win_amd64.pyd /IMPLIB:build\temp.win-amd64-3.6\Release\Output\src\DroneLogger.cp36-win_amd64.lib
DroneLogger.py.obj : warning LNK4197: export 'PyInit_DroneLogger' specified multiple times; using first specification
Creating library build\temp.win-amd64-3.6\Release\Output\src\DroneLogger.cp36-win_amd64.lib and object build\temp.win-amd64-3.6\Release\Output\src\DroneLogger.cp36-win_amd64.exp
Generating code
Finished generating code
LINK : fatal error LNK1158: cannot run 'rc.exe'
error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\BIN\\x86_amd64\\link.exe' failed
with exit status 1158

然后,我跟随this SO answer,并将C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x64\rc.exercdll.dll复制到C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\x86_amd64\。这样就解决了链接问题。

我已经花了几天的时间尝试使其在Windows上工作,而我想出的解决方案还是有问题的(也就是说,我不知道为什么它不能立即使用,我有一种感觉,我不应该只是为了使其正常运行而移动Microsoft EXE和DLL。

我的问题是双重的:

  • 为Python C扩展构建Windows安装程序真的没有更好/更便捷的方法吗?
  • 此解决方案为什么起作用,为什么有必要?

1 个答案:

答案 0 :(得分:1)

通常,使Linux上的Python扩展比Windows上编译容易,是因为在Linux上使用标准软件包管理,您通常会安装与用于编译Python本身相同的C编译器。在Windows上,可以选择几种Visual Studio版本,即mingw,cygwin。 对于Windows,我发现使用特殊的Visual C++ for Python 2.7 package from Microsoft是最简单的方法,与所问问题中使用的较新的Visual Studio版本不同,特殊的mingw在其路径中已将rc.exe与Visual C编译器一起正确地放置了。 另一种解决方案是安装{{3}}编译器,并在主python文件夹中的 Lib / distutils 中创建包含内容的文件 distutils.cfg

[build]
compiler=mingw32

[build_ext]
compiler=mingw32

代替使用这些编译器。除非将-static-libgcc(对于C ++项目为-static-libstdc++)添加到链接器标志,否则libgcc(和libstdc ++)的DLL必须随扩展一起提供,这样它也可以在未安装mingw运行时的情况下工作/在路径中。