Skip to content

Commit 4e7b231

Browse files
authored
Add new functions to generate rust bindings in build.rs (#1444)
* Add new functions to generate rust bindings in `build.rs` Add `RustWasm::generate_to_out_dir` that parses the `wit` folder, selects a world, generates bindings and places them in a file in the `OUT_DIR`. `generate_to_out_dir_modify` allows modifying the generated file. * Use world name as output path in `generate_to_out_dir`
1 parent 33e7748 commit 4e7b231

File tree

3 files changed

+32
-4
lines changed

3 files changed

+32
-4
lines changed

crates/guest-rust/macro/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use syn::punctuated::Punctuated;
88
use syn::spanned::Spanned;
99
use syn::{LitStr, Token, braced, token};
1010
use wit_bindgen_core::AsyncFilterSet;
11+
use wit_bindgen_core::WorldGenerator;
1112
use wit_bindgen_core::wit_parser::{PackageId, Resolve, UnresolvedPackageGroup, WorldId};
1213
use wit_bindgen_rust::{Opts, Ownership, WithOption};
1314

crates/rust/src/lib.rs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use indexmap::{IndexMap, IndexSet};
66
use std::collections::{BTreeMap, HashMap, HashSet};
77
use std::fmt::{self, Write as _};
88
use std::mem;
9+
use std::path::{Path, PathBuf};
910
use std::str::FromStr;
1011
use wit_bindgen_core::abi::{Bitcast, WasmType};
1112
use wit_bindgen_core::{
@@ -26,7 +27,7 @@ struct InterfaceName {
2627
}
2728

2829
#[derive(Default)]
29-
struct RustWasm {
30+
pub struct RustWasm {
3031
types: Types,
3132
src_preamble: Source,
3233
src: Source,
@@ -277,15 +278,41 @@ pub struct Opts {
277278
}
278279

279280
impl Opts {
280-
pub fn build(self) -> Box<dyn WorldGenerator> {
281+
pub fn build(self) -> RustWasm {
281282
let mut r = RustWasm::new();
282283
r.skip = self.skip.iter().cloned().collect();
283284
r.opts = self;
284-
Box::new(r)
285+
r
285286
}
286287
}
287288

288289
impl RustWasm {
290+
/// Generates Rust bindings from the `wit/` directory and writes
291+
/// the result into Cargo’s `OUT_DIR`. Intended for use in `build.rs`.
292+
///
293+
/// The `world` parameter specifies the world name to select.
294+
/// It must be provided unless the main package contains exactly one world.
295+
///
296+
/// Returns the full path to the generated bindings file.
297+
pub fn generate_to_out_dir(mut self, world: Option<&str>) -> Result<PathBuf> {
298+
let mut resolve = Resolve::default();
299+
println!("cargo:rerun-if-changed=wit/");
300+
let (pkg, _files) = resolve.push_path("wit")?;
301+
let main_packages = vec![pkg];
302+
let world = resolve.select_world(&main_packages, world)?;
303+
304+
let mut files = Files::default();
305+
self.generate(&resolve, world, &mut files)?;
306+
let out_dir = std::env::var("OUT_DIR").expect("cargo sets OUT_DIR");
307+
let (name, contents) = files
308+
.iter()
309+
.next()
310+
.expect("exactly one file should be generated");
311+
let dst = Path::new(&out_dir).join(name);
312+
std::fs::write(&dst, contents)?;
313+
Ok(dst)
314+
}
315+
289316
fn new() -> RustWasm {
290317
RustWasm::default()
291318
}

src/bin/wit-bindgen.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ fn main() -> Result<()> {
145145
#[cfg(feature = "cpp")]
146146
Opt::Cpp { opts, args } => (opts.build(args.out_dir.as_ref()), args),
147147
#[cfg(feature = "rust")]
148-
Opt::Rust { opts, args } => (opts.build(), args),
148+
Opt::Rust { opts, args } => (Box::new(opts.build()) as Box<dyn WorldGenerator>, args),
149149
#[cfg(feature = "go")]
150150
Opt::Go { opts, args } => (opts.build(), args),
151151
#[cfg(feature = "csharp")]

0 commit comments

Comments
 (0)