python - 将 Python 编译为 WebAssembly

标签 python emscripten webassembly

我已经读到可以将 Python 2.7 代码转换为 Web Assembly,但我找不到有关如何转换的明确指南。

到目前为止,我已经使用 Emscripten 及其所有必要的组件将 C 程序编译到 Web Assembly,所以我知道它正在工作(使用指南:http://webassembly.org/getting-started/developers-guide/)

为了在 Ubuntu 机器上执行此操作,我必须采取哪些步骤?我是否必须将 python 代码转换为 LLVM bitcode 然后使用 Emscripten 编译它?如果是这样,我将如何实现这一目标?

最佳答案

WebAssembly 与 asm.js
首先,让我们看看原则上 WebAssembly 与 asm.js 有何不同,以及是否有重用现有知识和工具的潜力。下面给出了很好的概述:

  • Why create a new standard when there is already asm.js?
  • What is the difference between asm.js and web assembly?
  • Why WebAssembly is Faster Than asm.js

  • 让我们概括一下,WebAssembly(MVP,因为在 its roadmap 上有更多内容,粗略):
  • 是具有静态类型的 AST 二进制格式,可以由现有的 JavaScript 引擎(因此支持 JIT 或编译的 AOT)执行,
  • 它比 JavaScript 紧凑 10-20%(gzipped 比较)和一个数量级的解析速度,
  • 它可以表达更多不适合 JavaScript 语法的低级操作,读取 asm.js(例如 64 位整数、特殊 CPU 指令、SIMD 等)
  • 可转换(在某种程度上)到/从 asm.js。

  • 因此,目前 WebAssembly 是 asm.js 的一个迭代,并且只针对 C/C++(和类似的语言)。
    网络上的 Python
    看起来 GC 并不是阻止 Python 代码针对 WebAssembly/asm.js 的唯一因素。两者都表示低级静态类型代码,其中无法(实际上)表示 Python 代码。由于当前的 WebAssembly/asm.js 工具链是基于 LLVM 的,因此可以轻松编译为 LLVM IR 的语言可以转换为 WebAssembly/asm.js。但遗憾的是,正如 Unladen Swallow 所证明的那样,Python 太动态了,无法适应它。和 several attempts的 PyPy。
    这个 asm.js 演示文稿有 slides about the state of dynamic languages .这意味着目前只能将整个 VM(C/C++ 语言实现)编译为 WebAssembly/asm.js 并解释(尽可能使用 JIT)原始源。对于 Python,有几个现有项目:
  • PyPy:PyPy.js (作者的 talk at PyCon)。这是release repo .主JS文件,pypyjs.vm.js , 是 13 MB(在 gzip -6 之后为 2MB)+ Python stdlib + 其他东西。
  • CPython:pyodide , EmPython , CPython-Emscripten , EmCPythonempython.js是 5.8 MB(在 gzip -6 之后为 2.1 MB),没有 stdlib。
  • 微蟒:this fork .
    那里没有构建的 JS 文件,所以我可以用 trzeci/emscripten/ 构建它。 ,一个现成的 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 
    
    它产生 micropython.js 1.1 MB(在 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 一起编译。但实际上我不知道该怎么做。
    解决方案
    目前,如果您正在构建一个传统的网站或网络应用程序,其中下载几兆字节的 JS 文件几乎是一种选择,请查看 Python-to-JavaScript 转译器(例如 Transcrypt)或 JavaScript Python 实现(例如 Brython )。或者从 list of languages that compile to JavaScript 与其他人一起试试你的运气.
    否则,如果下载大小不是问题,并且您已准备好解决很多问题,请在上述三个中进行选择。
    2020 年第三季度更新
  • JavaScript 端口 was integrated进入 MicroPython。它住在
    ports/javascript .
  • 该端口可用作名为 MicroPython.js 的 npm 包。 .
    您可以在 RunKit 中试用.
  • 在 Rust 中有一个积极开发的 Python 实现,称为
    RustPython .因为 Rust 官方支持 WebAssembly as compile target ,不出意外还有 demo link就在
    自述文件的顶部。虽然,现在还早。他们的免责声明如下。

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

    Our current build supports only a subset of Python syntax.


  • 关于python - 将 Python 编译为 WebAssembly,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44761748/

    相关文章:

    Python 和 C++ 共享相同的内存资源

    go - go channel 和 goroutines 如何转换为 webassembly?

    c++ - Qt for wasm : error: use of undeclared identifier 'QThreadPool'

    webassembly - 如何在 Vite 中使用嵌入式 Webassembly?

    rust - 使用into_serde反序列化字符串使应用程序 panic

    Python 比较 C API 中的对象

    python - 创建可变数量的变量并从列表中填充它们

    c++ - 在 makefile 中使用 ifeq 编译 C 或 CPP 文件

    javascript - "Assertion failed: you need to wait for the runtime to be ready"在JavaScript中调用C函数时出错

    python - 在 python 的 c 扩展中使用 opencv 时出现问题?