将Python编译为WebAssembly [英] Compiling Python to WebAssembly

查看:231
本文介绍了将Python编译为WebAssembly的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经知道可以将Python 2.7代码转换为Web Assembly,但是我找不到关于如何这样做的权威指南.

I have read that it is possible to convert Python 2.7 code to Web Assembly, but I cannot find a definitive guide on how to to so.

到目前为止,我已经使用Emscripten及其所有必要组件将C程序编译为Web程序,因此我知道它是有效的(使用指南:

So far I have compiled a C program to Web Assembly using Emscripten and all its necessary components, so I know it is working (guide used: http://webassembly.org/getting-started/developers-guide/)

要在Ubuntu计算机上执行此操作,我必须采取哪些步骤?我是否必须将python代码转换为LLVM位代码,然后使用Emscripten对其进行编译?如果是这样,我将如何实现?

What are the steps I must take in order to do this on an Ubuntu machine? Do I have to convert the python code to LLVM bitcode then compile it using Emscripten? If so, how would I achieve this?

推荐答案

WebAssembly与asm.js

首先,让我们来看一下 WebAssembly asm.js 的区别,以及是否有可能重用现有的知识和工具.以下内容提供了很好的概述:

WebAssembly vs asm.js

First, let's take a look how, in principle, WebAssembly is different from asm.js, and whether there's potential to reuse existing knowledge and tooling. The following gives pretty good overview:

我们概括一下WebAssembly(MVP,因为有关其路线图,大致):

Let's recapitulate, WebAssembly (MVP, as there's more on its roadmap, roughly):

  • 是具有静态类型的AST的二进制格式,可以由现有的JavaScript引擎(因此可以进行JIT或已编译的AOT)执行,
  • 与JavaScript相比,它的压缩程度(压缩比较)提高了10-20%,并且解析速度快了一个数量级,
  • 它可以表达不适合JavaScript语法的更多底层操作,读取asm.js(例如64位整数,特殊的CPU指令,SIMD等)
  • 在某种程度上可以与asm.js转换.

因此,当前WebAssembly是asm.js的迭代,并且仅针对C/C ++(和类似语言).

Thus, currently WebAssembly is an iteration on asm.js and targets only C/C++ (and similar languages).

看起来GC并不是唯一阻止Python代码定位WebAssembly/asm.js的东西.两者都代表低级的静态类型代码,在其中无法(实际)表示Python代码.由于WebAssembly/asm.js的当前工具链基于LLVM,因此可以轻松地将其编译为LLVM IR的语言可以转换为WebAssembly/asm.js.但是,可惜的是,空腹燕子证明了Python的动态性也无法适应.和对PyPy的多次尝试.

It doesn't look like GC is the only thing that stops Python code from targeting WebAssembly/asm.js. Both represent low-level statically typed code, in which Python code can't (realistically) be represented. As current toolchain of WebAssembly/asm.js is based on LLVM, a language that can be easily compiled to LLVM IR can be converted to WebAssembly/asm.js. But alas, Python is too dynamic to fit into it as well, as proven by Unladen Swallow and several attempts of PyPy.

此asm.js演示文稿具有有关动态语言状态的幻灯片.这意味着当前只能将整个VM(C/C ++中的语言实现)编译为WebAssembly/asm.js并解释(在可能的情况下使用JIT)原始源.对于Python,有几个现有项目:

This asm.js presentation has slides about the state of dynamic languages. What it means is that currently it's only possible to compile whole VM (language implementation in C/C++) to WebAssembly/asm.js and interpret (with JIT where possible) original sources. For Python there're several existing projects:

  1. PyPy: PyPy.js (作者的版本库.JS主文件 pypyjs.vm.js 是13 MB(在 gzip -6 之后为2MB)+ Python stdlib +其他内容.

  1. PyPy: PyPy.js (author's talk at PyCon). Here's release repo. Main JS file, pypyjs.vm.js, is 13 MB (2MB after gzip -6) + Python stdlib + other stuff.

CPython: pyodide CPython-Emscripten EmCPython 等. empython.js 是5.8 MB( gzip -6 ),没有stdlib.

CPython: pyodide, EmPython, CPython-Emscripten, EmCPython, etc. empython.js is 5.8 MB (2.1 MB after gzip -6), no stdlib.

Micropython:这把叉子.

Micropython: this fork.

那里没有构建的JS文件,因此我可以使用 来构建它trzeci/emscripten/ ,现成的Emscripten工具链.像这样:

There was no built JS file there, so I was able to build it with trzeci/emscripten/, a ready-made Emscripten toolchain. Something like:

 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,则后者已经是要考虑的问题.

It produces micropython.js of 1.1 MB (225 KB after gzip -d). The latter is already something to consider, if you need only very compliant implementation without stdlib.

要生成WebAssembly版本,您可以将 Makefile 的第13行更改为

To produce WebAssembly build you can change line 13 of the Makefile to

 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输出,以了解如何使用这些文件.

You can look at HTML output of emcc hello.c -s WASM=1 -o hello.html, to see how to use these files.

通过这种方式,您还可以潜在地在WebAssembly中构建PyPy和CPython,以在兼容的浏览器中解释您的Python应用程序.

This way you can also potentially build PyPy and CPython in WebAssembly to interpret your Python application in a compliant browser.

这里另一个可能有趣的事情是 Nuitka ,这是Python到C ++的编译器.可能有可能将您的Python应用程序构建为C ++,然后将其与带有Emscripten的CPython一起编译.但是实际上我不知道该怎么做.

Another potentially interesting thing here is Nuitka, a Python to C++ compiler. Potentially it can be possible to build your Python app to C++ and then compile it along with CPython with Emscripten. But practically I've no idea how to do it.

就目前而言,如果您要建立一个常规的网站或Web应用程序,而几乎不能选择下载几MB的JS文件,请查看Python到JavaScript的编译器(例如 Brython ).或者尝试与列表中的其他人一起走运可以编译为JavaScript的语言.

For the time being, if you're building a conventional web site or web app where download several-megabyte JS file is barely an option, take a look at Python-to-JavaScript transpilers (e.g. Transcrypt) or JavaScript Python implementations (e.g. Brython). Or try your luck with others from list of languages that compile to JavaScript.

否则,如果下载大小不成问题,并且您已准备好应对很多毛病,请在上述三个选项中进行选择.

Otherwise, if download size is not an issue, and you're ready to tackle a lot of rough edges, choose between the three above.

  1. JavaScript端口已集成到MicroPython中.它住在端口/javascript .

  1. JavaScript port was integrated into MicroPython. It lives in ports/javascript.

该端口可以作为名为 MicroPython.js 的npm软件包使用.您可以在 RunKit 中进行试用.

The port is available as a npm package called MicroPython.js. You can try it out in RunKit.

Rust中有一个积极开发的Python实现,称为 RustPython .因为Rust正式支持 WebAssembly为编译目标,也就不足为奇了,演示链接自述文件的顶部.虽然,这还早.他们的免责声明如下.

There's an actively developed Python implementation in Rust, called RustPython. Because Rust officially supports WebAssembly as compile target, no surprise there's demo link right in the top of the readme. Though, it's early. Their disclaimer follows.

RustPython处于开发阶段,不应在生产或容错设置.

RustPython is in a development phase and should not be used in production or a fault intolerant setting.

我们当前的版本仅支持Python语法的一部分.

Our current build supports only a subset of Python syntax.

这篇关于将Python编译为WebAssembly的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