I've been trying to learn how to build components and checked out this tutorial here: https://component-model.bytecodealliance.org/tutorial.html
After some false starts, I managed to get three wasm files built from referencing the given WIT file (instead of the default location wit file generated by cargo-component). I'm running into problems trying to compose them however:
$ wasm-tools compose /path/to/calculator.wasm -d /path/to/adder.wasm -o composed.wasm
[2024-03-16T23:40:21Z WARN ] instance `docs:calculator/add@0.1.0` will be imported because a dependency named `docs:calculator/add@0.1.0` could not be found
[2024-03-16T23:40:21Z WARN ] instance `wasi:cli/environment@0.2.0` will be imported because a dependency named `wasi:cli/environment@0.2.0` could not be found
[2024-03-16T23:40:21Z WARN ] instance `wasi:cli/exit@0.2.0` will be imported because a dependency named `wasi:cli/exit@0.2.0` could not be found
[2024-03-16T23:40:21Z WARN ] instance `wasi:io/error@0.2.0` will be imported because a dependency named `wasi:io/error@0.2.0` could not be found
[2024-03-16T23:40:21Z WARN ] instance `wasi:io/streams@0.2.0` will be imported because a dependency named `wasi:io/streams@0.2.0` could not be found
[2024-03-16T23:40:21Z WARN ] instance `wasi:cli/stdin@0.2.0` will be imported because a dependency named `wasi:cli/stdin@0.2.0` could not be found
[2024-03-16T23:40:21Z WARN ] instance `wasi:cli/stdout@0.2.0` will be imported because a dependency named `wasi:cli/stdout@0.2.0` could not be found
[2024-03-16T23:40:21Z WARN ] instance `wasi:cli/stderr@0.2.0` will be imported because a dependency named `wasi:cli/stderr@0.2.0` could not be found
[2024-03-16T23:40:21Z WARN ] instance `wasi:clocks/wall-clock@0.2.0` will be imported because a dependency named `wasi:clocks/wall-clock@0.2.0` could not be found
[2024-03-16T23:40:21Z WARN ] instance `wasi:filesystem/types@0.2.0` will be imported because a dependency named `wasi:filesystem/types@0.2.0` could not be found
[2024-03-16T23:40:21Z WARN ] instance `wasi:filesystem/preopens@0.2.0` will be imported because a dependency named `wasi:filesystem/preopens@0.2.0` could not be found
error: no dependencies of component `/path/to/calculator.wasm` were found
The first warning was unexpected to me, as I would expect that to be made available by the adder.wasm
dep being passed on the CLI. All of the remaining errors are unexpected to me as calculator.wasm
was built from a lib crate and while the target was wasm32-wasi
, none of those symbols are referenced in the WIT file (or my program).
I don't think I've deviated in any way, but here's a repo with the full source in play here just in case: https://github.com/ssnover/wasm-component-tutorial
Just so I'm sure I understand the warnings: When it says will be imported, does that mean that it searches the provided dependencies? The phrasing of the first warning about adder strikes me as odd as I wouldn't expect a warning if it had searched the dependencies, I would expect an error. On the other hand, if it hadn't it seems like it shouldn't be a warning, since that's the happy path of linking a dependency.
Thanks!
Hi Shane! I'm unable to reproduce the error, as when I clone your repo, do a cargo component build
in adder
, a cargo component build
in calculator
, then finally a wasm-tools compose calculator/target/wasm32-wasi/debug/calculator.wasm -d adder/target/wasm32-wasi/debug/adder.wasm -o composed.wasm
, I get a successful composition.
That said, the way the -d
option works in wasm-tools compose
is that it registers the exports of the provided component as potential dependencies to satisfy instantiation arguments with; the (potentially poorly worded) warning is letting you know that a dependency to satisfy the import docs:calculator/add@0.1.0
of calculator.wasm
could not be located, so it will remain an import in the composed component. One reason for this is that your adder.wasm
is not exporting using the expected name, perhaps?
Try setting the RUST_LOG=debug
environment variable when running wasm-tools compose
; there might be useful diagnostic information to determine why the export from adder doesn't match the import from calculator.
The remaining warnings for all of the WASI instances is because the tool was written well before WASI preview 2 was a thing, so it treats those imports like any other import; those warnings are expected for practically every component that uses WASI as a result. We should probably elide those warnings entirely (although I'm working on a replacement for wasm-tools compose
that doesn't behave this way at all).
Hey Peter! Thanks for checking out my test repo and confirming I've at least got the build set up right now (it seems maybe my compiled adder.wasm
was left over from a previous configuration).
Your explanation points out a potential hole in my knowledge: when a component is compiled can it be compiled such that not all of its imported symbols are linked? (i.e. maybe with the expectation that they'll be linked to host runtime symbols?) Did my invocation fail specifically because it could not resolve any of the imports then, since it's okay to not resolve all of them?
The additional logging statements help a lot, and confirm that I had made some changes after my most recent build of adder.wasm
. Is there a tool specifically for listing the imports and exports for a .wasm
file? I tried going through the wasm-tools objdump
subcommand looking for precisely the list of imports/exports that shows up in the debug logs of compose
, but had no luck there. I see in the usage text that it mentions objdump
is relatively incomplete.
when a component is compiled can it be compiled such that not all of its imported symbols are linked? (i.e. maybe with the expectation that they'll be linked to host runtime symbols?)
Yes, imports are not statically linked at compilation time and remain imports in the output module/component, with the expectation that either a host or, in the case of the component model, another component may satisfy the imports via a composition.
Eventually cargo-component
will have some functionality around automatically composing dependencies into the output, if desired, but it currently lacks that feature.
Did my invocation fail specifically because it could not resolve any of the imports then, since it's okay to not resolve all of them?
That's correct, the tool will error if none of the imports were satisfied by a dependency as otherwise the output would be identical to the input; at least one of the imports must be satisfied for the tool to output a composed component.
Is there a tool specifically for listing the imports and exports for a .wasm file?
I generally use wasm-tools print
on the component and look for the imports / exports, but that can be verbose; I don't know of a tool that prints only that information, but it would be easy to write and useful enough to include in wasm-tools
, I think.
Thanks for answering all my questions here! I'll look into writing something like that, I find imported/exported symbols to be the first thing I look to when I'm debugging linking with native binary objects.
Also, for components there is wasm-tools component wit
that will show the world representation of the component as WIT, which can be one way of seeing its imports and exports.
Last updated: Dec 23 2024 at 13:07 UTC