May 28, 2021
참고: 웹어샘블리 인 액션 (한빛출판사) 를 읽고 정리한 내용입니다.
c file : 소수인지 판별
calculate_primes.c
#include <stdlib.h>
#include <stdio.h>
#include <emscripten.h>
int IsPrime(int value) {
    if (value == 2) { return 1;}
    if (value <=1 || value % 2 == 0) { return 0; }
    for (int i = 3; (i * i) <= value; i += 2) {
        if (value % i == 0) { return 0; } 
    }
  return 1
}
int main() {
    int start = 3;
    int end = 100000;
    printf("Prime numbers between %d and %d:\n", start, end);
    for (int i = start; i <= end; i += 2) {
      if (IsPrime(i)) {
        printf("%d", i)
      }
    }
   print("\n")
  
   return 0;
}$ git clone https://github.com/emscripten-core/emsdk.git
$ cd emsdk
$ ./emsdk install latestInstalling SDK 'sdk-releases-upstream-77b065ace39e6ab21446e13f92897f956c80476a-64bit'..
Installing tool 'node-14.15.5-64bit'..
Error: Downloading URL 'https://storage.googleapis.com/webassembly/emscripten-releases-builds/deps/node-v14.15.5-darwin-x64.tar.gz': <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1056)>
Warning: Possibly SSL/TLS issue. Update or install Python SSL root certificates (2048-bit or greater) supplied in Python folder or https://pypi.org/project/certifi/ and try again.
Installation failed!emsdk파일 상단에
ssl import 추가
수정파일: vi emsdk.py
import ssl
ssl._create_default_https_context = ssl._create_unverified_contextlog
./emsdk install latest              ✔
Installing SDK 'sdk-releases-upstream-77b065ace39e6ab21446e13f92897f956c80476a-64bit'..
Installing tool 'node-14.15.5-64bit'..
Downloading: /Users/sdk/IdeaProjects/emsdk/zips/node-v14.15.5-darwin-x64.tar.gz from https://storage.googleapis.com/webassembly/emscripten-releases-builds/deps/node-v14.15.5-darwin-x64.tar.gz, 31560456 Bytes
Unpacking '/Users/sdk/IdeaProjects/emsdk/zips/node-v14.15.5-darwin-x64.tar.gz' to '/Users/sdk/IdeaProjects/emsdk/node/14.15.5_64bit'
Done installing tool 'node-14.15.5-64bit'.
Installing tool 'python-3.9.2-1-64bit'..
Downloading: /Users/sdk/IdeaProjects/emsdk/zips/python-3.9.2-1-macos-x86_64.tar.gz from https://storage.googleapis.com/webassembly/emscripten-releases-builds/deps/python-3.9.2-1-macos-x86_64.tar.gz, 32022000 Bytes
Unpacking '/Users/sdk/IdeaProjects/emsdk/zips/python-3.9.2-1-macos-x86_64.tar.gz' to '/Users/sdk/IdeaProjects/emsdk/python/3.9.2-1_64bit'
Done installing tool 'python-3.9.2-1-64bit'.
Installing tool 'releases-upstream-77b065ace39e6ab21446e13f92897f956c80476a-64bit'..
Downloading: /Users/sdk/IdeaProjects/emsdk/zips/77b065ace39e6ab21446e13f92897f956c80476a-wasm-binaries.tbz2 from https://storage.googleapis.com/webassembly/emscripten-releases-builds/mac/77b065ace39e6ab21446e13f92897f956c80476a/wasm-binaries.tbz2, 165357215 Bytes
Unpacking '/Users/sdk/IdeaProjects/emsdk/zips/77b065ace39e6ab21446e13f92897f956c80476a-wasm-binaries.tbz2' to '/Users/sdk/IdeaProjects/emsdk/upstream'
Done installing tool 'releases-upstream-77b065ace39e6ab21446e13f92897f956c80476a-64bit'.
Done installing SDK 'sdk-releases-upstream-77b065ace39e6ab21446e13f92897f956c80476a-64bit'../emsdk activate latest
$ . ./emsdk activate latest            ✔
Setting the following tools as active:
   node-14.15.5-64bit
   python-3.9.2-1-64bit
   releases-upstream-77b065ace39e6ab21446e13f92897f956c80476a-64bit
Next steps:
- To conveniently access emsdk tools from the command line,
  consider adding the following directories to your PATH:
    /Users/sdk/IdeaProjects/emsdk
    /Users/sdk/IdeaProjects/emsdk/node/14.15.5_64bit/bin
    /Users/sdk/IdeaProjects/emsdk/upstream/emscripten
- This can be done for the current shell by running:
    source "/Users/sdk/IdeaProjects/emsdk/emsdk_env.sh"
- Configure emsdk in your bash profile by running:
    echo 'source "/Users/sdk/IdeaProjects/emsdk/emsdk_env.sh"' >> $HOME/.bash_profilesh 파일 퍼미션 변경
$chmod a+x emsdk_env.sh
실행
$ ./emsdk_env.sh
./emsdk_env.sh                      ✔
Adding directories to PATH:
PATH += /Users/sdk/IdeaProjects/emsdk/upstream/emscripten
PATH += /Users/sdk/IdeaProjects/emsdk/node/14.15.5_64bit/bin
Setting environment variables:
PATH = /Users/sdk/IdeaProjects/emsdk/upstream/emscripten:/Users/sdk/IdeaProjects/emsdk/node/14.15.5_64bit/bin:/Users/sdk/IdeaProjects/emsdk:/Library/Frameworks/Python.framework/Versions/2.7/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/go/bin:/usr/local/share/dotnet:~/.dotnet/tools:/Library/Apple/usr/bin:/Library/Frameworks/Mono.framework/Versions/Current/Commands
EMSDK_NODE = /Users/sdk/IdeaProjects/emsdk/node/14.15.5_64bit/bin/node
EMSDK_PYTHON = /Users/sdk/IdeaProjects/emsdk/python/3.9.2-1_64bit/bin/python3
SSL_CERT_FILE = /Users/sdk/IdeaProjects/emsdk/python/3.9.2-1_64bit/lib/python3.9/site-packages/certifi/cacert.pem$ source ./emsdk_env.sh
source ./emsdk_env.sh              ✔
Adding directories to PATH:
PATH += /Users/sdk/IdeaProjects/emsdk/upstream/emscripten
PATH += /Users/sdk/IdeaProjects/emsdk/node/14.15.5_64bit/bin
Setting environment variables:
PATH = /Users/sdk/IdeaProjects/emsdk/upstream/emscripten:/Users/sdk/IdeaProjects/emsdk/node/14.15.5_64bit/bin:/Users/sdk/IdeaProjects/emsdk:/Library/Frameworks/Python.framework/Versions/2.7/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/go/bin:/usr/local/share/dotnet:~/.dotnet/tools:/Library/Apple/usr/bin:/Library/Frameworks/Mono.framework/Versions/Current/Commands
EMSDK_NODE = /Users/sdk/IdeaProjects/emsdk/node/14.15.5_64bit/bin/node
EMSDK_PYTHON = /Users/sdk/IdeaProjects/emsdk/python/3.9.2-1_64bit/bin/python3
SSL_CERT_FILE = /Users/sdk/IdeaProjects/emsdk/python/3.9.2-1_64bit/lib/python3.9/site-packages/certifi/cacert.pemsource  "/Users/sdk/IdeaProjects/emsdk/emsdk_env.sh" >> $HOME/.bash_profile
stdout
source  "/Users/sdk/IdeaProjects/emsdk/emsdk_env.sh" >> $HOME/.bash_profile                                                    SIGINT(2) ↵
Adding directories to PATH:
PATH += /Users/sdk/IdeaProjects/emsdk
PATH += /Users/sdk/IdeaProjects/emsdk/upstream/emscripten
PATH += /Users/sdk/IdeaProjects/emsdk/node/14.15.5_64bit/bin
Setting environment variables:
PATH = /Users/sdk/IdeaProjects/emsdk:/Users/sdk/IdeaProjects/emsdk/upstream/emscripten:/Users/sdk/IdeaProjects/emsdk/node/14.15.5_64bit/bin:/Library/Frameworks/Python.framework/Versions/2.7/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/go/bin:/usr/local/share/dotnet:~/.dotnet/tools:/Library/Apple/usr/bin:/Library/Frameworks/Mono.framework/Versions/Current/Commands
EMSDK = /Users/sdk/IdeaProjects/emsdk
EM_CONFIG = /Users/sdk/IdeaProjects/emsdk/.emscripten
EMSDK_NODE = /Users/sdk/IdeaProjects/emsdk/node/14.15.5_64bit/bin/node
EMSDK_PYTHON = /Users/sdk/IdeaProjects/emsdk/python/3.9.2-1_64bit/bin/python3emcc -v
emcc -v                             ✔
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 2.0.23 (b15ca40ca02f469de3bf9a4de67a2655aede8974)
clang version 13.0.0 (/opt/s/w/ir/cache/git/chromium.googlesource.com-external-github.com-llvm-llvm--project 5852582532b3eb3ea8da51a1e272d8d017bd36c9)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /Users/sdk/IdeaProjects/emsdk/upstream/bin
source ./emsdk_env.sh
ource ./emsdk_env.sh               ✔
Adding directories to PATH:
PATH += /Users/sdk/IdeaProjects/emsdk
PATH += /Users/sdk/IdeaProjects/emsdk/upstream/emscripten
PATH += /Users/sdk/IdeaProjects/emsdk/node/14.15.5_64bit/bin
Setting environment variables:
PATH = /Users/sdk/IdeaProjects/emsdk:/Users/sdk/IdeaProjects/emsdk/upstream/emscripten:/Users/sdk/IdeaProjects/emsdk/node/14.15.5_64bit/bin:/Library/Frameworks/Python.framework/Versions/2.7/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/go/bin:/usr/local/share/dotnet:~/.dotnet/tools:/Library/Apple/usr/bin:/Library/Frameworks/Mono.framework/Versions/Current/Commands
EMSDK = /Users/sdk/IdeaProjects/emsdk
EM_CONFIG = /Users/sdk/IdeaProjects/emsdk/.emscripten
EMSDK_NODE = /Users/sdk/IdeaProjects/emsdk/node/14.15.5_64bit/bin/node
EMSDK_PYTHON = /Users/sdk/IdeaProjects/emsdk/python/3.9.2-1_64bit/bin/python3
SSL_CERT_FILE = /Users/sdk/IdeaPr$ emcc --version
emcc --version                    1 ↵
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 2.0.23 (b15ca40ca02f469de3bf9a4de67a2655aede8974)
Copyright (C) 2014 the Emscripten authors (see AUTHORS.txt)
This is free and open source software under the MIT license.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.C 코드를 엠스크립튼을 이용해 웹어셈블리 파일로 컴파일
$ emcc calculate_primes.c -o html_template.html
생성된 파일
.wasm : 어샘블리모듈.js: 자바 스크립트.html: html 파일-o: 플래그 값
html_template.html: html까지 입력시 - 전체 자동생성(wasm,  js. html)
ls -al                    ✔
total 760
drwxr-xr-x  8 sdk  staff     256 May 28 08:12 .
drwxr-xr-x  5 sdk  staff     160 May 28 07:37 ..
-rw-r--r--  1 sdk  staff     548 May 28 08:12 calculate_primes.c
-rw-r--r--  1 sdk  staff  121901 May 28 08:12 html
-rwxr-xr-x  1 sdk  staff   12354 May 28 08:12 html.wasm
-rw-r--r--  1 sdk  staff  102683 May 28 08:12 html_template.html
-rw-r--r--  1 sdk  staff  121910 May 28 08:12 html_template.js
-rwxr-xr-x  1 sdk  staff   12354 May 28 08:12 html_template.wasmpython -m SimpleHTTPServer 8080
python3 -m http.server 8080
or
emrun --port 8080 test.html
python3 -m http.server 8080
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
      
   
    
      
   
    
html
안에 <script src="js_plumbing.js"></script> 작성
1 <!DOCTYPE html>
2 <html>
3   <head>
4     <meta charset="utf-8">
5   </head>
6   <body>
7       HTML page I created for my WebAssembly module.<br/>
8       WebAssembly 모듈 용으로 만든 HTML 페이지입니다.
9   <script src="js_plumbing.js"></script>
10   </body>
11 </html>$emcc calculate_primes.c -o js_plumbing.js
실행
      
   
    
