使用distutils编译Python模块时,幕后有很多事情发生。您对问题的每次尝试都越来越接近,但是现在遇到的问题是,您正在使用带有Windows(交叉)编译器的Linux头文件。(mingw32不支持sys
/ select.h,但是cygwin可能是另一回事了)。实际上,是由于缺少配置头文件,导致您的交叉编译尝试使用POSIX接口而不是Win32替代方案。
我的回答倒退了几步,开始只是简单地手工构建模块,在Linux上使用mingw32,然后在证明我们具备所有要求之后,将开始使用distutils。
我还假设您没有Windows构建框(甚至是VM)可用于仅在Windows上本机构建扩展,因为这比交叉编译要简单得多。如果您正在阅读本文,并且可以选择使用Windows框来构建Windows
Python扩展,请执行此 *** 作,以节省时间和精力。也就是说,仅使用Linux盒即可构建Windows Python模块。
从已经安装并在Linux机器上工作的mingw32开始(例如使用Debian /
Ubuntu软件包),第一步是获取Windows头文件(或更具体的配置)。我假设您的目标是大多数人在搜索引擎中键入“ python
windows”时获得的构建,所以我从python.org下载Windows
MSI安装程序并从中提取它们。
我们想从Python发行版中获得两件事:
- python27.dll(通常放置在c: windows system32或c: windows syswow64中)
- “ include”目录(通常放置在c: python27 include中)
在Linux下,有几种不同的方法可以解压缩。您可以使用Wine安装MSI文件。我在测试中成功使用了cabextract和7z,例如,使用cabextract:
cabextract /tmp/python-2.7.10.msi -F '*.h'cabextract /tmp/python-2.7.10.msi -F 'python27.dll'
(注意:如果使用7z,则会在另一个名为“ python”的内部存档中找到您真正想要的文件)。
在这一点上,您还可以提取文件“ libpython27.a”,该文件通常位于c: python27 libs
中,但是此文件对于使用mingw32进行链接是不够的,甚至不起作用。
给定头文件,我们现在有足够的能力来编译扩展程序,尽管如上所述,要使mingw32链接到python27.dll,我们需要首先做更多的工作。我们将需要一个名为pexports的工具来列出Python
DLL中所有导出的符号,并让dlltool生成存根库供mingw32链接。我直接下载了pexports,然后使用以下命令将其解压缩:
tar xvf ~/Downloads/pexports-0.47-mingw32-bin.tar.xz
解压缩后,我们将获得一个Windows可执行文件。我在这里的示例中使用Wine来直接运行它;或者,您可以提取源,并将其构建为可在Linux主机上本地运行的工具:
tar xvf ~/Downloads/pexports-0.47-mingw32-src.tar.xz(cd pexports-0.47 && ./configure && make)
或者您也可以使用Python模块pefile(在良好的跨平台上运行)复制该工具的功能,以提取我们关心的导出,如果您也希望避免使用Wine的话。
无论如何,使用pexports都可以生成一个.def文件,其中包含我们需要的dlltool信息:
wine bin/pexports.exe -v python27.dll > python27.def
或者,(如果您已将pexports构建为本机工具),则只需:
./pexports-0.47/pexports -v python27.dll > python27.def
python27.dll是我们之前从.msi文件中提取的文件。
(这是我的pexports参考)
获得.def文件后,您可以使用mingw32 dlltool生成一个.a文件,稍后我们将使用该文件将Python模块链接到:
i586-mingw32msvc-dlltool -A --dllname python27.dll --def python27.def --output-lib libpython27.a
现在,我们可以考虑运行SWIG本身来生成要编译的代码了。我将您的示例界面进一步简化为:
%module test%inline %{int gcd(int x, int y) { int g; g = y; while (x > 0) { g = x; x = y % x; y = g; } return g;}%}
然后在Linux机器上以以下方式运行SWIG:
swig -Wall -python test.i
这生成了我用以下代码编译的test_wrap.c:
i586-mingw32msvc-gcc test_wrap.c -I../include -Wall -Wextra -shared -o _test.pyd ./libpython27.a
这里有一个仅使用Linux构建的Windows Python模块。
为了检查它是否真正运行,我将test.py和_test.pyd复制到Windows框中,然后执行以下 *** 作:
Python 2.7.10 (default, May 23 2015, 09:40:32) [MSC v.1500 32 bit (Intel)] on win32Type "help", "copyright", "credits" or "license" for more information.>>> import test>>> test.gcd(1024, 512)512>>>
现在剩下的就是确保distutils可以通过 *** 纵路径来找到正确的包含文件和库来进行链接。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)