wit-bindgen icon indicating copy to clipboard operation
wit-bindgen copied to clipboard

rust: Generating bindings in `build.rs`

Open tomasol opened this issue 4 months ago • 2 comments

I know there are two supported ways of generating Rust bindings - generate! macro and wit-bindgen CLI.

When using the macro, I find myself regularly restarting rust-analyzer after every change in the wit folder, otherwise the RA does not see the changes.

Using the CLI has its own challenges, e.g. the need to specify default_bindings_module as discussed in this issue

The build.rs approach avoids both of those pitfalls.

use anyhow::Result;
use std::path::Path;
use wit_bindgen_rust::Opts;
use wit_parser::Resolve;

fn main() -> Result<()> {
    println!("cargo:rerun-if-changed=wit/");

    let opts = Opts {
        generate_all: true,
        ..Default::default()
    };
    let mut generator = opts.build();
    let mut resolve = Resolve::default();
    let (pkg, _files) = resolve.push_path("wit")?;
    let main_packages = vec![pkg];
    let world = resolve.select_world(&main_packages, None)?;
    let mut files = Default::default();
    generator.generate(&resolve, world, &mut files)?;

    let out_dir = std::env::var("OUT_DIR").unwrap();
    let dst = Path::new(&out_dir).join("generated.rs");
    let (_name, contents) = files.iter().next().unwrap();
    std::fs::write(&dst, contents)?;
    Ok(())
}
mod generated {
    #![allow(clippy::empty_line_after_outer_attr)]
    include!(concat!(env!("OUT_DIR"), "/generated.rs"));
}

Is this is a supported approach? If so, could it be simplified and documented?

tomasol avatar Nov 18 '25 13:11 tomasol

Happy to take some PRs to help simplify this, I think it's reasonable to keep supporting it yeah

alexcrichton avatar Nov 18 '25 18:11 alexcrichton

I've added a draft PR to address this, looking for feedback.

tomasol avatar Nov 30 '25 19:11 tomasol