엠스크립튼으로 웹어셈블리 파일만 생성
C/C++ 코드를 웹 어셈블리로 컴파일
다른 파일은 생성하지 않음
side module(복수 모듈)을 만들 때 사용함.
side_module.c
int Increment(int value) {
  return (value + 1);
}
int Decrement(int value) {
  return (value - 1);
}emcc side_module.c -s SIDE_MODULE=2 -O1 -s EXPORTED_FUNCTIONS=['_Increment'] -o side_module.wasm
-s SIDE_MODULE=2
-O1: 최적화 플래그 
지정해 주지 않으면
-O0이 적용되어 모듈 로드 시 링크 에러발생
-s EXPORTED_FUNCTIONS: 변수명 앞에 언더스코어(_)추가해야 함 
변수 여러개 사용
-s "EXPORTED_FUNCTIONS=['_Increment', '_Decrement']"
emcc side_module.c 
   -s SIDE_MODULE=2 -O1 
   -s "EXPORTED_FUNCTIONS=['_Increment', '_Decrement']" 
   -o side_module.wasmzsh: no matches found: EXPORTED_FUNCTIONS=[_Incrrement]EXPORTED_FUNCTION을 ""로 감싸 줌  
emcc side_moduel.c -s SIDE_MODULE=2 -O1 -s \
"EXPORTED_FUNCTIONS=['_Incrrement']" -o side_moudle.wasm$ls -al
 ls -al                   ✔
total 16
drwxr-xr-x   4 sdk  staff  128 May 29 09:35 .
drwxr-xr-x  10 sdk  staff  320 May 29 09:21 ..
-rw-r--r--   1 sdk  staff   54 May 29 09:35 side_moduel.c
-rwxr-xr-x   1 sdk  staff  176 May 29 09:35 side_moudle.wasm
      
   
    
      
   
    
트러블 슈팅 https://github.com/rustwasm/rust-parcel-template/issues/52 https 에서만 작동 하는 것 같음. 한 시간 날림
side_module.html:1 Uncaught (in promise) TypeError: Failed to execute 'compile' on 'WebAssembly': Incorrect response MIME type. Expected 'application/wasm'.c에서 작성한 Increment()를 wasm로 컴파일 후 js 에서 fetch로 받아 함수 실행
기대했던 결과는 console에 출력 되는 것이였음.
아쉽 
emcc validate.cpp -o validate.js -s “EXTRAEXPORTEDRUNTIME_METHODS=[‘ccall’, ‘UTF8ToString’]”