הידור של C ו-C++‎ ל-WebAssembly באמצעות Emscripten

תכונות באינטרנט: WebAssembly

אפשר להשתמש ב-Emscripten כדי לקמפל את C ו-C++‎ למודולים של WebAssembly‏ (Wasm) עם ביצועים גבוהים לדפדפן.

1. דגלים מודרניים של הידור Emscripten

כשמבצעים הידור וקישור באמצעות emcc או em++, תמיד צריך להשתמש בדגלים מודולריים מודרניים:

  • ‫-sEXPORT_ES6: פולט תחביר מודול ES6 סטנדרטי (import/export) במקום אובייקטים גלובליים מדור קודם. הפעולה הזו מגדירה באופן אוטומטי את -sMODULARIZE.
  • ‫-sENVIRONMENT=web: מסיר קוד זמן ריצה של Node.js/מעטפת כדי לצמצם את גודל החבילה.
  • ‫-sSTRICT: אכיפת ברירות המחדל המודרניות של Emscripten והצגת שגיאה בדגלים שהוצאו משימוש.
  • ‫-sALLOW_MEMORY_GROWTH: מאפשרת לערימת הזיכרון הלינארי של WebAssembly להתרחב באופן דינמי בזמן הקצאת הזיכרון.
  • ‫-Oz (או -O3) + -flto: אופטימיזציה לגודל מטען ייעודי (payload) מינימלי בגרסאות build להפצה.

2. לא לחסום את ה-thread הראשי

אם קריאה ל-WebAssembly צפויה להימשך זמן רב (כלומר יותר מכמה אלפיות השנייה), אין לקרוא לה בשרשור הראשי של הדפדפן.

כדי להימנע מהרצת קוד כזה ב-thread הראשי של הדפדפן, יש כמה גישות אפשריות:

  1. מריצים את כל תוכנית WebAssembly ב-Web Worker. לרוב זה הפתרון הפשוט ביותר, כי הוא לא דורש הגדרת גישה ל-SharedArrayBuffer או שינוי של קוד המקור של התוכנית.

  2. משתמשים ב-pthreads או ב-Wasm Workers. כך אפשר לשתף את העבודה בין כמה עובדים, אבל נדרשת גישה ל-SharedArrayBuffer, שיכולה לכלול הוספה של כותרות HTTP מסוג COOP או COEP.

  3. כדאי לארגן מחדש (Refactoring) את קוד ה-C/C++‎ כדי להימנע מקריאות שנמשכות זמן רב. לדוגמה, חלוקת העבודה לחלקים קטנים שאפשר לקרוא להם מ-requestIdleCallback.

3. שימו לב לאזהרות ולשגיאות בזמן הריצה

חשוב לבדוק את תוכנית ה-WebAssembly שנוצרה ולוודא שלא מופיעות אזהרות או שגיאות במסוף.

בונים ומריצים את התוכניות כש--sASSERTIONS מופעל, ומתקנים את כל הכשלים בזמן הריצה שנוצרים.

4. אם אפשר, כדאי להימנע מקישור דינמי

‫Emscripten פועל בצורה הכי טובה עם ספריות סטטיות (.a). ספריות משותפות (.so, .dylib, .dll) פחות שימושיות בפריסה בדפדפן ויכולות לסבך את העניינים שלא לצורך.

5. העברת ספריות C/C++‎ קיימות

כשמשלבים ספריות C/C++‎ קיימות עם מערכות build רגילות:

פרויקטים ב-CMake

עוטפים את פקודות CMake ב-emcmake וב-emmake:

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

פרויקטים של Autoconf / Make

משתמשים ב-emconfigure כדי להגדיר יעדים של toolchain לעיבוד בין מערכות:

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