将Python编译为WebAssembly

2024-05-13 07:27:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经了解到可以将Python2.7代码转换为Web程序集,但是我找不到关于如何这样做的明确指南。

到目前为止,我已经使用Emscripten及其所有必需的组件编译了一个C程序到Web程序集,因此我知道它正在工作(使用的指南:http://webassembly.org/getting-started/developers-guide/

为了在Ubuntu机器上完成这项工作,我必须采取哪些步骤?我需要将python代码转换为LLVM位代码,然后使用Emscripten编译它吗?如果是这样,我该如何实现?


Tags: 代码org程序机器webhttpubuntu指南
3条回答

WebAssembly与asm.js

首先,让我们看看,原则上,WebAssemblyasm.js有何不同,以及是否有可能重用现有的知识和工具。以下是很好的概述:

让我们概括一下,WebAssembly(MVP,因为有更多关于its roadmap的内容,大致如下):

  • 是具有静态类型的AST二进制格式,可以由现有的JavaScript引擎执行(因此可以使用JIT或编译AOT)
  • 它比JavaScript紧凑10-20%(gzip比较),解析速度快一个数量级
  • 它可以表示更多不符合JavaScript语法的低级操作,读取asm.js(例如64位整数、特殊CPU指令、SIMD等)
  • 可以(在某种程度上)转换到/从asm.js。

因此,目前WebAssembly是As.js上的迭代,而目标仅是C/C++。

网络上的Python

看起来GC并不是阻止Python代码瞄准WebAssembly/asm.js的唯一方法。两者都表示低级静态类型的代码,其中Python代码不能(实际地)表示。由于当前WebAssembly/asm.js的工具链是基于LLVM的,因此可以将一种易于编译为LLVM-IR的语言转换为WebAssembly/asm.js。但遗憾的是,Python的动态性太强,无法容纳它,PyPy的Unladen Swallowseveral attempts证明了这一点。

这个asm.js演示文稿有slides about the state of dynamic languages。它的意思是,目前只有将VM(语言实现在C/C++中)编译成WebSasMals/as.js,并用可能的JIT解释原始源。对于Python,有几个现有项目:

  1. PyPy:PyPy.js(作者的talk at PyCon)。这是release repo。JS主文件pypyjs.vm.js是13mb(在gzip -6之后是2MB)+Python stdlib+其他东西。
  2. CPython:pyodideEmPythonCPython-EmscriptenEmCPython等,empython.js是5.8mb(在gzip -6之后是2.1MB),没有stdlib。
  3. 微蟒:this fork

    那里没有生成的JS文件,所以我可以用^{}来生成它,这是一个现成的Emscripten工具链。类似于:

    git clone https://github.com/matthewelse/micropython.git
    cd micropython
    docker run --rm -it -v $(pwd):/src trzeci/emscripten bash
    apt-get update && apt-get install -y python3
    cd emscripten
    make -j
    # to run REPL: npm install && nodejs server.js 
    

    它产生1.1 MB的micropython.js(在gzip -d之后225 KB)。如果您只需要非常兼容的实现而不需要stdlib,那么后者已经是需要考虑的了。

    要生成WebAssembly构建,可以将Makefile的第13行更改为

    CC = emcc -s RESERVED_FUNCTION_POINTERS=20 -s WASM=1
    

    然后make -j产生:

    113 KB micropython.js
    240 KB micropython.wasm
    

    您可以查看emcc hello.c -s WASM=1 -o hello.html的HTML输出,了解如何使用这些文件。

    这样,您还可以在WebAssembly中构建PyPy和CPython,以便在兼容的浏览器中解释Python应用程序。

另一个潜在有趣的事情是Nuitka,一个Python到C++编译器。潜在地,可以将您的Python应用程序构建到C++,然后与Emscripten一起使用CPython编译它。但实际上我不知道该怎么做。

解决方案

目前,如果您正在构建一个传统的web站点或web应用程序,而下载几个兆字节的JS文件几乎不是一个选项,那么看看Python到JavaScript的transpiler(例如Transcrypt)或JavaScript-Python实现(例如Brython)。或者和list of languages that compile to JavaScript的其他人碰碰运气。

否则,如果下载大小不是问题,并且您已经准备好处理许多粗糙的边,请在以上三者之间进行选择。

简而言之:您不能将任意的Python转换为Web程序集,我怀疑您在未来很长一段时间内是否能够。解决方法可能是Python-to-C-to-Web程序集,但这通常也行不通,因为Python-to-C是脆弱的(见下文)。

WebAssembly是专门针对C类语言的,您可以在http://webassembly.org/docs/high-level-goals/中看到

从Python到C的转换可以使用PyPy这样的工具来完成,PyPy已经开发了很长时间,但是对于任意的Python代码仍然不起作用。这有几个原因:

  1. Python有一些非常方便、抽象和漂亮的数据结构,但是它们很难转换成静态代码。
  2. Python依赖于动态垃圾收集。
  3. 大多数Python代码在很大程度上依赖于不同的库,每个库都有自己的特点和问题(比如用C编写,甚至是用汇编语言编写)。

如果你仔细研究为什么Python to C(或者Python to C++)如此棘手,你可以看到这个简洁答案背后的详细原因,但我认为这超出了你的问题范围。

在web程序集实现垃圾回收之前,这是不可能的。你可以在这里跟踪进度:https://github.com/WebAssembly/proposals/issues/16

相关问题 更多 >