bytecodealliance / bytecodealliance/cargo-component

Generate WIT, not Rust source code

Open
#387 1 comment 4 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
593
Forks
68
PR merge metrics
No merged PRs in 30d

Description

Currently, to the best of my knowledge, `cargo component` generates a `src/bindings.rs` file using a version of `wit-bindgen` baked directly into the executable `cargo-component` itself. Running `cargo component new` generates a project that depends on `wit-bindgen-rt` at a matching version of what `cargo-component` has baked in to itself.

This is problematic to the development of `wit-bindgen`, unfortunately, because the generated code using `wit-bindgen 0.A.0` generally requires `wit-bindgen-rt 0.A.0` as well, and you can't mix and match versions. Mismatched versions can arise relatively easily with `cargo-component` in two situations:

1. An older project might update to using a newer `cargo-component` executable, meaning that the `Cargo.toml` depends on an older `wit-bindgen-rt` while the executable generates bindings with a newer `wit-bindgen` version.
2. An older project might update `wit-bindgen-rt` but fail to update `cargo-component`, producing the inverse problem where an older `wit-bindgen` is used with a newer `wit-bindgen-rt`.

This is coming up as I'm doing refactoring in `wit-bindgen` and shuffling things around, and ideally I'd prefer to not break `cargo component` users because at this time if anything is added to `wit-bindgen-rt` then users will break.

As an alternative, what I might recommend is to instead have `cargo component` manage WIT, not generated source code. The basic idea is that `cargo component` would generate-and-manage `src/bindings.wit` instead of `src/bindings.rs`. The template for `cargo component new` would add a dependency on `wit-bindgen` but critically wouldn't actually generate any code. For example the generated file might look like:

```rust
wit_bindgen::generate!("./src/bindings.wit");

fn main() {
println!("hello!");
}
```

This should be more idiomatic in terms of `wit-bindgen` usage where it's "just" a call to the `generate!` macro with various options. The key difference is that the input `*.wit` is completely managed by `cargo component` and handles things like dependencies and such which `wit-bindgen` otherwise doesn't do.

My hope is that this wouldn't break things like IDE integration workflows as they in theory already need to work with procedural macros. The upside though is that the `cargo component` executable wouldn't even need to depend on `wit-bindgen` itself because it doesn't generate any Rust code. Instead it only generates a reference to `wit-bindgen` and then a macro invocation. The WIT management all remains in `cargo component`, however.

This would additionally solve the problem of updating/changing `wit-bindgen` as, after inception, it's a per-project decision of when to update `wit-bindgen` which is orthogonal from using `cargo component` as a build tool.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.