Biên dịch C và C++ sang WebAssembly bằng Emscripten

Tính năng web: WebAssembly

Sử dụng Emscripten để biên dịch C và C++ thành các mô-đun WebAssembly (Wasm) hiệu suất cao cho trình duyệt.

1. Cờ biên dịch Emscripten hiện đại

Khi biên dịch và liên kết với emcc hoặc em++, hãy luôn sử dụng cờ mô-đun hiện đại:

  • -sEXPORT_ES6: Phát ra cú pháp mô-đun ES6 tiêu chuẩn (import/export) thay vì các đối tượng chung cũ. Thao tác này sẽ tự động đặt -sMODULARIZE.
  • -sENVIRONMENT=web: Loại bỏ mã thời gian chạy Node.js/shell để giảm thiểu kích thước gói.
  • -sSTRICT: Thực thi các giá trị mặc định hiện đại của Emscripten và không thực thi các cờ không dùng nữa.
  • -sALLOW_MEMORY_GROWTH: Cho phép vùng nhớ khối xếp tuyến tính WebAssembly mở rộng linh động khi phân bổ bộ nhớ.
  • -Oz (hoặc -O3) + -flto: Tối ưu hoá để có kích thước tải trọng tối thiểu trong các bản phát hành.

2. Tránh chặn luồng chính

Nếu lệnh gọi vào WebAssembly có khả năng mất nhiều thời gian (tức là hơn vài mili giây), thì bạn không nên gọi lệnh đó trên luồng trình duyệt chính.

Để tránh chạy mã như vậy trên luồng trình duyệt chính, bạn có thể áp dụng một số phương pháp sau:

  1. Chạy toàn bộ chương trình WebAssembly trong một Web Worker. Đây thường là giải pháp đơn giản nhất vì không cần thiết lập quyền truy cập SharedArrayBuffer hoặc thay đổi nguồn chương trình.

  2. Sử dụng pthread hoặc Wasm Worker. Điều này cho phép chia sẻ công việc giữa nhiều trình chạy, nhưng yêu cầu quyền truy cập SharedArrayBuffer, có thể bao gồm việc thêm tiêu đề HTTP COOP/COEP.

  3. Cải tiến mã C/C++ để tránh các lệnh gọi chạy trong thời gian dài. Ví dụ: chia nhỏ công việc thành các phần nhỏ có thể được gọi từ requestIdleCallback.

3. Chú ý đến các cảnh báo và lỗi trong thời gian chạy

Hãy nhớ kiểm thử chương trình WebAssembly thu được và đảm bảo không có cảnh báo hoặc lỗi nào được tạo trên bảng điều khiển.

Tạo và chạy các chương trình có bật -sASSERTIONS, đồng thời khắc phục mọi lỗi thời gian chạy xảy ra.

4. Tránh liên kết động nếu có thể

Emscripten hoạt động hiệu quả nhất với các thư viện tĩnh (.a). Thư viện dùng chung (.so, .dylib, .dll) ít hữu ích hơn trong việc triển khai trình duyệt và có thể làm phức tạp hoá mọi thứ một cách không cần thiết.

5. Chuyển thư viện C/C++ hiện có

Khi tích hợp các thư viện C/C++ hiện có với hệ thống xây dựng tiêu chuẩn:

Dự án CMake

Gói các lệnh CMake bằng emcmake và emmake:

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

Dự án Autoconf/Make

Sử dụng emconfigure để đặt mục tiêu chuỗi công cụ biên dịch chéo:

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