From 99bb14ed8b5fdcdc3680cae96e494acdad3a04ac Mon Sep 17 00:00:00 2001 From: James Sturtevant Date: Wed, 25 Feb 2026 13:21:50 -0800 Subject: [PATCH] feat: add world selection for multi-world WIT files Support WIT_WORLD_NAME env var in hyperlight-wasm-macro to select a specific world from WIT files containing multiple worlds. Signed-off-by: James Sturtevant --- CHANGELOG.md | 3 +++ README.md | 26 ++++++++++++++++++++++++++ src/hyperlight_wasm/build.rs | 1 + src/hyperlight_wasm_macro/Cargo.toml | 2 +- src/hyperlight_wasm_macro/src/lib.rs | 7 ++++++- src/wasm_runtime/build.rs | 1 + 6 files changed, 38 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e0792293..7334ae8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). ## [Prerelease] - Unreleased +### Added +- Added support for selecting a specific world from WIT files with multiple worlds using the `WIT_WORLD_NAME` environment variable (#202) + ## [v0.12.0] - 2025-12 ### Added diff --git a/README.md b/README.md index 6b53ebb5..debd3779 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,32 @@ generate bindings from the same component type in the host. For a complete (albeit small) example of this, see [this example](https://aka.ms/hyperlight-wasm-sockets-sample). +### Selecting a specific world + +If your WIT file contains multiple worlds, you can select which world +to use by setting the `WIT_WORLD_NAME` environment variable to the name +of the desired world. If not set, the last world in the file will be used. + +For example, given a WIT file with multiple worlds: + +```wit +package example:worlds; + +world http-world { + export http-interface; +} + +world queue-world { + export queue-interface; +} +``` + +To generate bindings for `http-world` instead of the default `queue-world`: + +``` +WIT_WORLD=/path/to/output.wasm WIT_WORLD_NAME=http-world cargo build -p hyperlight-wasm +``` + ### Debugging the macro You can get more detailed error messages by expanding the Macro locally: diff --git a/src/hyperlight_wasm/build.rs b/src/hyperlight_wasm/build.rs index ed74b622..315fa0ba 100644 --- a/src/hyperlight_wasm/build.rs +++ b/src/hyperlight_wasm/build.rs @@ -103,6 +103,7 @@ fn build_wasm_runtime() -> PathBuf { println!("cargo::rerun-if-changed={}", in_repo_dir.display()); println!("cargo::rerun-if-env-changed=WIT_WORLD"); + println!("cargo::rerun-if-env-changed=WIT_WORLD_NAME"); // the PROFILE env var unfortunately only gives us 1 bit of "dev or release" let cargo_profile = if profile == "debug" { "dev" } else { "release" }; diff --git a/src/hyperlight_wasm_macro/Cargo.toml b/src/hyperlight_wasm_macro/Cargo.toml index 18f29ca2..06a09079 100644 --- a/src/hyperlight_wasm_macro/Cargo.toml +++ b/src/hyperlight_wasm_macro/Cargo.toml @@ -16,4 +16,4 @@ proc-macro2 = { version = "1.0.106" } syn = { version = "2.0.117" } itertools = { version = "0.14.0" } prettyplease = { version = "0.2.37" } -hyperlight-component-util = { version = "0.12.0" } +hyperlight-component-util = { git = "https://github.com/hyperlight-dev/hyperlight.git", branch = "main" } diff --git a/src/hyperlight_wasm_macro/src/lib.rs b/src/hyperlight_wasm_macro/src/lib.rs index 5ed3f8a2..19fdea20 100644 --- a/src/hyperlight_wasm_macro/src/lib.rs +++ b/src/hyperlight_wasm_macro/src/lib.rs @@ -26,10 +26,15 @@ mod wasmguest; /// into wasmtime) and registers wasmtime host functions with the /// wasmtime linker for component imports (which are implemented by /// calling to the Hyperlight host). +/// +/// If the WIT file contains multiple worlds, set the `WIT_WORLD_NAME` +/// environment variable to select a specific world by name. If not set, +/// the last world in the file will be used. #[proc_macro] pub fn wasm_guest_bindgen(_: proc_macro::TokenStream) -> proc_macro::TokenStream { let path = std::env::var_os("WIT_WORLD").unwrap(); - util::read_wit_type_from_file(path, |kebab_name, ct| { + let world_name = std::env::var("WIT_WORLD_NAME").ok(); + util::read_wit_type_from_file(path, world_name, |kebab_name, ct| { let decls = emit::run_state(true, true, |s| { // Emit type/trait definitions for all instances in the world rtypes::emit_toplevel(s, &kebab_name, ct); diff --git a/src/wasm_runtime/build.rs b/src/wasm_runtime/build.rs index 4b19da63..9a9572c8 100644 --- a/src/wasm_runtime/build.rs +++ b/src/wasm_runtime/build.rs @@ -60,6 +60,7 @@ fn main() { cfg.compile("wasm_runtime"); println!("cargo::rerun-if-env-changed=WIT_WORLD"); + println!("cargo::rerun-if-env-changed=WIT_WORLD_NAME"); println!("cargo::rustc-check-cfg=cfg(component)"); if env::var_os("WIT_WORLD").is_some() { println!("cargo::rustc-cfg=component");