Stream: general

Topic: Issues following the component model tutorial


view this post on Zulip Shane Snover (ssnover) (Mar 16 2024 at 23:54):

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!

Contribute to ssnover/wasm-component-tutorial development by creating an account on GitHub.

view this post on Zulip Peter Huene (Mar 17 2024 at 05:19):

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).

view this post on Zulip Shane Snover (ssnover) (Mar 17 2024 at 14:18):

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.

view this post on Zulip Peter Huene (Mar 17 2024 at 19:39):

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.

view this post on Zulip Shane Snover (ssnover) (Mar 17 2024 at 21:10):

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.

view this post on Zulip Peter Huene (Mar 18 2024 at 00:16):

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: Nov 22 2024 at 16:03 UTC