Kompilowanie C i C++ do WebAssembly za pomocą Emscripten

Funkcje internetowe: WebAssembly

Użyj Emscripten, aby skompilować kod C i C++ do modułów WebAssembly (Wasm) o wysokiej wydajności dla przeglądarki.

1. Nowoczesne flagi kompilacji Emscripten

Podczas kompilowania i łączenia za pomocą emcc lub em++ zawsze używaj nowoczesnych flag modułowych:

  • -sEXPORT_ES6: emituje standardową składnię modułu ES6 (import/export) zamiast starszych obiektów globalnych. Spowoduje to automatyczne ustawienie -sMODULARIZE.
  • -sENVIRONMENT=web: usuwa kod środowiska wykonawczego Node.js/powłoki, aby zminimalizować rozmiar pakietu.
  • -sSTRICT: wymusza nowoczesne ustawienia domyślne Emscripten i powoduje błąd w przypadku wycofanych flag.
  • -sALLOW_MEMORY_GROWTH: umożliwia dynamiczne rozszerzanie sterty pamięci liniowej WebAssembly podczas przydzielania pamięci.
  • -Oz (lub -O3) + -flto: optymalizuje pod kątem minimalnego rozmiaru ładunku w kompilacjach do publikacji.

2. Unikaj blokowania wątku głównego

Jeśli wywołanie WebAssembly może zająć dużo czasu (tj. więcej niż kilka milisekund), nie powinno być wywoływane w głównym wątku przeglądarki.

Aby uniknąć uruchamiania takiego kodu w głównym wątku przeglądarki, możesz zastosować kilka rozwiązań:

  1. Uruchom cały program WebAssembly w procesie Web Worker. Często jest to najprostsze rozwiązanie, ponieważ nie wymaga konfigurowania dostępu do SharedArrayBuffer ani zmieniania kodu źródłowego programu.

  2. Używaj pthreads lub Wasm Workers. Dzięki temu zadanie może być współdzielone przez wiele instancji roboczych, ale wymaga dostępu do SharedArrayBuffer, co może wiązać się z dodaniem nagłówków HTTP COOP/COEP.

  3. Zrefaktoryzuj kod C/C++, aby uniknąć długotrwałych wywołań. Możesz na przykład podzielić zadanie na mniejsze części, które można wywołać z requestIdleCallback.

3. Zwracaj uwagę na ostrzeżenia i błędy w czasie działania.

Przetestuj wynikowy program WebAssembly i upewnij się, że w konsoli nie są generowane żadne ostrzeżenia ani błędy.

Skompiluj i uruchom programy z włączoną opcją -sASSERTIONS i napraw wszystkie błędy czasu działania.

4. W miarę możliwości unikaj linkowania dynamicznego.

Emscripten działa najlepiej z bibliotekami statycznymi (.a). Biblioteki udostępnione (.so, .dylib, .dll) są mniej przydatne we wdrażaniu w przeglądarce i mogą niepotrzebnie komplikować proces.

5. Przenoszenie istniejących bibliotek C/C++

Podczas integracji istniejących bibliotek C/C++ ze standardowymi systemami kompilacji:

Projekty CMake

Użyj poleceń CMake z emcmake i emmake:

mkdir build && cd build
emcmake cmake .. -DCMAKE_BUILD_TYPE=Release
emmake make

Projekty Autoconf / Make

Użyj emconfigure, aby ustawić cele łańcucha narzędzi do kompilacji skrośnej:

emconfigure ./configure --host=wasm32-unknown-emscripten --disable-shared
emmake make