자 시작해보자!
스텝 1: 데모를 확인할 브라우저를 설치한다.
현재 크롬 카나리는 리눅스를 지원하지 않으니 파이어폭스 나이틀리를 설치한다. 맥이나 윈도우 유저는 크롬 카나리를 이용할 것을 권장한다. 파이어폭스를 실행할 때는 절대 경로를 이용해서 실행해야 한다. 그렇지 않으면 인스톨 된 일반 파이어폭스가 실행된다.
cd
wget https://archive.mozilla.org/pub/firefox/nightly/latest-mozilla-central/firefox-53.0a1.en-US.linux-x86_64.tar.bz2
tar xf firefox-53.0a1.en-US.linux-i686.tar.bz2
cd firefox
./firefox
상태바를 확인해서 파이어폭스 나이틀리 버전이 실행되었는지 확인한다. 브라우저가 웹어셈블리를 사용할 수 있도록 설정한다.
- 파이어폭스의 경우 주소창에 about:config 을 입력해 이동을 한다. 이동하게 되면 경고 얼럿이 뜨는데 수락해 주고 서치바에서 wasm을 입력하고 javascript.options.wasm 을 더블클릭해 값이 true가 되도록 바꾼다. 그리고 브라우저를 다시 시작한다.
- 크롬 카나리의 경우 주소창에 chrome://flags 를 입력하고 Experimental WebAssembly 항목이 나올 때까지 스크롤하고 링크를 클릭해 활성화 한 뒤 브라우저를 재실행 한다.(역: 번역 시점 최신 버전인 카나리 59 버전에서는 별도의 설정을 안 해도 된다.)
여기에서 웹어셈블리의 데모를 확인할 수 있다.
스텝 2: 우분투의 요구 사항
우분투에서 binaryen 툴체인을 이용하려면 몇 가지 라이브러리를 컴파일해야 한다.
sudo apt-get install git cmake make ninja-build
웹어셈블리가 지원되는 LLVM을 빌드 하려면 최소한 3.4.4 버전 이상의 cmake가 필요하다. 하단에 부록 파트를 살펴보면 소스 코드를 이용해 cmake를 설치하는 방법을 찾을 수 있다.
스텝 3: 인프라스트럭처와 툴체인 컴파일
일단 LLVM이 웹어셈블리를 지원하도록 준비해야 한다. 만약 오래된 버전의 cmake를 사용하고 있다면 이 튜토리얼의 하단에 위치한 부록 파트를 확인한다.
git clone http://llvm.org/git/llvm.git
cd llvm/tools
git clone http://llvm.org/git/clang.git
cd ../projects
git clone http://llvm.org/git/compiler-rt.git
cd ..
mkdir build
cd build
cmake -G Ninja -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly ..
ninja
ninja install
만약 닌자가 메모리를 너무 많이 사용하는 경우 아래의 항목 살펴봐라(컴파일을 느리게 하는 원인들이다.)
- 스왑 스페이스의 사용을 비활성화해 시스템이 멈추는것을 피한다 sudo swapoff -a
- echo $MAKEFLAFS 의 내용을 확인해 얼마나 많은 프로세서가 컴파일할 때 사용되는지 확인한다. ninja -j1 을 이용하는 것을 추천한다.
- 메모리를 적게 사용하는 골드 링커를 이용한다. 골드 링커를 이용하려면 id(id.bfd) 의 심벌릭 링크를 id.gold 로 변경한다.
id.bfg*를 *id.gold 로 변경하기 위해선 아래의 과정을 거친다.
ls -lah /usr/bin/ld # check which ld you are using
sudo rm /usr/bin/ld
sudo ln -s /usr/bin/ld.gold /usr/bin/ld
ls -lah /usr/bin/ld # check that you are using gold linker
스왑 스페이스를 다시 켜려면 sudo sudo swapon -a 를 입력한다. 그리고 이제 Binaryen 을 컴파일한다. Binaryen 는 최소 세 개의 필요한 바이너리들을 제공한다.
- asm.js를 컴파일 하기 위한 asm2wasm
- LLVM 웹어셈블리 백엔드
.s
아웃풋 파일을 컴파일 하기 위한 s2wasm
- Rust MIR를 컴파일 하기 위한 mir2wasm
cd
git clone https://github.com/WebAssembly/binaryen
cd binaryen
cmake .
make
컴파일이 끝나면 bin 디렉터리에 필요한 실행파일들을 얻게 된다. 필요에 따라 sudo make install 을 수행할 수 있다. 마지막으로 WABT(The WebAssembly Binary Toolkit)을 아래의 순서에 따라 설치한다.
git clone https://github.com/WebAssembly/wabt.git
cd wabt
mkdir build
cd build
cmake -G Ninja -DBUILD_TESTS=OFF ..
ninja
sudo ninja install
스텝 4: HELLO WORLD 예제
웹어셈블리 Hello world 어플리케이션을 실행하려면 html 템플릿과 필요한 코드를 준비해야 한다. 아래의 hello_world 라는 새 디렉터리를 만들고 그 안에 아래의 html 코드를 index.html로 저장한다.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Hello world</title>
<script>
if ('WebAssembly' in window) {
fetch('hello_world.wasm')
.then(response => response.arrayBuffer())
.then(buffer => WebAssembly.compile(buffer))
.then(module => {
const instance = new WebAssembly.Instance(module);
document.getElementById("btn").addEventListener("click", function() {
alert("count function result is : " + instance.exports.count());
}, false);
});
} else {
output.value = "Your browser doesn't support Web Assembly. You may need " +
"to enable it in your browser's flags.";
}
</script>
</head>
<body>
<input type="button" id="btn" value="Click me to execute hello world!" />
</body>
</html>
그리고 C를 이용해 출력해 보자, 아래의 내용을 hello_world.c로 저장한다.
int counter = 100;
int count() {
return counter + 1;
}
이제 컴파일을 수행한다.
clang -emit-llvm --target=wasm32 -S hello_world.c
llc hello_world.ll -march=wasm32
s2wasm hello_world.s > hello_world.wast
wast2wasm -o hello_world.wasm hello_world.wast
스텝 5: 예제를 열어본다.
드디어 이번 단계에서 파이어폭스를 통해 예제 파일을 열어본다.
cd hello_world
python -m SimpleHTTPServer 8000
혹은 wasm-cli 를 이용해 wasm 파일만 테스트 해볼 수 있다.
npm install -g wasm-cli
wasm hello_world.wasm
http://localhost:8000 을 파이어폭스 주소창에 입력해 예제를 열어본다.
부록
Error libgtk-3.so.0: cannot open shared object file: No such file or directory
파이어폭스 53 버전을 실행하려 할때 아래의 에러를 만날 수 있다.
XPCOMGlueLoad error for file /home/parallels/firefox-32/libmozgtk.so:
libgtk-3.so.0: cannot open shared object file: No such file or directory
Couldn't load XPCOM.
이럴땐
위와 같이 입력해 아래의 결과가 출력이 된다면
/usr/lib/x86_64-linux-gnu/libgtk-3.so.0
/usr/lib/x86_64-linux-gnu/libgtk-3.so.0.1000.8
64비트 버전의 모질라 파이어폭스를 다운로드 해야한다.
Error: GDK_BACKEND does not match available displays
위와 같은 에러 메세지를 만나면 DISPLAY 환경 변수를 셋팅해야 한다.
위의 내용을 .bashrc 나 .zshrc 에 추가해 언제나 값이 설정되도록 한다.
Error: CMake 3.4.3 or higher is required. You are running version 3.2.2
이 에러를 해결하려면 cmake를 다운로드해 컴파일 해야한다.
wget https://cmake.org/files/v3.7/cmake-3.7.0.tar.gz
tar -xf cmake-3.7.0.tar.gz
cd cmake-3.7.0
./bootstrap
make
sudo make install
Error: Uncaught ReferenceError: Wasm is not defined
Wasm.instantiateModule() 대신 WebAssembly.instance() 를 사용한다.
Error: Uncaught Error: memory access out of bounds
이 이슈에 대해서 다시 업데이트할 예정이지만 이 문제는 간혹 s2wasm 을 사용할 때 –allocate-stack 옵션으로 해결이 될 때가 있다.
역자 부록(맥과 크롬 카나리 환경을 위한 팁)
- 스텝 3의 첫번째, LLVM을 설치하기 전에 ninja-build를 설치해야 한다.
- LLVM은 다운로드하고 컴파일 하는 과정이 정말 오래 걸린다.
- 역자의 경우 스텝 3의 첫번째 LLVM 설치하는 부분에서 ninja install 은 sudo ninja install 로 권한을 주고 설치해야 했다.
- binaryen 을 make 로 빌드한뒤 sudo make install 로 인스톨 해야 툴들의 경로가 제대로 잡힌다.