Compile dotnet to wasm
February 2, 2022•475 words
.NETをwasmにAOTしてみる。おそらくランタイムごとwasmになるんかな
ひとまずこの人の説明通りやってみる。
https://stackoverflow.com/questions/70474778/compiling-c-sharp-project-to-webassembly
まず、emscriptenをいれる。Python3.6が必要ぽいけど入っていたのでそこはスキップ
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latest
環境変数がセットされたので一応サインアウトからのサインイン。
適当なフォルダでdotnet projectをつくって、nugetconfigでnugetリポジトリを追加する。3rdPartyせいなのね。blazorのとかこれじゃなかったのか。
mkdir sample
cd sample
dotnet new classlib
dotnet new nugetconfig
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<config>
<add key="globalPackagesFolder" value=".packages" />
</config>
<packageSources>
<!--To inherit the global NuGet package sources remove the <clear/> line below -->
<clear />
<add key="dotnet-experimental" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-experimental/nuget/v3/index.json" />
<add key="nuget" value="https://api.nuget.org/v3/index.json" />
</packageSources>
</configuration>
Class1にメソッドを追加
[System.Runtime.InteropServices.UnmanagedCallersOnly(EntryPoint = "Answer")]
public static int Answer()
{
return 41;
}
csprojに以下を追加
<ItemGroup>
<PackageReference Include="Microsoft.DotNet.ILCompiler.LLVM" Version="7.0.0-*" />
<PackageReference Include="runtime.win-x64.Microsoft.DotNet.ILCompiler.LLVM" Version="7.0.0-*" />
</ItemGroup>
次のコマンドでコンパイル
dotnet publish /p:NativeLib=Static /p:SelfContained=true -r browser-wasm -c Debug /p:TargetArchitecture=wasm /p:PlatformTarget=AnyCPU /p:MSBuildEnableWorkloadResolver=false /p:EmccExtraArgs="-s EXPORTED_FUNCTIONS=_Answer%2C_CoreRT_StaticInitialization -s EXPORTED_RUNTIME_METHODS=cwrap" --self-contained
するんだけどうまくいかない。こんなエラーが出る。
Microsoft (R) Build Engine version 17.1.0-preview-21610-01+96a618ca5 for .NET
Copyright (C) Microsoft Corporation. All rights reserved.
Determining projects to restore...
All projects are up-to-date for restore.
You are using a preview version of .NET. See: https://aka.ms/dotnet-core-preview
sample -> C:\Users\iwate\works\iwate\sample\bin\Debug\net6.0\browser-wasm\sample.dll
C:\Program Files\dotnet\sdk\6.0.200-preview.21617.4\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Publish.targets(248,5): error MSB3030: Could not copy the file "bin\Debug\net6.0\browser-wasm\native\sample.html" because it was not found. [\path\to\sample\sample.csproj]
StackOverflowじゃなくて、リポジトリのドキュメントを参考にしてみる。
https://github.com/dotnet/runtimelab/blob/feature/NativeAOT-LLVM/docs/using-nativeaot/compiling.md#webassembly
今度は、consoleアプリでそのままアプリケーションにする
dotnet new console
dotnet new nugetconfig
nuget.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<!--To inherit the global NuGet package sources remove the <clear/> line below -->
<clear />
<add key="dotnet-experimental" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-experimental/nuget/v3/index.json" />
<add key="nuget" value="https://api.nuget.org/v3/index.json" />
</packageSources>
</configuration>
csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.DotNet.ILCompiler" Version="7.0.0-*" />
<PackageReference Include="Microsoft.DotNet.ILCompiler.LLVM; runtime.win-x64.Microsoft.DotNet.ILCompiler.LLVM" Version="7.0.0-*" />
</ItemGroup>
</Project>
ビルド
dotnet publish -r browser-wasm -c Debug /p:TargetArchitecture=wasm /p:PlatformTarget=AnyCPU
workdloadが足りないって言われる
C:\Program Files\dotnet\sdk\6.0.200-preview.21617.4\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.ImportWorkloads.targets(38,5): error NETSDK1147: To build this project, the following workloads must be installed: wasm-tools
C:\Program Files\dotnet\sdk\6.0.200-preview.21617.4\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.ImportWorkloads.targets(38,5): error NETSDK1147: To install these workloads, run the following command: dotnet workload install wasm-tools
ので足す。
dotnet workload install wasm-tools
再度ビルドするがエラー
$ dotnet publish -r browser-wasm -c Debug /p:TargetArchitecture=wasm /p:PlatformTarget=AnyCPU
Microsoft (R) Build Engine version 17.1.0-preview-21610-01+96a618ca5 for .NET
Copyright (C) Microsoft Corporation. All rights reserved.
Determining projects to restore...
Restored C:\Users\iwate\works\iwate\wasm\wasm.csproj (in 1.6 min).
You are using a preview version of .NET. See: https://aka.ms/dotnet-core-preview
C:\Program Files\dotnet\sdk\6.0.200-preview.21617.4\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.targets(1110,5): warning NETSDK1179: One of '--self-contained' or '--no-self-contained' options are required when '--runtime' is used. [C:\Users\iwate\works\iwate\wasm\wasm.csproj]
wasm -> C:\Users\iwate\works\iwate\wasm\bin\Debug\net6.0\browser-wasm\wasm.dll
C:\Program Files\dotnet\packs\Microsoft.NET.Runtime.WebAssembly.Sdk\6.0.2-mauipre.1.22054.8\Sdk\WasmApp.targets(270,5): error : $(WasmMainJSPath) property needs to be set
プロジェクト構成見てみる
https://github.com/dotnet/runtimelab/tree/feature/NativeAOT-LLVM/samples/HelloWorld
dotnet6じゃなくて5だったので、5に変更。Program.csも5になるように、namespaceやらエントリーポイントで囲う。
PackageReferenceも一つでいいぽい
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.DotNet.ILCompiler.LLVM; runtime.win-x64.Microsoft.DotNet.ILCompiler.LLVM" Version="7.0.0-*" />
</ItemGroup>
</Project>
再度ビルド
$ dotnet publish -r browser-wasm -c Debug /p:TargetArchitecture=wasm /p:PlatformTarget=AnyCPU
Microsoft (R) Build Engine version 17.1.0-preview-21610-01+96a618ca5 for .NET
Copyright (C) Microsoft Corporation. All rights reserved.
Determining projects to restore...
Restored C:\Users\iwate\works\iwate\wasm\wasm.csproj (in 2.05 sec).
You are using a preview version of .NET. See: https://aka.ms/dotnet-core-preview
wasm -> C:\Users\iwate\works\iwate\wasm\bin\Debug\net5.0\browser-wasm\wasm.dll
Generating compatible native code. To optimize for size or speed, visit https://aka.ms/OptimizeCoreRT
RyuJIT compilation results, total methods 16830 RyuJit Methods 5699 33.8622%
C:\Program Files\dotnet\sdk\6.0.200-preview.21617.4\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Publish.targets(248,5): error MSB3030: Could not copy the file "bin\Debug\net5.0\browser-wasm\native\wasm.html" because it was not found.
ズコー。最初と一緒やん。