Note: The Listed platform will permanently shut down December 31, 2026. Your data published on Listed will still be available in your personal Standard Notes account. Learn more

Compile dotnet to wasm

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

ズコー。最初と一緒やん。


You'll only receive email when they publish something new.

More from iwate
All posts