Developer’s Guide

Dieser Artikel enthält Informationen, die für Personen relevant sind, die zu Emscripten beitragen möchten. Wir freuen uns über Beiträge von jedem, der helfen möchte!

Tipp

Die Informationen sind weniger relevant, wenn Sie Emscripten nur verwenden, könnten aber dennoch von Interesse sein.

Einrichtung

Um zum Kerncode von Emscripten beizutragen, wie z.B. emcc.py, müssen Sie keine Binärdateien erstellen, da emcc.py in Python geschrieben ist und die Kern-JS-Generierung in JavaScript erfolgt. Sie benötigen jedoch weiterhin Binärdateien für LLVM und Binaryen, die Sie mit dem emsdk erhalten können.

emsdk install tot
emsdk activate tot

Dies installiert die neuesten "tip-of-tree"-Binärdateien, die zum Ausführen von Emscripten benötigt werden. Sie können diese vom emsdk bereitgestellten Binärdateien mit einem Git-Checkout des Emscripten-Repositorys verwenden. Dazu können Sie entweder Ihre lokale .emscripten Konfigurationsdatei bearbeiten oder EM_CONFIG=/path/to/emsdk/.emscripten in Ihrer Umgebung setzen.

Wenn Sie zu LLVM oder Binaryen beitragen oder Änderungen an diesen testen möchten, können Sie diese aus dem Quellcode erstellen.

Interessante Repositories und Branches

Das Emscripten-Hauptrepository ist https://github.com/emscripten-core/emscripten.

Neben dem Emscripten-Repo sind die anderen interessanten Codebasen LLVM und Binaryen, die Emscripten aufruft, und haben ihre eigenen Repos.

Patches einreichen

Patches sollten wie üblich auf GitHub als Pull-Requests eingereicht werden.

