dotnet-sdk: add withWorkloads support#498033
dotnet-sdk: add withWorkloads support#498033JamieMagee wants to merge 4 commits intoNixOS:masterfrom
Conversation
|
8fa9333 to
02689b0
Compare
|
That's great @JamieMagee! I'll try to give it a spin next week. |
|
A review from GPT-5.4 I tested this on Linux with
|
|
Might also makes sense wrapping |
02689b0 to
f86edcf
Compare
|
@lostmsu Thanks for testing this, really appreciate it. I pushed fixes:
Re: wrapping |
|
with |
lostmsu
left a comment
There was a problem hiding this comment.
Tested locally - works except templates. As mentioned in a comment that could be fixed separately.
Add generate-workload-data.py, which builds the binary SDK for a given .NET version, reads its bundled workload manifests, resolves packs per RID, fetches NuGet hashes, and writes a Nix expression. Add update-workloads.sh as a convenience wrapper that regenerates data for all versions (derived from existing workloads/*.nix files, so no hardcoded version list to maintain).
Output of generate-workload-data.py for each supported SDK version. Each file contains SRI hashes for every NuGet pack and per-RID workload-to-pack mappings (linux-x64, linux-arm64, osx-x64, osx-arm64).
f86edcf to
c68376e
Compare
|
The generated workload nix stuff feels like it should be part of the existing generated expressions (versions/*.nix). Is there a reason we'd ever want to update them separately? |
The two generators have different inputs, dependencies, and update cadences. Merging them is possible but would mean the fast path ( |
with-workloads.nix composes a .NET SDK with workload packs pre-installed. Packs are fetched from NuGet into a separate derivation and made available to the SDK via the DOTNETSDK_WORKLOAD_PACK_ROOTS environment variable (set by dotnet-workload-hook.sh). This avoids merging packs into the SDK tree entirely. A small buildEnv overlay adds workload metadata (InstalledWorkloads sentinels) so `dotnet workload list` reports them, and removes the userlocal sentinel that would redirect pack lookups to ~/.dotnet. Native ELF binaries in workload packs are patched via autoPatchelfHook. Usage: dotnet-sdk.withWorkloads ["wasm-tools" "aspire"]
Add withWorkloads to dotnetCorePackages (takes an SDK and workload ID list) and to each wrapped SDK's passthru (takes just the workload ID list, capturing the SDK via finalAttrs). When the unwrapped SDK has a workloadPackRoot in its passthru, the wrapper sources dotnet-workload-hook.sh to set WORKLOAD_PACK_ROOTS. Add a wasm test that builds a browser-wasm project when the wasm-tools workload is installed, verifying the full workload pipeline. Chain update.sh and update-workloads.sh via the sequence combinator so workload data is regenerated alongside SDK version updates.
c68376e to
e59d80c
Compare
|
How to use this with dotnet-combined = (with pkgs.dotnetCorePackages;
combinePackages [
sdk_10_0-bin
sdk_9_0-bin
sdk_8_0-bin
]).withWorkloads [
"maui"
"maui-android"
"maui-ios"
"maui-maccatalyst"
"wasm-tools"
"aspire"
];results in : error: No workload data for .NET combined. Supported: 8.0, 9.0, 10.0, 11.0.EDIT: this seems to work dotnet-combined = (with pkgs.dotnetCorePackages;
combinePackages [
(sdk_10_0-bin.withWorkloads [
"maui"
"maui-mobile"
"maui-android"
"maui-ios"
"maui-maccatalyst"
"android"
"ios"
"maccatalyst"
"macos"
])
sdk_9_0-bin
sdk_8_0-bin
]); |
|
Yes, workloads are specific to the major SDK version, not shared across major versions. |
|
@JamieMagee should it be working with the For Edit: running this on > dotnet build -c Debug -f net9.0-ios
Determining projects to restore...
/nix/store/fb978fbhg5k3hwnyxl7g341qriq1v288-dotnet-sdk-9.0.312/share/dotnet/sdk/9.0.312/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.Sdk.ImportWorkloads.targets(38,5): error NETSDK1147: To build this project, the following workloads must be installed: maui-android [/Users/a/app_repo/Mobile.App.csproj::TargetFramework=net9.0-android]
/nix/store/fb978fbhg5k3hwnyxl7g341qriq1v288-dotnet-sdk-9.0.312/share/dotnet/sdk/9.0.312/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.Sdk.ImportWorkloads.targets(38,5): error NETSDK1147: To install these workloads, run the following command: dotnet workload restore [/Users/a/app_repo/Mobile.App.csproj::TargetFramework=net9.0-android]
> dotnet workload list
Installed Workload Id Manifest Version Installation Source
---------------------------------------------------------------------
android 35.0.105/9.0.100 SDK 9.0.300
ios 26.2.9000/9.0.100 SDK 9.0.300
maccatalyst 26.2.9000/9.0.100 SDK 9.0.300
macos 26.2.9000/9.0.100 SDK 9.0.300
maui 9.0.120/9.0.100 SDK 9.0.300
maui-android 9.0.120/9.0.100 SDK 9.0.300
maui-ios 9.0.120/9.0.100 SDK 9.0.300
maui-maccatalyst 9.0.120/9.0.100 SDK 9.0.300
maui-mobile 9.0.120/9.0.100 SDK 9.0.300
Use `dotnet workload search` to find additional workloads to install.
> dotnet --info
.NET SDK:
Version: 9.0.312
Commit: c45411d3fd
Workload version: 9.0.300-manifests.93c62a5d
MSBuild version: 17.14.43+2a0eb78b3
Runtime Environment:
OS Name: Mac OS X
OS Version: 26.2
OS Platform: Darwin
RID: osx-arm64
Base Path: /nix/store/fb978fbhg5k3hwnyxl7g341qriq1v288-dotnet-sdk-9.0.312/share/dotnet/sdk/9.0.312/
.NET workloads installed:
[macos]
Installation Source: SDK 9.0.300
Manifest Version: 26.2.9000/9.0.100
Manifest Path: /nix/store/z16n8s7fpfc9j5m0c2kydskrh6jiybck-dotnet-sdk-with-workloads-9.0.312/share/dotnet/sdk-manifests/9.0.100/microsoft.net.sdk.macos/26.2.9000/WorkloadManifest.json
Install Type: FileBased
[maui-maccatalyst]
Installation Source: SDK 9.0.300
Manifest Version: 9.0.120/9.0.100
Manifest Path: /nix/store/z16n8s7fpfc9j5m0c2kydskrh6jiybck-dotnet-sdk-with-workloads-9.0.312/share/dotnet/sdk-manifests/9.0.100/microsoft.net.sdk.maui/9.0.120/WorkloadManifest.json
Install Type: FileBased
[maui-ios]
Installation Source: SDK 9.0.300
Manifest Version: 9.0.120/9.0.100
Manifest Path: /nix/store/z16n8s7fpfc9j5m0c2kydskrh6jiybck-dotnet-sdk-with-workloads-9.0.312/share/dotnet/sdk-manifests/9.0.100/microsoft.net.sdk.maui/9.0.120/WorkloadManifest.json
Install Type: FileBased
[maui-android]
Installation Source: SDK 9.0.300
Manifest Version: 9.0.120/9.0.100
Manifest Path: /nix/store/z16n8s7fpfc9j5m0c2kydskrh6jiybck-dotnet-sdk-with-workloads-9.0.312/share/dotnet/sdk-manifests/9.0.100/microsoft.net.sdk.maui/9.0.120/WorkloadManifest.json
Install Type: FileBased
[ios]
Installation Source: SDK 9.0.300
Manifest Version: 26.2.9000/9.0.100
Manifest Path: /nix/store/z16n8s7fpfc9j5m0c2kydskrh6jiybck-dotnet-sdk-with-workloads-9.0.312/share/dotnet/sdk-manifests/9.0.100/microsoft.net.sdk.ios/26.2.9000/WorkloadManifest.json
Install Type: FileBased
[maui-mobile]
Installation Source: SDK 9.0.300
Manifest Version: 9.0.120/9.0.100
Manifest Path: /nix/store/z16n8s7fpfc9j5m0c2kydskrh6jiybck-dotnet-sdk-with-workloads-9.0.312/share/dotnet/sdk-manifests/9.0.100/microsoft.net.sdk.maui/9.0.120/WorkloadManifest.json
Install Type: FileBased
[maccatalyst]
Installation Source: SDK 9.0.300
Manifest Version: 26.2.9000/9.0.100
Manifest Path: /nix/store/z16n8s7fpfc9j5m0c2kydskrh6jiybck-dotnet-sdk-with-workloads-9.0.312/share/dotnet/sdk-manifests/9.0.100/microsoft.net.sdk.maccatalyst/26.2.9000/WorkloadManifest.json
Install Type: FileBased
[maui]
Installation Source: SDK 9.0.300
Manifest Version: 9.0.120/9.0.100
Manifest Path: /nix/store/z16n8s7fpfc9j5m0c2kydskrh6jiybck-dotnet-sdk-with-workloads-9.0.312/share/dotnet/sdk-manifests/9.0.100/microsoft.net.sdk.maui/9.0.120/WorkloadManifest.json
Install Type: FileBased
[android]
Installation Source: SDK 9.0.300
Manifest Version: 35.0.105/9.0.100
Manifest Path: /nix/store/z16n8s7fpfc9j5m0c2kydskrh6jiybck-dotnet-sdk-with-workloads-9.0.312/share/dotnet/sdk-manifests/9.0.100/microsoft.net.sdk.android/35.0.105/WorkloadManifest.json
Install Type: FileBased
Configured to use loose manifests when installing new manifests.
Host:
Version: 9.0.14
Architecture: arm64
Commit: 19c07820cb
.NET SDKs installed:
9.0.312 [/nix/store/z16n8s7fpfc9j5m0c2kydskrh6jiybck-dotnet-sdk-with-workloads-9.0.312/share/dotnet/sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 9.0.14 [/nix/store/z16n8s7fpfc9j5m0c2kydskrh6jiybck-dotnet-sdk-with-workloads-9.0.312/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 9.0.14 [/nix/store/z16n8s7fpfc9j5m0c2kydskrh6jiybck-dotnet-sdk-with-workloads-9.0.312/share/dotnet/shared/Microsoft.NETCore.App]
Other architectures found:
None
Environment variables:
DOTNET_ROOT [/nix/store/f27i8zs2c1z5nd6brhd2fw8mixlzs1qy-dotnet-sdk-wrapped-9.0.312]
global.json file:
/Users/a/app_repo/global.json
Learn more:
https://aka.ms/dotnet/info
Download .NET:
EDIT_2: same with the source built sdk |
As seen above: /nix/store/fb978fbhg5k3hwnyxl7g341qriq1v288-dotnet-sdk-9.0.312/share/dotnet/sdk/9.0.312/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.Sdk.ImportWorkloads.targets(38,5): error NETSDK1147: To build this project, the following workloads must be installed: maui-android [/Users/a/app_repo/Mobile.App.csproj::TargetFramework=net9.0-android]
/nix/store/fb978fbhg5k3hwnyxl7g341qriq1v288-dotnet-sdk-9.0.312/share/dotnet/sdk/9.0.312/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.Sdk.ImportWorkloads.targets(38,5): error NETSDK1147: To install these workloads, run the following command: dotnet workload restore [/Users/a/app_repo/Mobile.App.csproj::TargetFramework=net9.0-android]Same error appears for both |
Add
withWorkloadsto the .NET SDK, so you can do:Workload packs are fetched from NuGet into a separate derivation. The SDK finds them via
DOTNETSDK_WORKLOAD_PACK_ROOTS, set by a setup hook. Nothing gets merged into the SDK tree except metadata sentinels fordotnet workload list. Native ELF binaries in packs are patched withautoPatchelfHook.Pack data (hashes, per-RID mappings) comes from the SDK's own bundled manifests, generated by a Python script and checked in as Nix files. Regenerate with:
The update script is also chained into
passthru.updateScriptviasequence, so it runs alongside SDK version updates.Includes a wasm build test that verifies
dotnet buildworks with thewasm-toolsworkload installed.Supports .NET 8.0, 9.0, 10.0, and 11.0 across linux-x64, linux-arm64, osx-x64, and osx-arm64.
See #226107
Things done
passthru.tests.nixpkgs-reviewon this PR. See nixpkgs-review usage../result/bin/.