diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6ae69a01cd3..6968d8873d2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -869,11 +869,35 @@ jobs: exit 1 } + # NativeAOT-LLVM smoketest runs on Windows because runtime.linux-x64.Microsoft.DotNet.ILCompiler.LLVM + # does not have 8.0.0 versions available on the dotnet-experimental NuGet feed. + csharp-aot-smoketest: + needs: [lints] + runs-on: windows-latest + timeout-minutes: 15 + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup dotnet + uses: actions/setup-dotnet@v3 + with: + global-json-file: global.json + + - name: Setup Emscripten + uses: mymindstorm/setup-emsdk@v14 + with: + version: 4.0.23 + - name: Smoketest C# AOT build (NativeAOT-LLVM) + shell: pwsh run: | - cd modules/sdk-test-cs - EXPERIMENTAL_WASM_AOT=1 dotnet publish -c Release - test -f bin/Release/net8.0/wasi-wasm/publish/StdbModule.wasm + $env:EXPERIMENTAL_WASM_AOT = "1" + dotnet publish -c Release modules/sdk-test-cs + if (-not (Test-Path "modules/sdk-test-cs/bin/Release/net8.0/wasi-wasm/publish/StdbModule.wasm")) { + Write-Error "StdbModule.wasm not found" + exit 1 + } internal-tests: name: Internal Tests diff --git a/crates/bindings-csharp/NATIVEAOT-LLVM.md b/crates/bindings-csharp/NATIVEAOT-LLVM.md new file mode 100644 index 00000000000..9fe5bb15c24 --- /dev/null +++ b/crates/bindings-csharp/NATIVEAOT-LLVM.md @@ -0,0 +1,118 @@ +# Converting a SpacetimeDB 2.0.x project to use NativeAOT-LLVM + +This guide provides instructions on taking an existing C# module that targets the public-released SpacetimeDB CLI, and guides you through the necessary steps to enable `NativeAOT-LLVM` use. + +## Overview +In order to use `NativeAOT-LLVM` on a C# module, we'll need to set the `EXPERIMENTAL_WASM_AOT` environment variable to `1` which SpacetimeDB will check during publishing of a module. +For the module to work, we'll also need the `NuGet.Config` and `.csproj` files with the required package sources and references. + +### Prerequisites: +- **.NET SDK 8.x** (same version used by SpacetimeDB) +- **Emscripten SDK (EMSDK)** installed (must contain `upstream/emscripten/emcc.bat`) +- **(Optional) Binaryen (wasm-opt)** installed and on `PATH` (recommended: `version_116`) + +## Steps + +1. **Install EMSDK** + - Download and extract the `https://github.com/emscripten-core/emsdk` release. + - Example path: `D:\Tools\emsdk` + +2. **Set environment variables** + + ```powershell + $env:EXPERIMENTAL_WASM_AOT=1 + $env:EMSDK="D:\Tools\emsdk" + ``` + +3. **Ensure NuGet feed is configured** + NativeAOT-LLVM packages currently come from **dotnet-experimental**: + - Add the `dotnet-experimental` feed to a project-local `NuGet.Config` + ```xml + + ``` + This should be a `NuGet.Config` placed in the root directory of your module folder (next to the `.csproj`). You can simply add the above line to the `packageSources` of your existing file, or if you need to create a minimal one, you can use: + + ```xml + + + + + + + + + ``` + +4. **Ensure NativeAOT emits a `.wasm` output** + - For LLVM AOT builds, the CLI currently accepts `dotnet.wasm` under `bin/Release/net8.0/wasi-wasm/publish/`. + - In the module `.csproj`, ensure the AOT package references include: + + ```xml + + + + + + ``` + + The contents of your `.csproj` should look something like this: + + ```xml + + + net8.0 + wasi-wasm + enable + enable + + + + + + + + + + + ``` + + - **NU1504 warning**: Because the runtime targets also add these LLVM packages, you may see a duplicate PackageReference warning. It is non-blocking. + +5. **(Optional) Install wasm-opt (Binaryen)** + This step is optional, but provides performance improvements, and therefore is recommended. + - Download Binaryen `https://github.com/WebAssembly/binaryen/releases/tag/version_116` for Windows and extract it, e.g. `D:\Tools\binaryen`. + - Add `D:\Tools\binaryen\bin` to `PATH`. + - Verify: + + ```powershell + wasm-opt --version + ``` + +6. **Publish module** + - Use the SpacetimeDB CLI to publish from the module directory. + - With `EXPERIMENTAL_WASM_AOT=1`, publish should attempt LLVM AOT. + - Ensure the local server is running if publishing to `local`. + +## Troubleshooting + +### Package source mapping enabled +If you have **package source mapping** enabled in `NuGet.Config`, you must add mappings for the LLVM packages or restores will fail. + +```xml + + + + + + + + + +``` + +### wasi-experimental workload install fails +If the CLI cannot install the `wasi-experimental` workload automatically, install it manually: + +```powershell +dotnet workload install wasi-experimental +``` diff --git a/crates/bindings-csharp/Runtime/Runtime.csproj b/crates/bindings-csharp/Runtime/Runtime.csproj index 1e5e0f8531a..12db5ab4150 100644 --- a/crates/bindings-csharp/Runtime/Runtime.csproj +++ b/crates/bindings-csharp/Runtime/Runtime.csproj @@ -12,6 +12,7 @@ true SpacetimeDB true + https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-experimental/nuget/v3/index.json;$(RestoreAdditionalProjectSources) @@ -25,6 +26,13 @@ + + + + + + + diff --git a/crates/bindings-csharp/Runtime/build/SpacetimeDB.Runtime.targets b/crates/bindings-csharp/Runtime/build/SpacetimeDB.Runtime.targets index aa412113b31..5f183e0e040 100644 --- a/crates/bindings-csharp/Runtime/build/SpacetimeDB.Runtime.targets +++ b/crates/bindings-csharp/Runtime/build/SpacetimeDB.Runtime.targets @@ -1,5 +1,9 @@ + + @@ -42,10 +46,6 @@ - - - - diff --git a/modules/sdk-test-cs/sdk-test-cs.csproj b/modules/sdk-test-cs/sdk-test-cs.csproj index d4caede5ffa..09cf1192bb7 100644 --- a/modules/sdk-test-cs/sdk-test-cs.csproj +++ b/modules/sdk-test-cs/sdk-test-cs.csproj @@ -9,5 +9,9 @@ - + + + + + diff --git a/sdks/csharp/tools~/write-nuget-config.sh b/sdks/csharp/tools~/write-nuget-config.sh index 9997cd219ff..69286284ad8 100755 --- a/sdks/csharp/tools~/write-nuget-config.sh +++ b/sdks/csharp/tools~/write-nuget-config.sh @@ -15,6 +15,8 @@ cat >NuGet.Config < + + @@ -30,6 +32,11 @@ cat >NuGet.Config < + + + + + @@ -43,6 +50,8 @@ cat >"${SPACETIMEDB_REPO_PATH}/NuGet.Config" < + + @@ -58,6 +67,11 @@ cat >"${SPACETIMEDB_REPO_PATH}/NuGet.Config" < + + + + +