Сборка расширения Python C в Windows - PullRequest
0 голосов
/ 15 декабря 2018

Я пытаюсь собрать небольшой модуль Python на C. Это всего лишь один файл .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

Затем я последовал этот SO ответ и скопировал C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x64\rc.exe и rcdll.dll в C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\x86_amd64\.Это решило проблему со связыванием.

Я потратил несколько дней, пытаясь заставить его работать на Windows, и решение, которое я нашел, довольно сомнительно (то есть я не знаю, почему это не так).я работаю «из коробки», и у меня есть ощущение, что мне не следует перемещать файлы Microsoft EXE и DLL, чтобы это работало).

У меня двоякий вопрос:

  • Неужели нет лучшего или более простого способа создания установщика Windows для расширения Python C?
  • Почему это решение работает и зачем оно нужно?

1 Ответ

0 голосов
/ 16 декабря 2018

Что обычно облегчает компиляцию расширений Python в Linux, чем в Windows, так это то, что при стандартном управлении пакетами в Linux у вас обычно будет установлен тот же компилятор C, который использовался для компиляции самого Python.В Windows у вас есть выбор из нескольких версий Visual Studio, mingw, cygwin.Для Windows я нахожу наиболее простым использование специального пакета Visual C ++ для Python 2.7 от Microsoft , который, в отличие от более новой версии Visual Studio, использованной в заданном вопросе, правильно содержит rc.exe в своем путис компилятором Visual C.Другое решение - установить компиляторы mingw и создать файл distutils.cfg в Lib / distutils в основной папке python с содержимым

[build]
compiler=mingw32

[build_ext]
compiler=mingw32

вместо использования этих компиляторов.Если -static-libgcc-static-libstdc++ для проектов C ++) не будет добавлен во флаги компоновщика, библиотеки DLL для libgcc (и для libstdc ++) должны поставляться с расширением, чтобы оно работало также без установленной / находящейся в пути среды выполнения mingw.

...