Linux for Windows上的交叉编译扩展

时间:2018-01-30 09:31:44

标签: python cython cross-compiling

我已经设法在Linux上构建了一些使用MinGW进行Python扩展所必需的DLL。这些方面的东西:

from setuptools.command.build_py import build_py

class BuildGo(build_py):

    def run(self):
        if # need to build windows binaries
            self.build_win()
        build_py.run(self)

    def build_win(self):
        if # compilers and toolchain available
            try:
                # builds extra libraries necessary for this extension
            except subprocess.CalledProcessError as e:
                print(e.stderr)
                raise
            try:
                result = subprocess.check_output([
                    'x86_64-w64-mingw32-gcc-win32',
                    '-shared',
                    '-pthread',
                    '-o',
                    EXTRA_DLL,
                    FAKE_WIN_BINDINGS,
                    ARCHIVE_GENERATED_IN_PREVIOUS_STEP,
                    '-lwinmm',
                    '-lntdll',
                    '-lws2_32',
                ])
                print(result)
            except subprocess.CalledProcessError as e:
                print(e.stderr)
                raise

我现在希望我可以避免以同样痛苦的方式扩展build_ext以使其交叉编译Windows的Cython代码......我看到了setuptools的优雅相互作用的深渊,distutilscython“,在深渊有机会回顾我之前......难道没有办法只指定一些标志......就像编译器和Python的名字一样所需平台的二进制文件......它会这样做吗?

我读过这篇文章:http://whatschrisdoing.com/blog/2009/10/16/cross-compiling-python-extensions/ - 差不多10岁了。它只是让我想哭......自写完以来有什么变化吗?或者这些步骤或多或少是我为编译平台而不是我正在运行的平台所要做的事情?

或者,网上有一个示例项目吗?

目标

我的最终目标是生成一个egg包,其中包含PE和ELF二进制文件,并在pip或{{1}安装时将它们安装在任一平台上的正确位置}。它应该在Linux上编译(在MS Windows上编译它不是必需的)。

3 个答案:

答案 0 :(得分:1)

我将此作为社区维基发布,因为这是一个非常令人不满意的答案:它只是告诉你为什么它很难而不是提供真正的解决方案。

Windows上的官方Python发行版是compiled with Microsoft Visual C (MSVC),在编译Python扩展时,通常需要使用与编译Python相同的版本。这表明精确的编译器匹配非常重要。

可以获得使用Mingw编译的Python版本,然后这些版本将与使用Mingw编译的模块兼容。这可能会在Linux上作为交叉编译器工作,但这些模块仅对具有此自定义Python构建的人的一小部分人有用(因此无法创建有用的可分发.egg文件)。

一个合理的努力也是制作一个可以在Windows上构建兼容的Python扩展的Mingw版本:https://mingwpy.github.io/(我认为还https://anaconda.org/msys2/m2w64-toolchain)。这方面的主要驱动因素似乎是缺乏与MSVC兼容的免费Fortran Fortran编译器,因此构建Fortran模块的能力非常有用。根据我的经验,mingwpy工具链工作得很好,直到Python 3.4切换到更新版本的MSVC时a whole exciting new set compatibility issuesthis answer

我的感觉是,任何可行的解决方案都可能基于这些主要用于Windows的Mingw编译器。

答案 1 :(得分:1)

根据https://docs.python.org/3/distutils/builtdist.htmldistutils仅支持win32win_amd64之间在3.7win32/64之间的交叉编译。

此外,building extensions with compilers other than the MSVC that Python is built with is not officially supported

从理论上讲,有可能通过获得type 'a list1 = A | B of 'a * 'a list1 let fold folder (state : 'State) list = let rec loop s = function | A -> s | B(x : 'T, xs) -> loop (folder s x) xs loop state list // val fold : // folder:('State -> 'T -> 'State) -> state:'State -> list:'T list1 -> 'State B(1, B(2, B(3, B(4, A)))) |> fold (+) 0 // val it : int = 10 的Linux工具链(包括必要的标头和链接库),一套要与Windows二进制文件进行链接的必要Python,然后是forge compiler and linker paths and/or options in setup.py-仍然是不受支持的设置。

因此,使用Windows VM或在线构建服务(如AppVeyor)会更好。

答案 2 :(得分:0)

我曾经遇到过同样的问题,但是我只是使用虚拟机来编译我最痛苦的Microsoft依赖程序。

https://developer.microsoft.com/en-us/windows/downloads/virtual-machines

如果您无权访问Windows机器,或者您的程序使用非常特定的机器,例如优化的fortran编译器或某些POSIX依赖的东西或VS可再发行版本中的最新功能,则最好尝试基于虚拟机的编译系统。