Python'u WebAssembly için Derleme


95

Python 2.7 kodunu Web Assembly'ye dönüştürmenin mümkün olduğunu okudum, ancak bunun nasıl yapılacağına dair kesin bir kılavuz bulamıyorum.

Şimdiye kadar Emscripten ve tüm gerekli bileşenlerini kullanarak Web Assembly için bir C programı derledim, bu yüzden çalıştığını biliyorum (kullanılan kılavuz: http://webassembly.org/getting-started/developers-guide/ )

Bunu bir Ubuntu makinesinde yapmak için atmam gereken adımlar nelerdir? Python kodunu LLVM bit koduna dönüştürüp ardından Emscripten kullanarak derlemem gerekir mi? Öyleyse bunu nasıl başarabilirim?




1
Pyodide, Python çalışma zamanını WebAssembly aracılığıyla tarayıcıya getiriyor: github.com/iodide-project/pyodide
guettli

Yanıtlar:


149

WebAssembly vs asm.js

İlk olarak, WebAssembly’ın prensip olarak asm.js’den nasıl farklı olduğuna ve mevcut bilgi ve araçları yeniden kullanma potansiyeli olup olmadığına bir bakalım . Aşağıdakiler oldukça iyi bir genel bakış sağlar:

Özetleyelim, WebAssembly (MVP, yol haritasında daha fazlası olduğu için kabaca):

  • mevcut JavaScript motorları (ve dolayısıyla JIT uyumlu veya derlenmiş AOT) tarafından yürütülebilen statik tiplemeli bir ikili AST formatıdır,
  • % 10-20 daha kompakttır (gzip ile sıkıştırılmış karşılaştırma) ve ayrıştırılması JavaScript'ten daha hızlıdır,
  • JavaScript sözdizimine uymayan daha düşük seviyeli işlemleri ifade edebilir, asm.js okuyabilir (örn. 64 bit tam sayılar, özel CPU talimatları, SIMD, vb.)
  • asm.js'ye (bir dereceye kadar) dönüştürülebilir.

Bu nedenle, şu anda WebAssembly asm.js üzerinde bir yinelemedir ve yalnızca C / C ++ (ve benzer dilleri) hedefler.

Web'de Python

Python kodunun WebAssembly / asm.js'yi hedeflemesini engelleyen tek şey GC gibi görünmüyor. Her ikisi de, Python kodunun (gerçekçi olarak) temsil edilemediği düşük seviyeli statik olarak yazılmış kodu temsil eder. WebAssembly / asm.js'nin mevcut araç zinciri LLVM'ye dayandığından, LLVM IR'ye kolayca derlenebilen bir dil WebAssembly / asm.js'ye dönüştürülebilir. Ancak ne yazık ki, Unladen Swallow ve birkaç PyPy girişimiyle kanıtlandığı gibi Python da buna sığamayacak kadar dinamiktir .

Bu asm.js sunumunda dinamik dillerin durumu hakkında slaytlar vardır . Bunun anlamı, şu anda yalnızca tüm VM'yi (C / C ++ dil uygulaması) WebAssembly / asm.js'ye derlemek ve orijinal kaynakları yorumlamak (mümkün olduğunda JIT ile) mümkündür. Python için birkaç mevcut proje vardır:

  1. PyPy: PyPy.js (yazarın PyCon'daki konuşması ). İşte sürüm deposu . Ana JS dosyası pypyjs.vm.js13 MB (2MB sonra gzip -6) + Python stdlib + diğer şeylerdir.

  2. CPython: pyodide , EmPython , CPython-Emscripten , EmCPython , vb. empython.js5,8 MB (2,1 MB sonra gzip -6), stdlib yok.

  3. Micropython: bu çatal .

    Orada yerleşik bir JS dosyası yoktu, bu yüzden onu trzeci/emscripten/hazır bir Emscripten araç zinciri ile oluşturabildim. Gibi bir şey:

     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.js1.1 MB (sonra 225 KB gzip -d) üretir . Stdlib olmadan yalnızca çok uyumlu bir uygulamaya ihtiyacınız varsa, ikincisi zaten dikkate alınması gereken bir şeydir.

    WebAssembly üretmek amacıyla satır 13 değiştirebilir inşa Makefileetmek

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

    Ardından make -jşunları üretir:

     113 KB micropython.js
     240 KB micropython.wasm
    

    emcc hello.c -s WASM=1 -o hello.htmlBu dosyaların nasıl kullanılacağını görmek için HTML çıktısına bakabilirsiniz .

    Bu şekilde, Python uygulamanızı uyumlu bir tarayıcıda yorumlamak için WebAssembly içinde potansiyel olarak PyPy ve CPython da oluşturabilirsiniz.

Buradaki potansiyel olarak ilginç bir başka şey de Python'dan C ++ 'ya derleyici Nuitka'dır . Potansiyel olarak Python uygulamanızı C ++ 'ya oluşturmak ve daha sonra Emscripten ile CPython ile birlikte derlemek mümkün olabilir. Ama pratikte nasıl yapılacağına dair hiçbir fikrim yok.

Çözümler

Şimdilik, birkaç megabaytlık JS dosyası indirmenin pek mümkün olmadığı geleneksel bir web sitesi veya web uygulaması oluşturuyorsanız, Python'dan JavaScript'e aktarıcılara (örn. Transcrypt ) veya JavaScript Python uygulamalarına ( örn.Brython ). Ya da şansınızı JavaScript'e derleyen diller listesinden başkalarıyla deneyin .

Aksi takdirde, indirme boyutu bir sorun değilse ve birçok pürüzle başa çıkmaya hazırsanız, yukarıdaki üçü arasından seçim yapın.

Q3 2020 güncellemesi

  1. JavaScript portu MicroPython'a entegre edildi. Portlarda / javascript'te yaşıyor .

  2. Bağlantı noktası, MicroPython.js adlı bir npm paketi olarak mevcuttur . Sen bunu deneyebilirsiniz runkit .

  3. Rust'ta RustPython adında aktif olarak geliştirilmiş bir Python uygulaması var . Rust , derleme hedefi olarak WebAssembly'ı resmi olarak desteklediğinden, benioku'nun en üstünde demo bağlantısı olması şaşırtıcı değil. Yine de erken. Feragatnameleri aşağıdaki gibidir.

    RustPython bir geliştirme aşamasındadır ve üretimde veya hataya tahammülsüz bir ortamda kullanılmamalıdır.

    Mevcut yapımız yalnızca bir Python sözdizimi alt kümesini destekler.


2
Bu .js ve .wasm boyutları gerçekten adil değil. Akış sıkıştırması iyi desteklenir ve her ikisinin boyutunu azaltmak için kullanılabilir. Gzip ile sıkıştırılmış aynı dosyalar ne kadar büyük? Bunun dışında iyi cevap.
enigmaticPhysicist

Bu nedenle 2020'de, OP'nin aradığı en yakın şey pirodit gibi görünüyor. Web derlemesindeki Python çalışma zamanıdır (C'yi ve ardından Python'u wasm'ye koymayı varsayardım). Birden fazla kütüphaneyi de destekler. Ayrıca, kullanımı yeterince kolay görünüyor.
David Frick

3

Web derlemesi çöp toplamayı gerçekleştirene kadar bu mümkün olmayacaktır. İlerlemeyi buradan takip edebilirsiniz: https://github.com/WebAssembly/proposals/issues/16


18
Şart değil. GC'yi - ve özellikle Python IIRC tarafından kullanıldığı şekliyle referans sayımını - Wasm'ın üzerine uygulayabilirsiniz. Prensip olarak, CPython'u alıp Emscripten kullanarak Wasm'a derleyebilmelisiniz.
Andreas Rossberg

1
Başlı başına bir proje gibi wasm seslerin üstünde GC CPython uygulanması - OP'sinden My almak onlar mevcut araçların kullanmak istediğini oldu
Malcolm Beyaz

3
Fazladan bir şey yapmanıza gerek yok, derlemek için CPython alın. Zaten RC uygulaması AFAICT içerir.
Andreas Rossberg

3

Kısaca: Aktarıcılar var, ancak herhangi bir Python'u otomatik olarak Web Assembly'ye dönüştüremezsiniz ve uzun bir süre daha yapabileceğinizden şüpheliyim. Teorik olarak diller eşit derecede güçlü ve manuel çeviri her zaman mümkün olsa da, Python çok akıllı bir diller arası derleyici (veya aktarıcı) gerektiren bazı veri yapılarına ve ifade modlarına izin verir [aşağıya bakın]. Python'dan C'ye teknoloji orta derecede olgun olduğu için Python'dan C'ye Web Montajı olabilir, ancak Python'dan C'ye kırılgan olduğu için bu genellikle işe yaramayacaktır (aşağıya bakın).

WebAssembly, http://webassembly.org/docs/high-level-goals/ adresinde görebileceğiniz gibi özellikle C benzeri dilleri hedeflemektedir.

Python'dan C'ye çeviri, uzun süredir geliştirilmekte olan, ancak yine de keyfi Python kodu için çalışmayan PyPy gibi araçlarla yapılabilir. Bunun birkaç nedeni var:

  1. Python bazı çok kullanışlı, soyut ve güzel veri yapılarına sahiptir, ancak bunların statik koda çevrilmesi zordur.
  2. Python, dinamik çöp toplamaya bağlıdır.
  3. Çoğu Python kodu, büyük ölçüde, her birinin kendine özgü tuhaflıkları ve sorunları olan çeşitli kitaplıklara dayanır (C veya hatta assembler gibi).

Python'dan C'ye (veya Python'dan C ++'ya) neden bu kadar zor olduğuna daha dikkatli bakarsanız, bu kısa cevabın ardındaki ayrıntılı nedenleri görebilirsiniz, ancak bence bu, sorunuzun kapsamı dışında.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.