gtk workload (private SDK recipe)Proves net10.0-gtk4.22 end to end without touching the
machine-wide SDK.
| Step | Command |
|---|---|
| 1. Private SDK | dotnet-install.ps1 -Channel 10.0 -InstallDir $env:USERPROFILE\.dotnet-gtk |
| 2. Build + pack (default SDK) | dotnet cake build.cake --BuildTarget=Default |
| 3. Install into the private SDK | $env:DOTNET_ROOT="$env:USERPROFILE\.dotnet-gtk"; dotnet cake build.cake --BuildTarget=InstallPackedWorkload |
| 4. Check | $env:DOTNET_ROOT=...; $env:PATH="$env:USERPROFILE\.dotnet-gtk;$env:PATH"; dotnet workload list shows gtk |
| 5. Smoke test | pwsh Source/Workload/Test-WorkloadSmoke.ps1 (dotnet new gtk, build net10.0-gtk4.22, run, expects SMOKE done) |
Why two cake runs: DOTNET_ROOT also steers apphosts such as NuGetUtility.exe, which need a .NET 8 runtime a
fresh SDK does not carry, so the build runs under the default SDK and only the install sees the private one.
InstallWorkload (build + pack + install in one) still exists for a machine-wide SDK.
The install is plain file copies (manifest to sdk-manifests/<band>, packs to packs/, templates to
template-packs/, marker to metadata/workloads/<band>/InstalledWorkloads). The registry entry is written only
when an MSI install marker exists, so a private SDK never touches HKLM. The band is the SDK’s (10.0.400 for
10.0.403); manifests are packed for 10.0.100 to 10.0.400.
$env:DOTNET_ROOT = "$env:USERPROFILE\.dotnet-gtk"
$env:DOTNET_MULTILEVEL_LOOKUP = "0"
$env:PATH = "$env:USERPROFILE\.dotnet-gtk;$env:PATH"
dotnet new gtk -n App --debug:custom-hive <dir> # hive: see below
Project: <TargetFramework>net10.0-gtk4.22</TargetFramework> (the template default net10.0-gtk also works).
SelfContained and RuntimeIdentifier default to true / the host RID only when the project does not set them;
-p:SelfContained=false is honoured (GtkSharp is then not copied: framework-dependent builds cannot see the
workload runtime pack).
| Symptom | Cause / fix |
|---|---|
dotnet new gtk produces a net6.0 + GtkSharp 3.24 project |
The globally installed GtkSharp.Template.CSharp 3.x package has the same template identity and wins. Use --debug:custom-hive <empty dir> or dotnet new uninstall GtkSharp.Template.CSharp |
NuGetUtility.exe “framework 8.0.0 not found” |
DOTNET_ROOT was set during the build; set it only for step 3 |
| Restore: “No NuGet sources are defined” | Add a nuget.config with BuildOutput/NugetPackages (and nuget.org) |
Tests / restore pick a stale GtkSharp4 |
Same version string is cached in ~/.nuget/packages; restore with --packages <dir> |
dotnet test of GtkSharp.Tests hangs with no output |
The coverlet data collector (from coverlet.runsettings) stalls on a .NET 11 preview host; pass --settings <empty .runsettings> |
| Where | Fix |
|---|---|
GtkSharp.csproj |
Pack GtkSharp.targets as build/ and buildTransitive/ $(PackageId).targets (NuGet imports only that name); the Windows Gtk download now runs for PackageReference consumers |
Workload/Shared/Frameworks.targets |
TargetFrameworkVersion from _GtkSharpNetVersion (was 8.0) |
Workload/Directory.Build.props |
Default manifest band $(_GtkSharpNetVersion).100 (was 8.0.200) |
Sdk.in.targets |
SelfContained defaults to true only when unset |
Shared/Templates.targets |
Template pack ids were ...Template.CSharp4 (blanket Sharp->Sharp4); now GtkSharp4.Workload.Template.CSharp as the install expects |
Application template |
EventArgs was ambiguous with Gtk.EventArgs; now System.EventArgs |
build.cake |
InstallPackedWorkload split out of InstallWorkload |
Not done: the same recipe against a Linux SDK (WSL); the packs only declare win-x64;win-x86;linux-x64;linux-x86;osx-x64 runtime identifiers (no arm64).