Skip to content

Commit 2416d7b

Browse files
committed
feat: adding bindings command
Signed-off-by: Andrew Steurer <94206073+asteurer@users.noreply.github.com>
1 parent ed85413 commit 2416d7b

13 files changed

Lines changed: 143 additions & 53 deletions

File tree

Cargo.lock

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ clap = { version = "4.5.53", features = ["derive"] }
1313
regex = "1.12.2"
1414
url = "2.5.7"
1515
wat = { version = "1.243.0"}
16+
wit-bindgen-go = "0.50.0"
1617
wit-component = "0.243.0"
1718
wit-parser = "0.243.0"

examples/wasip2/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
generate-bindings:
2-
wit-bindgen go --world bindings --out-dir . wit
2+
componentize-go --world wasip2-example bindings
33

44
build-component: generate-bindings
5-
componentize-go --world bindings componentize
5+
componentize-go --world wasip2-example componentize
66

77
.PHONY: run
88
run: build-component

examples/wasip2/README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
- [**componentize-go**](https://github.com/asteurer/componentize-go) - Latest version
55
- [**go**](https://go.dev/dl/) - v1.25+
66
- [**wasmtime**](https://github.com/bytecodealliance/wasmtime) - Latest version
7-
- [**wit-bindgen**](https://github.com/bytecodealliance/wit-bindgen) - Latest version
87

98
### Run
109
```sh

examples/wasip2/wit/world.wit

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// We actually don't use this; it's just to let bindgen! find the corresponding world in wit/deps.
22
package wasmtime:wasi-http;
33

4-
world bindings {
4+
world wasip2-example {
55
include wasi:http/proxy@0.2.0;
66
}

examples/wasip3/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ $(GO)/bin/go:
55
tar xf $(GO).tbz
66

77
generate-bindings:
8-
wit-bindgen go --world bindings --out-dir . wit
8+
componentize-go --world wasip3-example bindings
99

1010
build-component: generate-bindings $(GO)/bin/go
11-
componentize-go --world bindings componentize --go $(GO)/bin/go
11+
componentize-go --world wasip3-example componentize --go $(GO)/bin/go
1212

1313
.PHONY: run
1414
run: build-component

examples/wasip3/README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@ everything is merged, we'll be able to switch to the upstream releases.
1313
## Building and Running
1414
### Prerequisites
1515
- [**componentize-go**](https://github.com/asteurer/componentize-go) - Latest version
16-
- [**go**](https://github.com/dicej/go/releases/tag/go1.25.5-wasi-on-idle) - The Makefile installs this for you
16+
- [**go**](https://github.com/dicej/go/releases/tag/go1.25.5-wasi-on-idle) - The [Makefile](./Makefile) installs the patched version of Go.
1717
- [**wasmtime**](https://github.com/bytecodealliance/wasmtime) - Latest version
18-
- [**wit-bindgen**](https://github.com/bytecodealliance/wit-bindgen) - Latest version
1918

2019
This will build the dependencies, generate Go bindings from the
2120
`wasi:http@0.3.0-rc-2025-09-16` WIT files, build the component, and run it using

examples/wasip3/wit/world.wit

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// We actually don't use this; it's just to let bindgen! find the corresponding world in wit/deps.
22
package wasmtime:wasi-http;
33

4-
world bindings {
4+
world wasip3-example {
55
include wasi:http/proxy@0.3.0-rc-2025-09-16;
66
}

src/bindings.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
use crate::common::parse_wit;
2+
use anyhow::Result;
3+
use std::path::{Path, PathBuf};
4+
5+
pub fn generate_bindings(
6+
wit_path: &[impl AsRef<Path>],
7+
world: Option<&str>,
8+
features: &[String],
9+
all_features: bool,
10+
output: Option<&Path>,
11+
) -> Result<()> {
12+
let (resolve, world) = parse_wit(wit_path, world, features, all_features)?;
13+
let mut files = Default::default();
14+
15+
wit_bindgen_go::Opts::default()
16+
.build()
17+
.generate(&resolve, world, &mut files)?;
18+
19+
let output_path = match output {
20+
Some(p) => {
21+
if p.is_relative() {
22+
std::env::current_dir()?.join(p)
23+
} else {
24+
p.to_path_buf()
25+
}
26+
}
27+
None => PathBuf::from("."),
28+
};
29+
30+
for (name, contents) in files.iter() {
31+
let file_path = output_path.join(name);
32+
if let Some(parent) = file_path.parent() {
33+
std::fs::create_dir_all(parent)?;
34+
}
35+
36+
std::fs::write(&file_path, contents)?;
37+
}
38+
39+
Ok(())
40+
}

src/command.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::componentize;
1+
use crate::{bindings::generate_bindings, componentize};
22
use anyhow::Result;
33
use clap::{Parser, Subcommand};
44
use std::{ffi::OsString, path::PathBuf};
@@ -48,6 +48,9 @@ pub struct Common {
4848
pub enum Command {
4949
/// Build a Go WebAssembly component.
5050
Componentize(Componentize),
51+
52+
/// Generate Go bindings for the world.
53+
Bindings(Bindings),
5154
}
5255

5356
#[derive(Parser)]
@@ -69,9 +72,19 @@ pub fn run<T: Into<OsString> + Clone, I: IntoIterator<Item = T>>(args: I) -> Res
6972
let options = Options::parse_from(args);
7073
match options.command {
7174
Command::Componentize(opts) => componentize(options.common, opts),
75+
Command::Bindings(opts) => bindings(options.common, opts),
7276
}
7377
}
7478

79+
#[derive(Parser)]
80+
pub struct Bindings {
81+
/// Output directory for bindings (or current directory if `None`).
82+
///
83+
/// This will be created if it does not already exist.
84+
#[arg(long, short = 'o')]
85+
pub output: Option<PathBuf>,
86+
}
87+
7588
fn componentize(common: Common, componentize: Componentize) -> Result<()> {
7689
// Step 1: Build a WebAssembly core module using Go.
7790
let core_module = componentize::build_wasm_core_module(
@@ -93,3 +106,13 @@ fn componentize(common: Common, componentize: Componentize) -> Result<()> {
93106
componentize::core_module_to_component(&core_module)?;
94107
Ok(())
95108
}
109+
110+
fn bindings(common: Common, bindings: Bindings) -> Result<()> {
111+
generate_bindings(
112+
common.wit_path.as_ref(),
113+
common.world.as_deref(),
114+
&common.features,
115+
common.all_features,
116+
bindings.output.as_deref(),
117+
)
118+
}

0 commit comments

Comments
 (0)