Skip to content

rust: Generating bindings in build.rs #1423

@tomasol

Description

@tomasol

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    gen-rustRelated to bindings for Rust-compiled-to-WebAssembly

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions