RUST to wasm 컴파일하기

채동기·2023년 5월 30일
3

Rust

목록 보기
2/5

Rust 환경 설치

install rust

rust install

위의 링크에서 rust를 설치할 수 있습니다.

Rustup은 Rust를 설치하고 관리하는 도구입니다. Rustup을 사용하면 다양한 버전의 Rust를 설치하고 관리할 수 있습니다. Rustup은 Rust 컴파일러인 rustc, Rust의 표준 라이브러리인 rust-std, Rust의 패키지 관리자인 cargo 및 rust-docs를 설치합니다.

install wasm-pack

패키지를 빌드하기 위해, wasm-pack이라는 추가적인 툴이 필요합니다. 이것을 통해 코드를 WebAssembly로 컴파일하고, npm에 적합한 패키징을 생성할 수 있습니다. 설치를 하려면 터미널에 다음 명령을 입력합니다.

cargo install wasm-pack

install node.js & npm 계정 생성

아래는 Node.js 설치와 npm 계정 생성을 요약한 내용입니다:

  1. Node.js 설치:

"Get npm!" 페이지에 접속하여 안내에 따라 Node.js와 npm을 설치합니다.
Node.js의 버전 선택은 개인의 선호나 요구에 따라 자유롭게 선택할 수 있습니다.

  1. npm 계정 생성:

npm 가입 페이지에서 양식을 작성하여 npm 계정을 생성합니다.
npm 계정을 만든 후, 명령 줄에서

npm adduser

명령을 실행합니다.
계정명, 패스워드, 이메일 등을 입력합니다.
제대로 작동했다면,

"Logged in as [계정명] on https://registry.npmjs.org/."

과 같은 출력을 볼 수 있습니다.
만약 문제가 발생한다면, npm에 문의하여 문제를 해결할 수 있습니다.
이렇게 하면 Node.js와 npm이 설치되고 npm 계정이 생성됩니다. 이제 npm 패키지를 생성하고 배포하는 작업을 수행할 수 있습니다.

WebAssembly npm 패키지 빌드하기

  1. Rust 패키지 생성:

개인 프로젝트를 담을 디렉토리로 이동한 후, 명령 줄에서 다음 명령어를 실행합니다:

cargo new --lib hello-wasm

이 명령어는 hello-wasm이라는 이름의 하위 디렉토리에 새로운 Rust 라이브러리를 생성합니다.

  1. 프로젝트 구조:

위 명령어를 실행하면 다음과 같은 구조가 생성됩니다:

+-- Cargo.toml
+-- src
+-- lib.rs

Cargo.toml은 빌드를 설정하기 위한 파일입니다.
src/lib.rs에는 Rust 코드가 생성됩니다.

  1. Cargo.toml 설정:

Cargo.toml 파일을 열어서 빌드에 필요한 설정을 추가하거나 수정합니다. 이 설정은 패키지의 종속성, 빌드 옵션 등을 정의하는 곳입니다.

  1. lib.rs 파일:

생성된 src/lib.rs 파일에는 Rust 코드가 작성되어 있습니다.
필요에 따라 Rust 코드를 수정하고 원하는 기능을 구현합니다.
이제 WebAssembly npm 패키지를 빌드하기 위한 기본적인 구조와 설정이 완료되었습니다. Rust 코드를 작성하고 필요한 빌드 옵션을 추가하여 원하는 기능을 구현하실 수 있습니다.

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        assert_eq!(2 + 2, 4);
    }
}

rust 작성하기

  1. wasm-bindgen 사용:
  • Rust 코드의 맨 위에 use wasm_bindgen::prelude::*;를 추가합니다.
  • 이 코드는 wasm-bindgen의 기능을 사용하기 위해 필요한 라이브러리를 가져옵니다.
  • wasm-bindgen은 Rust와 JavaScript 간의 통신을 위한 다리 역할을 합니다.
  1. wasm-bindgen 기능:
  • wasm-bindgen은 Rust와 JavaScript의 타입 사이의 상호 작용을 용이하게 해줍니다.
  • Rust 함수를 JavaScript에서 호출하거나, JavaScript의 예외를 Rust에서 처리할 수 있게 해줍니다. 이를 위해 wasm-bindgen의 기능을 사용할 수 있습니다.

