Comments (5)
The development of cargo-component
has gone through a few designs now relating to generating bindings.
The initial design was that cargo-component
would generate a behind-the-scenes bindings crate that would be magically linked against as a dependency of the user's component project so that bindings
would be seen as a normal crate of the generated code. To make that work, cargo-component
directly depended on the cargo
crate, which is a very large dependency as it make cargo-component
effectively a copy of cargo
with some component model bits bolted on.
It worked that way until support for resources was implemented in wit-bindgen
; at that point the generated bindings needed to explicitly know the Rust names of implementing types, which is why the wit_bindgen::generate!
macro takes arguments to name them. Taking inspiration from wit_bindgen::generate!
, a cargo_component_bindings::generate!
macro was implemented to accept these arguments and pass it under the covers to wit-bindgen
; however, this macro's implementation differed from wit_bindgen::generate!
in that it read no WIT source files; instead it would "deserialize" a resolved WIT document from a tiny wasm file generated by cargo-component
. This allowed cargo-component
itself complete control over the target world.
While this new design allowed cargo-component
to spawn cargo
and break its dependency on the cargo
crate to both greatly reduce its build time and executable size, it had the downside of increasing the time it takes to build a user's component as it pushed the wit-bindgen
dependency onto the user's package. It also made CI significantly slower, as it spends a lot of time building components.
To restore the component build-time impressions of users, I decided to put the code generation fully back in cargo-component
; this sped up build times and CI, but turned the generate!
macro into a filthy liar as it was ultimately reduced to simply including a source file generated by cargo-component
. I choose not to rename the macro at the time as there was enough recent breakage from introducing it in the first place.
Ultimately this leaves us with the question "why not simply use wit_bindgen::generate!
directly or wrap it with ?" if it means reducing the complexity of bindings generation and making a happier rust-analyzer
by default, at the cost of increased component build times?
The answer is that cargo-component
is designed to be a component-registry-first tool, similar to how cargo
is a crates.io
-first tool. Users should be able to easily target a world even seeing a WIT file and they should be able to consume interfaces from WASI and elsewhere in their custom WIT definitions without copying dependency files around like the Internet isn't a thing.
That support exists in cargo-component
today; the elephant in the room is that an operational registry service it can talk to does not. This is something being actively worked on, so hopefully this will all make sense from a DX perspective in the near (but quite long overdue) future.
from cargo-component.
That said, I'm happy to take a breaking change to rename the macro to something more suitable.
A better approach, I think, is to probably stop hiding behind magic and remove the macro entirely.
If instead we simply generated the bindings into src/bindings.rs
(possibly with a destination override in Cargo.toml
) with a big "this is a generated file" warning on top and had cargo component new
replace the macro invocation with a mod bindings
, then it would probably solve a lot of problems.
from cargo-component.
Removing the macro proved to be relatively straight forward to implement.
I'll put up a PR to see if we want to include the (very much breaking) change with the imminent cargo-component
release.
from cargo-component.
@peterhuene Thanks for the clear explanation. I have migrated my project to v0.7.0
to understand the change better. Here are my observations:
- generated bindings add some noise to PRs, although this can be mitigated using
.gitattributes
- if not all functions are used, they trigger a cargo warning. This can be fixed by prepending
#![allow(dead_code)]
to each file - after I've fixed it in my fork, bindings were not regenerated. This is because nix sets mtime of the exe to the start of Unix epoch.
There is a concern that using a registry would cause delays.. But even in that case, I would expect (same as with cargo) to have the wit files downloaded once and stored in a local cache.
I haven't seen generating sources in other Rust projects, but one nice thing is that the auto-complete finally works 🎉 . Hopefully rust-analyzer will be fixed soon. Perhaps in the future users could be able to choose between the proc-macro and the generated sources.
BTW, how are the resources configured now that the macro is gone? I haven't used this feature yet.
from cargo-component.
if not all functions are used, they trigger a cargo warning. This can be fixed by prepending #![allow(dead_code)] to each file
One can append #[allow(dead_code)]
to mod bindings
too, but I decided not to as I think we should be treating any dead code warnings coming from the bindings as bugs (either the emitted code could have the proper allows or dead code shouldn't be emitted).
after I've fixed it in my fork, bindings were not regenerated. This is because nix sets mtime of the exe to the start of Unix epoch.
That's unfortunate (but I'm sure there's a good reason for doing that). A workaround is to just touch Cargo.toml
for the same effect, but perhaps we should keep track of what version of cargo-component
generated the bindings and regenerate it if they differ, rather than using the executable mtime.
There is a concern that using a registry would cause delays.. But even in that case, I would expect (same as with cargo) to have the wit files downloaded once and stored in a local cache.
For what it's worth, the registry client implementation does cache packages locally, but it doesn't use .wit files; it uses .wasm files (encoded from wit source files) instead.
BTW, how are the resources configured now that the macro is gone? I haven't used this feature yet.
cargo-component
picks a default type name for any resources, which can be overridden by settings under the [package.metadata.component.bindings]
table in Cargo.toml
.
from cargo-component.
Related Issues (20)
- `cargo component check --workspace` should not generate bindings for workspace members without `[package.metadata.component]` set HOT 2
- `cargo-component` is not acquring a file lock for componentization
- Document the schema of the cargo-component Cargo.toml configuration HOT 3
- Hello world example fails when project name contains underscore HOT 1
- Add a `cargo component serve` subcommand that uses a default runner of `wasmtime serve`
- wit pubilsh --init fails to register the WIT package to wa.dev, while it successfully create a pacakge on the registry HOT 4
- Build fails with 'failed to create a target world for package ...' HOT 2
- Use something like nightly.link or a non-re-published release to avoid excess notifications
- Build error: `error: string size out of bounds (at offset {offset})` HOT 10
- Additional `import`s in generated component HOT 2
- Resource Static Methods Cause Build Failure When Imported HOT 5
- Wit package name/version validated against registry publishes
- Some wasi imports added per default into wit HOT 2
- cargo install cargo-component error HOT 5
- Compile error when installing cargo component HOT 7
- Minimum Supported Rust Version (MSRV)
- Bindings are sometimes incorrectly generated type + `Borrow` suffix vs `&` type HOT 2
- `cargo component add` not producing runnable/usable binaries
- Cargo Component install give error in RPI 4 (ARM CORTEX-A72) HOT 3
- Update to `-S cli` instead of `-S common` for wasmtime commands
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cargo-component.