Emscripten을 사용하여 C 및 C++를 WebAssembly로 컴파일하기

웹 기능: 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: 출시 빌드에서 최소 페이로드 크기에 맞게 최적화합니다.

2. 기본 스레드 차단 방지

WebAssembly 호출에 상당한 시간 (예: 수 밀리초 이상)이 걸릴 가능성이 있는 경우 기본 브라우저 스레드에서 호출하면 안 됩니다.

기본 브라우저 스레드에서 이러한 코드를 실행하지 않으려면 다음과 같은 몇 가지 방법을 사용할 수 있습니다.

  1. 웹 워커에서 전체 WebAssembly 프로그램을 실행합니다. SharedArrayBuffer 액세스를 설정하거나 프로그램 소스를 변경할 필요가 없으므로 가장 간단한 솔루션인 경우가 많습니다.

  2. pthreads 또는 Wasm Workers를 사용합니다. 이렇게 하면 여러 작업자 간에 작업을 공유할 수 있지만 SharedArrayBuffer 액세스가 필요하며, 여기에는 COOP/COEP HTTP 헤더 추가가 포함될 수 있습니다.

  3. C/C++ 코드를 리팩터링하여 장기 실행 호출을 방지합니다. 예를 들어 requestIdleCallback에서 호출할 수 있는 작은 조각으로 작업을 분할합니다.

3. 런타임 경고 및 오류에 주의하기

결과 WebAssembly 프로그램을 실제로 테스트하고 콘솔에 경고나 오류가 생성되지 않는지 확인합니다.

-sASSERTIONS를 사용 설정하여 프로그램을 빌드 및 실행하고 생성된 런타임 오류를 수정합니다.

4. 가능하면 동적 연결을 피합니다.

Emscripten은 정적 라이브러리 (.a)에서 가장 잘 작동합니다. 공유 라이브러리 (.so, .dylib, .dll)는 브라우저 배포에서 유용성이 떨어지며 불필요하게 복잡해질 수 있습니다.

5. 기존 C/C++ 라이브러리 포팅

기존 C/C++ 라이브러리를 표준 빌드 시스템과 통합하는 경우:

CMake 프로젝트

CMake 명령어를 emcmake 및 emmake로 래핑합니다.

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

Autoconf/Make 프로젝트

emconfigure를 사용하여 크로스 컴파일 도구 모음 타겟을 설정합니다.

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