실행 가능한 컴포넌트 만들기 (Rust)
이 페이지에는 WASI 0.2와 WASI 0.3에 대한 내용이 모두 포함되어 있습니다. 버전 간에 차이가 있는 부분에서는 아래 탭을 사용하여 버전을 전환하십시오.
WASI 0.3 툴체인 참고 사항. Rust의
wasm32-wasip3대상은 현재 Tier 3이며 미리 빌드된 아티팩트가 없습니다. 이 대상으로 빌드하려면 표준 라이브러리를 소스에서 직접 빌드해야 합니다. 따라서 이 페이지의 0.3 예제는wasm32-wasip2를 타깃으로 하는 라이브러리/리액터 패턴을 사용하며, 여기서는wit-bindgen의async기능이 0.3 바인딩 생성을 처리합니다.fn main()커맨드 컴포넌트 패턴에 대해서는 아직 Rust다운 0.3 방식이 없습니다.
command 컴포넌트 만들기
커맨드는 wasmtime(또는 다른 wasi:cli 호스트)에서 직접 실행할 수 있도록 하는 특정 익스포트를 가진 컴포넌트입니다. Rust 관점에서 보면, 이는 라이브러리 크레이트(lib) 패키지가 아니라 main 함수가 있는 애플리케이션(bin) 패키지에 해당합니다.
command 컴포넌트는 컴포넌트에 자연스러운 main 형태의 시작점이 있음을 나타내는 WebAssembly 코어 익스포트 _start를 포함하는 방식으로 동작합니다.
1. 새 Rust 바이너리 프로젝트 만들기
cargo로 커맨드를 만들려면 다음을 실행하십시오:
cargo new runnable-example
라이브러리 컴포넌트와 달리, 여기에는 --lib 플래그가 없습니다(cargo new의 기본값은 --bin입니다).
생성된 Rust 소스 파일의 이름은 lib.rs가 아니라 main.rs이며, main 함수를 포함합니다.
이 프로젝트에서는 직접 만든 크레이트나 서드파티 크레이트를 임포트하는 것을 포함하여 평소와 똑같이 Rust 코드를 작성할 수 있습니다.
프로젝트를 구성하는 모든 크레이트는 빌드 시점에 함께 링크되어 하나의 Wasm 컴포넌트로 컴파일됩니다. 이 경우 모든 링크는 Rust 수준에서 이루어지며, WIT나 컴포넌트 합성은 관여하지 않습니다. Wasm 인터페이스를 임포트하는 경우에만 WIT와 합성이 관여하게 됩니다.
2. 관련 Rust 코드 작성하기
다음 코드를 runnable-example/src/main.rs에 삽입할 수 있습니다:
pub fn main() {
eprintln!("Hello World!");
}
3. 컴포넌트 빌드하기
컴포넌트를 빌드하려면 cargo를 사용하십시오:
cargo build --target=wasm32-wasip2
컴포넌트를 릴리스 모드로 빌드할 수도 있습니다:
cargo build --target=wasm32-wasip2 --release
4. wasmtime으로 컴포넌트 실행하기
command 컴포넌트를 실행하려면 다음과 같이 하십시오.
wasmtime run ./target/wasm32-wasip2/debug/runnable-example.wasm
0.3
wasi:cli/run인터페이스를 익스포트하는 실행 가능한 컴포넌트에 대해서는 아래의 라이브러리/리액터 패턴을 참조하십시오.
라이브러리 컴포넌트를 wasi:cli/run 인터페이스를 통해 실행할 수 있도록 하기
때로는 (익스포트된 인터페이스를 통해) 라이브러리로 사용할 수 있으면서도 command 컴포넌트처럼 단독으로 실행할 수도 있는 컴포넌트를 만드는 것이 유용합니다.
리액터(라이브러리형) 컴포넌트는 직접 사용하도록 의도된 인터페이스를 익스포트하지만, WASI CLI의 wasi:cli/run 인터페이스를 함께 익스포트하여 이 라이브러리가 명령줄 인터페이스를 통해 실행되는 바이너리와 유사하게 실행될 수도 있음을 소비자에게 알릴 수 있습니다.
command 컴포넌트와 달리 라이브러리 컴포넌트에는 _start가 없지만, wasi:cli/run 인터페이스를 익스포트하면 이러한 익스포트를 인식하는 도구가 주어진 WebAssembly 바이너리를 쉽게 실행할 수 있습니다(예: wasmtime run).
1. 새 Rust 라이브러리 프로젝트 생성하기
wasi:cli/run을 익스포트하는 간단한 컴포넌트를 빌드하려면 먼저 새 Rust 프로젝트를 생성하십시오:
cargo new --lib runnable-example
새 프로젝트를 생성한 후 runnable-example/Cargo.toml을 수정하여 다음 줄을 추가함으로써 cdylib 크레이트가 되도록 하십시오:
[lib]
crate-type = ['cdylib']
WIT 인터페이스로부터 Rust 바인딩도 생성할 것이므로 wit-bindgen을 추가하십시오:
cargo add wit-bindgen
2. 적절한 WIT 인터페이스 추가하기
그런 다음 적절한 WIT 인터페이스를 추가하십시오. 예를 들어 “Hello World“를 출력하는 간단한 컴포넌트의 경우, runnable-example/wit/component.wit에 다음 내용을 추가하십시오:
package example:runnable;
interface greet {
greet: func(name: string) -> string;
}
world greeter {
export greet;
export wasi:cli/run@0.2.7;
}
이러한 방식으로 라이브러리 컴포넌트를 빌드하면 다음 두 가지가 이루어집니다:
- 다른 컴포넌트/호스트가
greet인터페이스를 사용할 수 있게 합니다 - 이 컴포넌트가 CLI처럼 실행될 수 있음을 나타내는 인터페이스(
wasi:cli/run)를 노출합니다- 컴포넌트가 실행될 때 무엇을 하는지에 대해서는 아무것도 보장되지 않는다는 점에 유의하십시오
greet는 우리가 만든 것이지만, wasi:cli는 잘 알려진 인터페이스입니다. wkg를 사용하여 이 인터페이스를 로컬 WIT로 해석할 수 있습니다:
wkg wit fetch
WASI 0.3의 경우
wkg0.15 이상을 사용하십시오. 이전 버전은wasi:cli@0.3.0-rc-2026-03-15패키지를 디코딩하지 못합니다.
이 시점에서 deps 하위 폴더와 원래의 component.wit이 포함된 wit 폴더가 있어야 합니다.
다른 컴포넌트나 플랫폼이 greet 인터페이스 익스포트를 사용할 수 있으므로, 위 WIT를 충족하도록 만들 컴포넌트는 라이브러리로 사용될 수 있습니다. 더 중요한 점은, 이 컴포넌트가 wasi:cli/run 덕분에 범용적으로 실행 가능한 컴포넌트로도 인식될 수 있으므로, wasi:cli 인터페이스를 지원하거나 인식하는 모든 도구(예: wasmtime run)와 함께 동작할 수 있다는 것입니다.
3. 컴포넌트 코드 작성하기
다음 코드를 runnable-example/src/lib.rs에 삽입할 수 있습니다:
#![allow(unused)]
fn main() {
mod bindings {
use super::Component;
wit_bindgen::generate!();
export!(Component);
}
/// Component off of which implementation will hang (this can be named anything)
struct Component;
/// Implementation for the `greet` interface export
impl bindings::exports::example::runnable::greet::Guest for Component {
fn greet(name: String) -> String {
format!("Hello {name}!")
}
}
/// Implementation for `wasi:cli/run` interface export
impl bindings::exports::wasi::cli::run::Guest for Component {
fn run() -> Result<(), ()> {
eprintln!("Hello World!");
Ok(())
}
}
}
4. 컴포넌트 빌드하기
컴포넌트를 빌드하려면 cargo를 사용하십시오:
cargo build --target=wasm32-wasip2
컴포넌트는 릴리스 모드로도 빌드할 수 있습니다:
cargo build --target=wasm32-wasip2 --release
5. wasmtime으로 컴포넌트 실행하기
wasmtime으로 컴포넌트를 실행할 수 있으며, 일반적인 리액터 컴포넌트와 달리 실행할 인터페이스와 함수를 지정할 필요가 없습니다(wasi:cli/run이 자동으로 감지되어 사용됩니다):
$ wasmtime run target/wasm32-wasip2/debug/runnable_example.wasm
Hello World!
Cargo는 라이브러리 크레이트 이름의 하이픈을 밑줄로 변환하므로, 패키지를
runnable-example로 생성했더라도 아티팩트는runnable_example.wasm이 됩니다.
버전 고정. WASI 0.3 도구(
wit-bindgen, Wasmtime, jco 등)는 모두 동일한 WIT 버전을 대상으로 해야 합니다. 2026-06-11 WASI 0.3.0 릴리스 시점 기준으로wit-bindgen0.58과 Wasmtime 45는 여전히 WIT의0.3.0-rc-2026-03-15스냅샷을 포함하고 있으므로, 해당 도구들이 갱신되기 전까지 게시된0.3.0으로 고정하면 실행 시점에no exported instance named wasi:cli/run@0.2.6(또는 이와 유사한) 오류가 발생합니다. 그때까지는 RC 버전으로 고정하십시오.