위 코드는 wasm-bindgen을 사용하여 Rust와 JavaScript 사이의 통신을 위한 준비를 마친 것입니다. 이제 Rust 코드를 작성하고 기능을 구현할 수 있습니다. wasm-bindgen을 활용하여 JavaScript와 상호작용하고 필요한 기능을 구현할 수 있습니다.

Rust에서 JavaScript의 외부함수 호출

  1. 외부 함수 선언:

Rust 코드에 #[wasm_bindgen] 속성을 추가하여 외부 함수를 선언합니다.
extern 블록 내에 JavaScript 함수의 시그니처를 Rust 형식에 맞게 작성합니다.
예시:

#[wasm_bindgen]
extern {
pub fn alert(s: &str);
}

  1. wasm-bindgen의 역할:

wasm-bindgen은 Rust 코드와 JavaScript 간의 함수 호출을 가능하게 해줍니다.
외부 함수를 호출하고자 할 때, wasm-bindgen은 해당 함수를 어떻게 찾아야 하는지 알고 있습니다.

  1. JavaScript 함수 호출:

Rust 코드에서 선언된 외부 함수를 호출하여 JavaScript 함수를 실행할 수 있습니다.
Rust 함수 내에서 JavaScript 함수를 호출하는 위 코드는 Rust에서 JavaScript의 외부 함수를 호출하기 위한 준비를 마친 것입니다. 이제 Rust 함수 내에서 해당 외부 함수를 호출하고, JavaScript 함수의 동작을 실행할 수 있습니다.

JavaScript가 호출할 수 있는 Rust 함수 작성

  1. 함수 속성:
    • Rust 코드에 #[wasm_bindgen] 속성을 추가하여 JavaScript에서 호출할 수 있는 함수를 작성합니다.
    • Rust 함수의 시그니처는 기존의 fn 구문으로 작성됩니다.

pub fn greet(name: &str) {
/ 함수 내용 /
}

  1. #[wasm_bindgen] 속성:

    • 이번에는 #[wasm_bindgen] 속성을 Rust 함수에 추가하여 JavaScript에서 호출 가능한 함수임을 나타냅니다.
    • 이 속성은 우리가 세상에 제공하는 기능을 의미합니다.
  2. JavaScript에서 호출:

    • Rust 함수 내에서 필요한 로직을 구현합니다.
    • JavaScript와 상호작용이 필요한 경우, Rust 함수 내에서 JavaScript 함수를 호출할 수 있습니다.
    • 예시:

      alert(&format!("Hello, {}!", name));

위 코드는 Rust에서 JavaScript가 호출할 수 있는 함수를 작성하는 것을 의미합니다. Rust 함수의 로직을 구현하고, 필요한 경우 JavaScript 함수를 호출하여 상호작용할 수 있습니다. 이 경우 greet 함수는 인자로 전달받은 이름을 사용하여 JavaScript의 alert 함수를 호출하고, 문자열을 경고창에 표시합니다.

라이브러리가 작성되었다면, 이제 해당 라이브러리를 빌드할 수 있습니다.

작성된 코드를 WebAssembly로 컴파일

  1. [package] 섹션:

    • 프로젝트의 메타데이터를 정의하는 부분입니다.
    • name: 프로젝트의 이름을 설정합니다.
    • version: 프로젝트의 버전을 설정합니다.
    • authors: 프로젝트의 작성자 정보를 설정합니다.
    • description: 프로젝트에 대한 간단한 설명을 설정합니다.
    • license: 프로젝트의 라이선스 정보를 설정합니다.
    • repository: 프로젝트의 GitHub 레포지토리 주소를 설정합니다.
  2. [lib] 섹션:

    • 프로젝트를 cdylib(crate dynamic library) 형식으로 빌드할 것임을 설정합니다.
    • 이 설정은 Rust에게 프로젝트를 WebAssembly로 컴파일할 것임을 알려줍니다.
  3. [dependencies] 섹션:

    • wasm-bindgen에 대한 의존성을 설정합니다.
    • 이 설정은 Cargo에게 해당 패키지를 다운로드하고 프로젝트에서 사용할 수 있도록 합니다.
    • wasm-bindgen의 버전을 명시해주어야 합니다.

