Skip to content

Commit fd0dc72

Browse files
committed
Remove emscripten dependency
Signed-off-by: James Sturtevant <[email protected]>
1 parent a66f726 commit fd0dc72

File tree

3 files changed

+16
-59
lines changed

3 files changed

+16
-59
lines changed

Directory.Packages.props

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
44
</PropertyGroup>
55
<ItemGroup>
6-
<PackageVersion Include="Microsoft.DotNet.ILCompiler.LLVM" Version="8.0.0-preview.7.23503.1" />
7-
<PackageVersion Include="runtime.win-x64.Microsoft.DotNet.ILCompiler.LLVM" Version="8.0.0-preview.7.23503.1" />
6+
<PackageVersion Include="Microsoft.DotNet.ILCompiler.LLVM" Version="9.0.0-preview.5.24304.1" />
7+
<PackageVersion Include="runtime.win-x64.Microsoft.DotNet.ILCompiler.LLVM" Version="9.0.0-preview.5.24304.1" />
88

99
<!-- Tests -->
1010
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.6.0" />

README.md

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ If you have any questions of problems feel free to reach out on the [c# zulip c
1010

1111
This is to simplify using Wasm components in c#.
1212

13-
Without this package, if you wanted to build a WASI preview 2 component with .NET, including using WIT imports/exports, there are about 5 different tools you'd need to discover, download, configure, and manually chain together. Just figuring out which versions of each are compatible with the others is a big challenge. Working out how to get started would be very painful.
13+
Without this package, if you wanted to build a WASI 0.2 component with .NET, including using WIT imports/exports, there are several different tools you'd need to discover, download, configure, and manually chain together. Just figuring out which versions of each are compatible with the others is a big challenge. Working out how to get started would be very painful.
1414

1515
With this package, you can add one NuGet reference. The build output is fully AOT compiled and is known to work in recent versions of wasmtime and WAMR.
1616

@@ -22,9 +22,7 @@ With this package, you can add one NuGet reference. The build output is fully AO
2222

2323
### 1. Set up SDKs
2424

25-
If you don't already have it, install [.NET 8 SDK](https://dotnet.microsoft.com/en-us/download/dotnet/8.0)
26-
27-
Also install an up-to-date Python 3.x. For example on Windows, [install Python from the Microsoft Store](https://www.microsoft.com/store/productId/9NCVDN91XZQP), and make sure it's available on your `PATH` (for example: check `python --version` prints a version). This is only required temporarily (a bug in Clang for WASI SDK means we require Emscripten, which in turn requires Python).
25+
If you don't already have it, install [.NET 8+ SDK](https://dotnet.microsoft.com/en-us/download/dotnet/8.0)
2826

2927
### 2. Create a project and add WasmComponent.Sdk package
3028

@@ -47,8 +45,6 @@ Edit the `.csproj` file, adding the following inside the `<PropertyGroup>`:
4745

4846
Now you can `dotnet build` to produce a `.wasm` file using NativeAOT compilation.
4947

50-
**Troubleshooting:** If you get the error *'python' is not recognized as an internal or external command*, go back and install Python as mentioned above. Also delete the `.emsdk` directory inside your user profile directory, then try again.
51-
5248
### 4. Run the WebAssembly binary
5349

5450
If you have a recent version of [wasmtime](https://github.com/bytecodealliance/wasmtime/releases) on your path, you can now run
@@ -57,17 +53,17 @@ If you have a recent version of [wasmtime](https://github.com/bytecodealliance/w
5753

5854
(if needed, replace `MyApp.wasm` with the actual name of your project)
5955

60-
## Creating a WASI Preview 2 component, including WIT support
56+
## Creating a WASI 0.2 component, including WIT support
6157

6258
This is much more advanced and is likely to break frequently, since the underlying tool ecosystem is continually changing.
6359

64-
The compilation above will also have generated `MyApp.component.wasm`, which is a WASI preview 2 component. You can also run that if you want, using `wasmtime --wasm component-model bin\Debug\net8.0\wasi-wasm\native\MyApp.component.wasm`.
60+
The compilation above will also have generated `MyApp.component.wasm`, which is a WASI 0.2 component. You can also run that if you want, using `wasmtime --wasm component-model bin\Debug\net8.0\wasi-wasm\native\MyApp.component.wasm`.
6561

66-
**Troubleshooting:** If you get an error like *import 'wasi:...' has the wrong type*, you need a different version of Wasmtime. Currently this package targets [Wasmtime](https://github.com/bytecodealliance/wasmtime/releases/tag/v14.0.4). WASI preview 2 is now stable and so you shouldn't run into this as often.
62+
**Troubleshooting:** If you get an error like *import 'wasi:...' has the wrong type*, you need a different version of Wasmtime. Currently this package targets [Wasmtime](https://github.com/bytecodealliance/wasmtime/releases/tag/v14.0.4). WASI 0.2 is now stable and so you shouldn't run into this as often.
6763

6864
### Referencing a WIT file
6965

70-
The whole point of the WASI preview 2 component model is to be able to interoperate across components. This is achieved using [WebAssembly Interface Type (WIT)](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md) files that specify data structures and functions to be imported or exported across components.
66+
The whole point of the WASI 0.2 component model is to be able to interoperate across components. This is achieved using [WebAssembly Interface Type (WIT)](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md) files that specify data structures and functions to be imported or exported across components.
7167

7268
This package wraps `wit-bindgen` so that any `.wit` files in your project will automatically generate corresponding C# sources, allowing you to import or export functionality. **Caution:** wit-bindgen's support for C# is *extremely early* and many definitions do not yet work.
7369

@@ -122,7 +118,7 @@ var result = OperationsInterop.Add(123, 456);
122118
Console.WriteLine($"The result is {result}");
123119
```
124120

125-
Since your component is no longer a self-contained application, you can no longer run it without also composing it with another WASI preview 2 component that implements the `add` function. To do that, either:
121+
Since your component is no longer a self-contained application, you can no longer run it without also composing it with another WASI 0.2 component that implements the `add` function. To do that, either:
126122

127123
* Create another .NET project and this time follow the steps for "exporting an implementation" below
128124
* Or, read docs for other platforms such as Rust or TinyGo, to implement a WASI component containing the implementation.
@@ -161,7 +157,7 @@ public class OperationsImpl : Operations
161157

162158
Make sure to get the namespace exactly correct! Although this is quite difficult to figure out at the moment, hopefully a future version of the C# support in wit-bindgen will make it easier.
163159

164-
Now when you build, you'll get a real WASI preview 2 component that exports an implementation for this WIT definition. You can confirm it using [wasm-tools](https://github.com/bytecodealliance/wasm-tools) by running:
160+
Now when you build, you'll get a real WASI 0,2 component that exports an implementation for this WIT definition. You can confirm it using [wasm-tools](https://github.com/bytecodealliance/wasm-tools) by running:
165161

166162
```
167163
wasm-tools component wit bin\Debug\net8.0\wasi-wasm\native\MyApp.component.wasm
@@ -179,7 +175,7 @@ world root {
179175
}
180176
```
181177

182-
This component can be used anywhere that WASI preview 2 components can be used. For example, use `wasm-tools compose` as illustrated above.
178+
This component can be used anywhere that WASI 0.2 components can be used. For example, use `wasm-tools compose` as illustrated above.
183179

184180
### WIT strings and memory
185181

@@ -201,8 +197,8 @@ This is a wrapper around various other bits of tooling:
201197

202198
* [NativeAOT-LLVM](https://github.com/dotnet/runtimelab/tree/feature/NativeAOT-LLVM) for compilation.
203199
* [wit-bindgen](https://github.com/bytecodealliance/wit-bindgen) for supporting WIT imports and exports
204-
* [wasm-tools](https://github.com/bytecodealliance/wasm-tools) for converting WebAssembly core modules into WASI preview 2 components.
205-
* [WASI SDK](https://github.com/WebAssembly/wasi-sdk) and [Emscripten](https://emscripten.org/), both of which are used by NativeAOT-LLVM.
200+
* [wasm-tools](https://github.com/bytecodealliance/wasm-tools) for converting WebAssembly core modules into WASI 0.2 components.
201+
* [WASI SDK](https://github.com/WebAssembly/wasi-sdk) which is used by NativeAOT-LLVM.
206202
* Compatible versions of these will be downloaded and cached on your machine the first time you run a build, so the first build will take a few minutes. After that it will only take seconds.
207203

208204
## Contributing

src/WitBindgen/build/WitBindgen.targets

Lines changed: 3 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -4,65 +4,26 @@
44

55
<!-- Keep this block all in sync manually, since URLs can be arbitrary -->
66
<WasiSdkVersion>22.0</WasiSdkVersion>
7-
<WasiSdkUrl Condition="$([MSBuild]::IsOSPlatform('Windows'))">https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-$(WasiSdkVersion.Split(".")[0])/wasi-sdk-$(WasiSdkVersion).m-mingw.tar.gz</WasiSdkUrl>
7+
<WasiSdkUrl Condition="$([MSBuild]::IsOSPlatform('Windows'))">https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-$(WasiSdkVersion.Split(".")[0])/wasi-sdk-$(WasiSdkVersion).m-mingw64.tar.gz</WasiSdkUrl>
88
<WasiSdkUrl Condition="$([MSBuild]::IsOSPlatform('Linux'))">https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-$(WasiSdkVersion.Split(".")[0])/wasi-sdk-$(WasiSdkVersion)-linux.tar.gz</WasiSdkUrl>
99
<WasiSdkUrl Condition="$([MSBuild]::IsOSPlatform('OSX'))">https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-$(WasiSdkVersion.Split(".")[0])/wasi-sdk-$(WasiSdkVersion)-macos.tar.gz</WasiSdkUrl>
1010
<WasiSdkRoot>$([System.IO.Path]::Combine("$([System.Environment]::GetFolderPath(SpecialFolder.UserProfile))", ".wasi-sdk", "wasi-sdk-$(WasiSdkVersion)"))</WasiSdkRoot>
1111

12-
<EmSdkVersion>3.1.61</EmSdkVersion>
13-
<EmSdkUrl>https://github.com/emscripten-core/emsdk/archive/refs/tags/$(EmSdkVersion).zip</EmSdkUrl>
14-
<!-- Support bring your own emscripten if $(EMSDK) is already set-->
15-
<EmscriptenRoot Condition="'$(EMSDK)' == ''">$([System.IO.Path]::Combine("$([System.Environment]::GetFolderPath(SpecialFolder.UserProfile))", ".emsdk", "emsdk-$(EmSdkVersion)"))</EmscriptenRoot>
16-
<EmscriptenRoot Condition="'$(EMSDK)' != ''">$(EMSDK)</EmscriptenRoot>
1712
</PropertyGroup>
1813

1914
<!--
20-
MSBuild stuff to acquire the necessary SDKs (WASI SDK and Emscripten) automatically. It will take a few mins on the
15+
MSBuild stuff to acquire the necessary SDKs (WASI SDK) automatically. It will take a few mins on the
2116
first build on a given machine, but after that should no-op.
2217
-->
23-
<Target Name="PrepareWasmSdks" BeforeTargets="CheckWasmSdks" DependsOnTargets="ObtainWasiSdk; ObtainEmscripten">
18+
<Target Name="PrepareWasmSdks" BeforeTargets="CheckWasmSdks" DependsOnTargets="ObtainWasiSdk">
2419
<PropertyGroup>
2520
<ClangExeName>clang</ClangExeName>
2621
<ClangExeName Condition="$([MSBuild]::IsOSPlatform('Windows'))">$(ClangExeName).exe</ClangExeName>
27-
<EmSdk>$(EmscriptenRoot)</EmSdk>
2822
<Wasicompiler>$(WasiSdkRoot)\bin\$(ClangExeName)</Wasicompiler>
2923
<WASI_SDK_PATH>$(WasiSdkRoot)</WASI_SDK_PATH>
3024
</PropertyGroup>
3125
</Target>
3226

33-
<Target Name="ObtainEmscripten" Condition="'$(EMSDK)' == '' AND !(Exists($(EmscriptenRoot)))">
34-
<!--
35-
This is not ideal because if your solution has multiple projects that use WasmComponent.Sdk, then if you
36-
build in parallel in CI where your machine doesn't already have wasi-sdk/emsdk, then it may try to download
37-
and extract the SDKs multiple times in parallel to the same disk location, which may cause it to fail.
38-
The only reason this doesn't happen in this repo is that it explicitly runs the PrepareWasmSdks task before
39-
building other projects.
40-
41-
For a proper fix, consider implementing an MSBuild task in C# that obtains wasi-sdk/emsdk, and uses a mutex
42-
so that only one flow executes at a time, with others blocking until it's done.
43-
-->
44-
45-
<PropertyGroup>
46-
<EmSdkDownloadTempDir>$([System.IO.Path]::Combine($([System.IO.Path]::GetTempPath()), $([System.IO.Path]::GetRandomFileName())))</EmSdkDownloadTempDir>
47-
</PropertyGroup>
48-
49-
<MakeDir Directories="$(EmSdkDownloadTempDir)" />
50-
<DownloadFile
51-
SourceUrl="$(EmSdkUrl)"
52-
DestinationFolder="$(EmSdkDownloadTempDir)">
53-
<Output TaskParameter="DownloadedFile" ItemName="EmSdkDownloadTempFile" />
54-
</DownloadFile>
55-
56-
<!-- Windows 10+ has tar built in, so this should work cross-platform -->
57-
<Message Importance="high" Text="Extracting @(EmSdkDownloadTempFile) to $(EmscriptenRoot)..." />
58-
<MakeDir Directories="$(EmscriptenRoot)" />
59-
<Exec Command="tar -xf &quot;@(EmSdkDownloadTempFile)&quot; -C . --strip-components=1" WorkingDirectory="$(EmscriptenRoot)" />
60-
<RemoveDir Directories="$(EmSdkDownloadTempDir)" />
61-
62-
<Exec Command="emsdk install $(EmSdkVersion)" WorkingDirectory="$(EmscriptenRoot)" />
63-
<Exec Command="emsdk activate $(EmSdkVersion)" WorkingDirectory="$(EmscriptenRoot)" />
64-
</Target>
65-
6627
<Target Name="ObtainWasiSdk" Condition="!(Exists($(WasiSdkRoot)))">
6728
<PropertyGroup>
6829
<WasiSdkDownloadTempDir>$([System.IO.Path]::Combine($([System.IO.Path]::GetTempPath()), $([System.IO.Path]::GetRandomFileName())))</WasiSdkDownloadTempDir>

0 commit comments

Comments
 (0)