dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.25k stars 4.73k forks source link

WASI components import `wasi:cli/environemnt` and `wasi:cli/exit` when not being used #107405

Open jsturtevant opened 1 month ago

jsturtevant commented 1 month ago

problem statement

When building a component for wasi:http when running in wasmtime I get the following error:

wasmtime serve .\bin\Debug\net8.0\wasi-wasm\native\MyApp.wasm --addr 127.0.0.1:3000
Error: component imports instance `wasi:cli/environment@0.2.0`, but a matching implementation was not found in the linker

Caused by:
    0: instance export `get-environment` has the wrong type
    1: function implementation is missing

When inspecting the component built I see imports for wasi:cli/environemnt and wasi:cli/exit, even though I only built against the wasi:http world:

wasm-tools.exe component wit .\bin\Debug\net8.0\wasi-wasm\native\MyApp.wasm
package root:component;

world root {
  import wasi:cli/environment@0.2.0;
  import wasi:cli/exit@0.2.0;
....

I was able to work around it by telling wasmtime to provide the cli imports:

wasmtime serve -S cli ...

question

Should these imports be included in the component? Is there a way to detect during compilation if the env/exit are being used and not include them?

Discussion in Bytecode Alliance Zulip: https://bytecodealliance.zulipchat.com/#narrow/stream/407028-C.23.2F.2Enet-collaboration/topic/missing.20implementation.20was.20not.20found.20in.20linker

example

https://github.com/jsturtevant/wasi-http-oci

dicej commented 1 month ago

Note that you can specify -Wl,--wasi-adapter,proxy to the linker (e.g. as a CustomLinkerArg) when targeting wasi-http, which will stub out those imports.

SingleAccretion commented 1 month ago

It is by design that the actual imports is a superset of "used" imports (including from other worlds). I expect that in the long term, as both WASI and .NET's use of it mature, this set will only grow.

CustomLinkerArg

CustomLinkerArg -> LinkerArg (https://github.com/dotnet/runtime/pull/107194#issuecomment-2322059659).

dotnet-policy-service[bot] commented 1 month ago

Tagging subscribers to 'arch-wasm': @lewing See info in area-owners.md if you want to be subscribed.

jsturtevant commented 1 month ago

It is by design that the actual imports is a superset of "used" imports (including from other worlds). I expect that in the long term, as both WASI and .NET's use of it mature, this set will only grow.

I guess I am not following this fully. In this case the component implements wasi-http not wasi-cli. Why would it have wasi-cli imports if it's not using it?

SingleAccretion commented 1 month ago

I guess I am not following this fully. In this case the component implements wasi-http not wasi-cli

The .NET runtime assumes that it has access to the full "system library"; it differentiates these libraries by the OS component of the RID. Since we only have wasi-wasm, there is one and only monolithic WASI.

Why would it have wasi-cli imports if it's not using it?

There is a path somewhere (which could be dynamically unreachable) that eventually calls the imports. Consider e. g. that a lot of knobs that .NET exposes are configured via environment variables.