ex)

 	[package]
    name = "hello-wasm"
    version = "0.1.0"
    authors = ["Your Name <you@example.com>"]
    description = "A sample project with wasm-pack"
    license = "MIT/Apache-2.0"
    repository = "https://github.com/yourgithubusername/hello-wasm"

    [lib]
    crate-type = ["cdylib"]

    [dependencies]
    wasm-bindgen = "0.2"

Cargo.toml 파일에서 위의 설정을 추가하고 저장한 뒤, WebAssembly로 컴파일할 준비가 되었습니다.

패키지 빌드하기

wasm-pack build --scope mynpmusername

주어진 명령어를 실행하면 wasm-pack이 다음 작업들을 수행합니다.

  1. Rust 코드를 WebAssembly로 컴파일합니다.
  2. wasm-bindgen을 실행하여 WebAssembly를 npm이 이해할 수 있는 모듈로 감싸는 JavaScript 파일을 생성합니다.
  3. pkg 디렉토리를 만들고 JavaScript 파일과 WebAssembly 코드를 해당 디렉토리로 이동시킵니다.
  4. Cargo.toml 파일을 읽고 동등한 package.json 파일을 생성합니다.
  5. README.md 파일이 있다면 패키지로 복사합니다.

빌드가 완료되면 pkg 디렉토리에 npm 패키지가 생성됩니다.

npm에 패키지 배포

    cd pkg
    npm publish --access=public

npm에 우리의 새 패키지를 배포할 수 있습니다.
우리는 이제 Rust로 쓰여졌으나, WebAssembly로 컴파일된 npm 패키지를 갖고 있습니다. 이것은 JavaScript에 쓰일 수 있도록 준비되었으며, 다른 사용자들은 Rust를 설치할 필요가 없습니다. 왜냐하면 패키지에는 WebAssembly 코드만 포함되어있으며, Rust 소스는 없기 때문입니다.

웹상의 패키지 사용하기

주어진 지침에 따라 웹사이트를 빌드해보겠습니다. 아래는 각 단계에 대한 설명입니다:

  1. pkg와 hello-wasm 디렉토리를 빠져나와서 site 디렉토리를 생성하고 해당 디렉토리로 이동합니다.
cd ../..
mkdir site
cd site
  1. package.json 파일을 생성하고 다음 내용을 작성합니다:
  • json
{
  "scripts": {
    "serve": "webpack-dev-server"
  },
  "dependencies": {
    "@mynpmusername/hello-wasm": "^0.1.0"
  },
  "devDependencies": {
    "webpack": "^4.25.1",
    "webpack-cli": "^3.1.2",
    "webpack-dev-server": "^3.1.10"
  }
}

dependencies 섹션에서 @mynpmusername 부분을 실제 npm 계정명으로 대체해야 합니다.

  1. webpack 설정 파일인 webpack.config.js를 생성하고 다음 내용을 작성합니다:
  • javascript
const path = require('path');
module.exports = {
  entry: "./index.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "index.js",
  },
  mode: "development"
};
  1. index.html 파일을 생성하고 다음 내용을 작성합니다:
  • html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>hello-wasm example</title>
  </head>
  <body>
    <script src="./index.js"></script>
  </body>
</html>
  1. HTML에서 참조되는 index.js 파일을 생성하고 다음 내용을 작성합니다:
  • javascript
const js = import("./node_modules/@yournpmusername/hello-wasm/hello_wasm.js");
js.then(js => {
  js.greet("WebAssembly");
});

npm 계정명을 한 번 더 입력해야 합니다.

파일들을 모두 생성했으므로, 다음 명령어를 실행해봅시다:

npm install
npm run serve

이 명령어는 간단한 웹 서버를 시작합니다. http://localhost:8080을 열면 화면에 "Hello, WebAssembly!"라고 쓰여진 alert 창이 표시됩니다. 이제 JavaScript로부터 Rust를 성공적으로 호출했습니다.

출처

https://developer.mozilla.org/ko/docs/WebAssembly/Rust_to_wasm#npm%EC%97%90_%ED%8C%A8%ED%82%A4%EC%A7%80_%EB%B0%B0%ED%8F%AC

profile
what doesn't kill you makes you stronger

0개의 댓글