Beim Einreichen von Patches bitten wir Sie:

  • Fügen Sie einen automatischen Test hinzu, wenn Sie neue Funktionalität hinzufügen oder einen Fehler beheben. Suchen Sie in test/*.py nach verwandten Tests, da es oft am einfachsten ist, einen bestehenden zu erweitern. Wenn Sie sich nicht sicher sind, wie Sie Ihren Code testen sollen, fragen Sie gerne um Hilfe.

  • Beachten Sie unseren Kodierstil, der in .clang-format festgelegt ist.

  • Wir squashen und mergen PRs normalerweise, was bedeutet, dass der PR zu einem einzigen Commit auf dem Ziel-Branch wird. Deswegen ist es in Ordnung, Merge-Commits im PR selbst zu haben, da diese entfernt werden. Bitte geben Sie eine gute Beschreibung für den finalen Commit in der PR-Beschreibung an, und wir werden diese beim Squashen verwenden.

Code-Reviews

Einer der Kernentwickler wird einen Pull-Request vor dem Mergen überprüfen. Wenn mehrere Tage ohne Kommentare zu Ihrem PR vergehen, kommentieren Sie bitte im PR, um die Entwickler zu benachrichtigen. (Wenn das passiert, Entschuldigung! Manchmal werden Dinge übersehen.)

Compiler-Übersicht

Das Emscripten Compiler Frontend (emcc) ist ein Python-Skript, das den gesamten Kompilierungsprozess verwaltet.

  • emcc ruft Clang auf, um C++ zu kompilieren, und wasm-ld, um es zu verlinken. Es erstellt und integriert sich mit den Emscripten-Systembibliotheken, sowohl den kompilierten als auch den in JS implementierten.

  • emcc ruft dann emscripten.py auf, das die endgültige Transformation zu Wasm (einschließlich des Aufrufs von wasm-emscripten-finalize von Binaryen) durchführt und den JS-Compiler aufruft (siehe src/compiler.mjs und verwandte Dateien), der das JS ausgibt.

  • Bei der Optimierung von Wasm ruft emcc dann wasm-opt auf, führt Meta-DCE und andere nützliche Dinge aus. Es führt auch JS-Optimierungen für das JS durch, das zusammen mit dem Wasm ausgegeben wird.

Emscripten Test-Suite

Emscripten verfügt über eine umfassende Testsuite, die praktisch alle Emscripten-Funktionen abdeckt. Diese Tests werden automatisch in CI ausgeführt, wenn Sie einen Pull-Request erstellen, und sie sollten alle bestehen. Wenn Sie Probleme mit einem Testfehler haben, den Sie nicht beheben können, informieren Sie bitte die Entwickler.

Bisecting

Wenn Sie eine Regression finden, ist Bisektion oft der schnellste Weg, um herauszufinden, was schief gelaufen ist. Dies gilt nicht nur für die Suche nach einer tatsächlichen Regression in Emscripten, sondern auch, wenn Ihr Projekt nach einem Upgrade nicht mehr funktioniert und Sie untersuchen müssen, ob es sich um eine Emscripten-Regression oder etwas anderes handelt. Der Rest dieses Abschnitts behandelt die Bisektion auf Emscripten selbst. Er ist hoffentlich sowohl für Personen, die Emscripten verwenden, als auch für Emscripten-Entwickler nützlich.

Wenn Sie einen großen Bisektionsbereich haben – zum Beispiel, der mehr als eine Emscripten-Version abdeckt –, dann haben Sie wahrscheinlich Änderungen in mehreren Repos (Emscripten, LLVM und Binaryen). In diesem Fall ist es am einfachsten und schnellsten, die Bisektion mit emsdk-Builds durchzuführen. Jeder Schritt der Bisektion lädt einen Build herunter, der von den Emscripten-Release-Buildern erstellt wurde. Mit diesem Ansatz müssen Sie nichts selbst kompilieren, sodass es sehr schnell sein kann!

Dazu benötigen Sie ein grundlegendes Verständnis des Emscripten Release-Prozesses. Die Hauptidee ist, dass

emsdk install [HASH]

Sie können einen beliebigen Emscripten-Build von jedem Zeitpunkt in der Vergangenheit installieren (vorausgesetzt, der Build war erfolgreich). Jeder Build wird durch einen Hash (eine lange Zeichenkette aus Zahlen und Zeichen) identifiziert, der ein Hash eines Commits im Releases-Repo ist. Die Zuordnung von Emscripten-Versionsnummern zu solchen Hashes wird durch emscripten-releases-tags.json im emsdk-Repo verfolgt.

Vor diesem Hintergrund würde der Bisektionsprozess wie folgt aussehen:

  1. Finden Sie die Hashes, zwischen denen bisectiert werden soll. Möglicherweise kennen Sie sie bereits, wenn Sie das Problem bei tot-Builds gefunden haben. Wenn Sie stattdessen nur Emscripten-Versionsnummern kennen, verwenden Sie emscripten-releases-tags.json, um die Hashes zu finden.

  2. Verwenden Sie diese Hashes, um ein normales git bisect im emscripten-releases Repo durchzuführen.

  3. Laden Sie bei jedem Schritt der Bisektion den Binär-Build für den aktuellen Commit-Hash (im emscripten-releases-Repo, auf dem Sie bisectieren) mit emsdk install HASH herunter. Testen Sie dann Ihren Code und führen Sie git bisect good oder git bisect bad entsprechend aus und fahren Sie mit der Bisektion fort, bis Sie den ersten fehlerhaften Commit finden.

Der erste fehlerhafte Commit ist eine einzelne Änderung im Releases-Repo. Dieser Commit aktualisiert im Allgemeinen ein einzelnes Sub-Repo (Emscripten, LLVM oder Binaryen), um eine oder mehrere neue Änderungen hinzuzufügen. Oft ist diese Liste sehr kurz oder sogar ein einzelner Commit, und Sie können sehen, welcher tatsächliche Commit das Problem verursacht hat. Beim Einreichen eines Fehlers kann die Erwähnung eines solchen Bisektionsergebnisses die Dinge erheblich beschleunigen (selbst wenn dieser Commit mehrere Änderungen enthält).

Wenn dieser Commit mehrere Änderungen enthält, können Sie optional weitere Bisektionen im spezifischen Repo durchführen (da alle Änderungen normalerweise in nur einem davon liegen, während die anderen unverändert bleiben). Dies erfordert ein lokales Neubuilden, was bei der in diesem Abschnitt beschriebenen Hauptbisektion nicht erforderlich war.

Arbeiten mit C-Strukturen und Defines

Wenn Sie das Layout von C-Strukturen ändern oder C-Defines modifizieren, die in JavaScript-Bibliotheksdateien verwendet werden, müssen Sie möglicherweise tools/struct_info.json anpassen. Jedes Mal, wenn diese Datei geändert oder ein Struktur-Layout geändert wird, müssen Sie ./tools/gen_struct_info.py ausführen, um die von JavaScript verwendeten Informationen neu zu generieren. Beachten Sie, dass Sie sowohl ./tools/gen_struct_info.py als auch ./tools/gen_struct_info.py --wasm64 ausführen müssen.

Der Test test_gen_struct_info schlägt fehl, wenn Sie dies vergessen.

Siehe auch