Rust를 Webassembly로 컴파일 하는 방법과 방법을 정리 해 둔다.
환경 구축이라 순차적으로 따라하면 될것 같지만, 막상 해 보면 시간도 오래 걸리고 잘 안된다. 컴파일 환경 구축 부터 Cargo 로 빌드하는 방법 까지 정리 해 둔다.
아래에서 시간이 엄청 많이 걸린다.
그리고 nodejs와 node 문제 인것 같은데 pre-built 환경을 구성 하면서 node를 설치 했지만 중간에 node 4.1.1 버전이 설치된다. node 설치는 오래 걸리지 않으므로 무시하자.
아직 html 생성은 지원하지 않는다. 그래서 target/wasm32-unknown-emscripten/debug/deps/ 아래 hello.html 파일(html 파일 이름은 편한대로 해도 된다) 을 생성해야 한다. 당연히 .wasm 파일을 호출 하는 코드가 있어야 할텐데, 아래는 실행에 필요한 최소 내용이다. html에 붙여 넣어 주자.
target/wasm32-unknown-emscripten/debug/deps/ 디렉토리에 html 파일을 넣는 이유는 .js 파일에 .wasm 파일 경로가 동일 디렉토리로 되어 있기 때문.
환경 구축이라 순차적으로 따라하면 될것 같지만, 막상 해 보면 시간도 오래 걸리고 잘 안된다. 컴파일 환경 구축 부터 Cargo 로 빌드하는 방법 까지 정리 해 둔다.
OS 선택
Rust와 Emscripten이 설치 되는 OS면 된다. Rust는 Windows, Mac, Ubuntu OS에서 실행 되는 것을 확인 했지만 Emscripten은 우분투 최신 버전과 14.04에서만 테스트를 해 보았기 때문에 최신 Ubuntu 기준으로 정리를 해둔다.
Docker Image 만들어 두면 편할 것 같았는데, 막상 컴파일 환경을 이미지로 빌드하고 보니 이미지 크기가 25GB를 넘는 문제가 있다.
Rust 설치
안정된 Rust 버전과 wasm32 타겟 설치
rustup install stable
rustup default stable
rustup target add wasm32-unknown-emscripten
Emscripten 설치
참고:
우분투 14.04에서는 설치 중에 cmake 버전 때문에 문제가 생긴다. cmake 최신 버전을 설치 해주면 문제 없다.
최신 우분투에서는 아래 순으로 진행하면 된다. docker에서 실행 한 순서 이기 때문에 sudo로 실행하지 않는다.
apt-get update
apt-get install build-essential
apt-get install cmake
apt-get install python2.7
apt-get install nodejs
apt-get install default-jre
ln -s /usr/bin/python2.7 /usr/bin/python #링크를 생성해 주자
apt-get install curl
curl -o emsdk-portable.tar.gz https://s3.amazonaws.com/mozilla-games/emscripten/releases/emsdk-portable.tar.gz
tar -xvzf emsdk-portable.tar.gz
cd emsdk-portable
./emsdk update
아래에서 시간이 엄청 많이 걸린다.
그리고 nodejs와 node 문제 인것 같은데 pre-built 환경을 구성 하면서 node를 설치 했지만 중간에 node 4.1.1 버전이 설치된다. node 설치는 오래 걸리지 않으므로 무시하자.
여기 까지 진행하면 아래 메시지를 확인 가능
./emsdk install latest
Done installing tool 'emscripten-tag-1.37.9-64bit'.
Done installing SDK 'sdk-tag-1.37.9-64bit'.
...
Emscripten 최신 버전 활성화
./emsdk activate latest
source ./emsdk_env.sh
emcc 버전 체크
emcc -v
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 1.37.9
clang version 4.0.0 (emscripten 1.37.9 : 1.37.9)
Target: x86_64-unknown-linux-gnu
...
1.37.0 이하라면 update
apt-get install git-core
./emsdk update
./emsdk install sdk-incoming-64bit
./emsdk activate sdk-incoming-64bit
Rust 코드 컴파일
cat hello.rs
fn main() {
println!("hello");
}
rustc --target==wasm32-unknown-emscripten hello.rs -o hello.html
ls -al
-rw-r--r-- 1 root root 816159 Apr 3 12:16 hello.asm.js
-rw-r--r-- 1 root root 102727 Apr 3 12:16 hello.html
-rw-r--r-- 1 root root 247359 Apr 3 12:16 hello.js
-rw-r--r-- 1 root root 35 Apr 3 12:10 hello.rs
-rw-r--r-- 1 root root 155653 Apr 3 12:16 hello.wasm
Cargo 로 빌드하기
프로젝트 생성
cargo new hello
Cargo.toml에 rustc 옵션 추가
[package]
name = "rust-wasm"
version = "0.1.0"
authors = ["freestrings <freestrings@gmail.com>"]
[dependencies]
[target.wasm32-unknown-emscripten]
rustflags=["-o rust-wasm.html"]
테스트 코드
cat src/main.rs
fn main() {
println!("hello");
}
컴파일
cargo rustc --target=wasm32-unknown-emscripten
ls -al target/wasm32-unknown-emscripten/debug/deps/
...
-rw-r--r-- 1 root root 6769048 Apr 2 12:08 rust_wasm-5d7a20a47b6ec337.asm.js
-rw-r--r-- 2 root root 310906 Apr 2 12:08 rust_wasm-5d7a20a47b6ec337.js
-rw-r--r-- 1 root root 1667847 Apr 2 12:08 rust_wasm-5d7a20a47b6ec337.wasm
...
실행
target/wasm32-unknown-emscripten/debug/deps/ 디렉토리에 html 파일을 넣는 이유는 .js 파일에 .wasm 파일 경로가 동일 디렉토리로 되어 있기 때문.
파이어폭스 52 버전 부터는 Webassembly를 기본 지원하고 있기 때문에 최신 파이어폭스에서 결과를 확인하면 편하다.
<!doctype html>
<html lang="en-us">
<body>
<textarea class="emscripten" id="output" rows="20" style="width:100%"></textarea>
<script async type="text/javascript" src="JS 파일"></script>
<script>
var Module = {
print: (function() {
var element = document.getElementById('output');
return function(text) {
element.innerHTML += text;
};
})()
};
</script>
</body>
</html>
컴파일2
프로젝트 루트 ./cargo (없으면 생성) 아래 config 파일을 생성하고 링커 속성을 지정해 준다. 링커 속성은 target에 플랫폼이 컴파일 될 때 rustc에 전달된다.
echo "emcc \"-o\" \"test.html\" \"-02\" \$@" > ./emcc_conf
cat ./cargo/config
[target.wasm32-unknown-emscripten]
linker = "/work/emcc_conf"
참고
설치 관련해서는 https://hackernoon.com/compiling-rust-to-webassembly-guide-411066a69fde 가 정리가 가장 잘 되어 있다.
그리고 Emscripten이나 LLVM 기본 이해는 https://www.slideshare.net/Hybrid0/llvm-28276305 가 읽을 만하고, WebAssembly는 https://www.slideshare.net/gyeongseokseo/web-assembly-70493156 가 읽을 만하다.
그리고 Emscripten이나 LLVM 기본 이해는 https://www.slideshare.net/Hybrid0/llvm-28276305 가 읽을 만하고, WebAssembly는 https://www.slideshare.net/gyeongseokseo/web-assembly-70493156 가 읽을 만하다.
블로그 관리자가 댓글을 삭제했습니다.
답글삭제