尝试使用distutils交叉编译mingw32的SWIG Python扩展时出错

尝试使用distutils交叉编译mingw32的SWIG Python扩展时出错,第1张

尝试使用distutils交叉编译mingw32的SWIG Python扩展时出错

使用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发行版中获得两件事:

  1. python27.dll(通常放置在c: windows system32或c: windows syswow64中)
  2. “ 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可以通过 *** 纵路径来找到正确的包含文件和库来进行链接。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5662105.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存