Use stable net/netframework folders for the mono SDK tasks - #132402
Merged
Conversation
The mono and WebAssembly SDK packages placed their task assemblies in TFM-versioned subfolders (tasks/net11.0, tasks/net472, tools/net11.0), and the Sdk.props.in/Sdk.targets.in templates hardcoded those TFMs via template tokens. Every .NET Core TFM bump then required coordinated updates across the layout producer and all of its consumers. Emit the task build output into stable, version-independent folders (net for .NET Core, netframework for .NET Framework) by overriding OutputPath/IntermediateOutputPath, mirroring ILLink.Tasks. This covers WasmAppBuilder, WasmBuildTasks, MonoAOTCompiler, MonoTargetsTasks, LibraryBuilder, MobileBuildTasks, AppleAppBuilder, AndroidAppBuilder, HelixTestTasks and WorkloadBuildTasks. The package layouts and the in-tree consumers (Directory.Build.props, WasmApp.LocalBuild.props, AppleBuild.LocalBuild.props) now use the same net/netframework names, which also lets the hardcoded _NetCoreAppToolCurrent literals and the now-dead property forwarding in tests.ioslike.targets go away. With no TFM tokens left, the .in templates become fully static, so rename them to their final names and drop the GenerateFileFromTemplate steps from the pkgprojs. The netframework OutputPath overrides are guarded on NetFrameworkToolCurrent being non-empty. In source-only builds it is empty, so the bare '$(TargetFramework)' == '$(NetFrameworkToolCurrent)' comparison was also true in the outer build of a multi-targeting project (where TargetFramework is likewise empty), which appended netframework/ to the shared OutputPath and made GetFilesToPackage look in netframework/net/. This applies to Microsoft.NET.Sdk.WebAssembly.Pack.Tasks too, which grew the same pattern in a previous change. WorkloadBuildTasks keeps a TFM-named folder for its pinned net8.0 build, since that one is selected by the consuming project's own TFM. Its Sdk.targets now defaults to tasks/net rather than resolving tasks/$(TargetFramework), which silently produced a nonexistent path for consumers on any other TFM. Along the way this fixes a few latent issues: - WasmBuildTasks.dll was packaged at tasks/ while WasmBuildTasksAssemblyPath pointed at tasks/<TFM>/. It now ships in tasks/net where the property resolves. - src/tests/Common/Directory.Build.targets re-derived the WasmAppBuilder and MonoTargetsTasks output paths instead of using the shared properties. It now uses them so it cannot drift again. - TestExclusionListTasks was removed in dotnet#123909 but left behind a stale project reference and two unused properties. - The MonoAOTCompiler.Task readme pointed at tools/<target-framework>/ rather than the tasks/ folder the package actually ships. Contributes to dotnet#123155 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 50cbbd7b-5246-4157-959c-0f92990d8f73
akoeplinger
requested review from
lewing,
maraf,
steveisok and
vitek-karas
as code owners
August 17, 2026 11:18
|
Azure Pipelines: Successfully started running 4 pipeline(s). 12 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR removes TFM-versioned task output folders for Mono/WebAssembly SDK task assemblies and switches to stable net / netframework (plus pinned net8.0 where required), updating both package layouts and in-tree consumers to eliminate hardcoded TFMs in paths and templates.
Changes:
- Override
OutputPath/IntermediateOutputPathfor multiple task projects to emit outputs into stablenet/netframeworkfolders. - Update SDK props/targets, local build props, and test build targets to consume the new stable folders and remove now-unneeded TFM token templating steps.
- Fix/align packaging and documentation paths to match the new on-disk and in-package layouts (including removing stale references like
TestExclusionListTasks).
Reviewed changes
Copilot reviewed 35 out of 35 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/tests/Common/Directory.Build.targets | Copy runtime dependency inputs via shared task output directory properties instead of reconstructing TFM paths. |
| src/tasks/WorkloadBuildTasks/WorkloadBuildTasks.csproj | Emit task outputs into stable net folder while keeping a pinned net8.0 output for TFM-selected consumption. |
| src/tasks/WasmBuildTasks/WasmBuildTasks.csproj | Emit build output into stable net folder and package it under tasks/net. |
| src/tasks/WasmAppBuilder/WasmAppBuilder.csproj | Emit outputs into net / netframework, adjust packaged task paths, and update task loading paths. |
| src/tasks/tasks.proj | Remove stale reference to removed TestExclusionListTasks. |
| src/tasks/MonoTargetsTasks/MonoTargetsTasks.csproj | Emit outputs into net / netframework and package into stable task folders. |
| src/tasks/MonoTargetsTasks/JsonToItemsTaskFactory/README.md | Update example path to use bin/.../net/ stable folder. |
| src/tasks/MobileBuildTasks/MobileBuildTasks.csproj | Emit outputs into net / netframework and package into stable task folders. |
| src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks.csproj | Guard netframework output path overrides and use stable net / netframework folder names. |
| src/tasks/LibraryBuilder/LibraryBuilder.csproj | Emit outputs into net / netframework and package into stable task folders. |
| src/tasks/HelixTestTasks/HelixTestTasks.csproj | Emit output into stable net folder for version-independent consumption. |
| src/tasks/AppleAppBuilder/AppleAppBuilder.csproj | Emit output into stable net folder and package under tasks/net. |
| src/tasks/AotCompilerTask/MonoAOTCompiler.csproj | Emit outputs into net / netframework and package into stable task folders. |
| src/tasks/AndroidAppBuilder/AndroidAppBuilder.csproj | Emit output into stable net folder and package under tasks/net. |
| src/mono/wasm/build/WasmApp.LocalBuild.props | Switch local build task output directories to stable net folder names. |
| src/mono/wasm/build/README.md | Update documented task directory example to use stable net folder. |
| src/mono/nuget/Microsoft.NET.Runtime.WorkloadTesting.Internal/Sdk/Sdk.targets | Default to tasks/net for task resolution, with net8.0 override for pinned TFM selection. |
| src/mono/nuget/Microsoft.NET.Runtime.WebAssembly.Wasi.Sdk/Sdk/Sdk.targets | Resolve tasks from stable tasks/net / tasks/netframework folders. |
| src/mono/nuget/Microsoft.NET.Runtime.WebAssembly.Wasi.Sdk/Microsoft.NET.Runtime.WebAssembly.Wasi.Sdk.pkgproj | Stop generating .targets from templates; include static Sdk.targets. |
| src/mono/nuget/Microsoft.NET.Runtime.WebAssembly.Sdk/Sdk/Sdk.targets | Resolve tasks from stable tasks/net / tasks/netframework folders. |
| src/mono/nuget/Microsoft.NET.Runtime.WebAssembly.Sdk/Microsoft.NET.Runtime.WebAssembly.Sdk.pkgproj | Stop generating .targets from templates; include static Sdk.targets. |
| src/mono/nuget/Microsoft.NET.Runtime.wasm.Sample.Mono/Microsoft.NET.Runtime.wasm.Sample.Mono.pkgproj | Place sample tool files under tools/net/ stable folder. |
| src/mono/nuget/Microsoft.NET.Runtime.MonoTargets.Sdk/Sdk/MonoTargetsTasks.props | Resolve MonoTargetsTasks from stable tasks/net / tasks/netframework folders. |
| src/mono/nuget/Microsoft.NET.Runtime.MonoTargets.Sdk/Microsoft.NET.Runtime.MonoTargets.Sdk.pkgproj | Stop generating .props from templates; include static MonoTargetsTasks.props. |
| src/mono/nuget/Microsoft.NET.Runtime.MonoAOTCompiler.Task/Sdk/Sdk.props | Resolve MonoAOTCompiler from stable tasks/net / tasks/netframework folders. |
| src/mono/nuget/Microsoft.NET.Runtime.MonoAOTCompiler.Task/README.md | Update UsingTask example to use tasks/net/MonoAOTCompiler.dll. |
| src/mono/nuget/Microsoft.NET.Runtime.MonoAOTCompiler.Task/Microsoft.NET.Runtime.MonoAOTCompiler.Task.pkgproj | Stop generating Sdk.props from templates; include static Sdk.props. |
| src/mono/nuget/Microsoft.NET.Runtime.LibraryBuilder.Sdk/Sdk/Sdk.targets | Resolve tasks from stable tasks/net / tasks/netframework folders. |
| src/mono/nuget/Microsoft.NET.Runtime.LibraryBuilder.Sdk/Microsoft.NET.Runtime.LibraryBuilder.Sdk.pkgproj | Stop generating .targets from templates; include static Sdk.targets. |
| src/mono/nuget/Microsoft.NET.Runtime.iOS.Sample.Mono/Microsoft.NET.Runtime.iOS.Sample.Mono.pkgproj | Place sample tool files under tools/net/ stable folder. |
| src/mono/nuget/Microsoft.NET.Runtime.Android.Sample.Mono/Microsoft.NET.Runtime.Android.Sample.Mono.pkgproj | Place sample tool files under tools/net/ stable folder. |
| src/mono/msbuild/apple/build/AppleBuild.LocalBuild.props | Switch local build task output directories to stable net folder names. |
| src/mono/browser/build/README.md | Update documented task directory example to use stable net folder. |
| eng/testing/tests.ioslike.targets | Remove forwarding of now-unused _NetCoreAppToolCurrent property into Apple build test property set. |
| Directory.Build.props | Switch shared task output directory properties and task assembly paths to stable net/netframework folder names and remove stale TestExclusionListTasks properties. |
$(TargetFramework) is now passed in as a global property by the AOT build command instead of hardcoding the TFM in the props file, so that .NET Core TFM bumps don't require updating it. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 50cbbd7b-5246-4157-959c-0f92990d8f73
maraf
approved these changes
Aug 17, 2026
This was referenced Aug 17, 2026
Member
Author
|
/ba-g failure are unrelated issues |
Member
Author
|
/backport to release/11.0-rc1 |
Contributor
|
Started backporting to |
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #130782, which did the same for
Microsoft.NET.Sdk.WebAssembly.Pack.Tasks.The mono and WebAssembly SDK packages placed their task assemblies in TFM-versioned subfolders (
tasks/net11.0,tasks/net472,tools/net11.0), and theSdk.props.in/Sdk.targets.intemplates hardcoded those TFMs via template tokens. Every .NET Core TFM bump then required coordinated updates across the layout producer and all of its consumers.This emits the task build output into stable, version-independent folders (
netfor .NET Core,netframeworkfor .NET Framework) by overridingOutputPath/IntermediateOutputPath, mirroringILLink.Tasks. It coversWasmAppBuilder,WasmBuildTasks,MonoAOTCompiler,MonoTargetsTasks,LibraryBuilder,MobileBuildTasks,AppleAppBuilder,AndroidAppBuilder,HelixTestTasksandWorkloadBuildTasks.The package layouts and the in-tree consumers (
Directory.Build.props,WasmApp.LocalBuild.props,AppleBuild.LocalBuild.props) now use the same names, which also lets the hardcoded_NetCoreAppToolCurrentliterals and the now-dead property forwarding intests.ioslike.targetsgo away.With no TFM tokens left, the
.intemplates become fully static, so they're renamed to their final names and theGenerateFileFromTemplatesteps are dropped from the pkgprojs.WorkloadBuildTaskskeeps a TFM-named folder for its pinnednet8.0build, since that one is selected by the consuming project's own TFM. ItsSdk.targetsnow defaults totasks/netrather than resolvingtasks/$(TargetFramework), which silently produced a nonexistent path for consumers on any other TFM.Latent issues fixed along the way
OutputPathoverrides are now guarded onNetFrameworkToolCurrentbeing non-empty. In source-only builds it is empty, so the bare'$(TargetFramework)' == '$(NetFrameworkToolCurrent)'comparison was also true in the outer build of a multi-targeting project (whereTargetFrameworkis likewise empty), appendingnetframework/to the sharedOutputPath. This applies toMicrosoft.NET.Sdk.WebAssembly.Pack.Taskstoo, which grew the same pattern in Use stable net/netframework folders for WebAssembly.Pack.Tasks #130782.WasmBuildTasks.dllwas packaged attasks/whileWasmBuildTasksAssemblyPathpointed attasks/<TFM>/. It now ships intasks/netwhere the property resolves.src/tests/Common/Directory.Build.targetsre-derived theWasmAppBuilderandMonoTargetsTasksoutput paths instead of using the shared properties, so it had already drifted. It now uses them.TestExclusionListTaskswas removed in Remove support for issues.targets #123909 but left behind a stale project reference and two unused properties.MonoAOTCompiler.Taskreadme pointed attools/<target-framework>/rather than thetasks/folder the package actually ships.Validation
All 10 task projects build clean into
net(+netframeworkwhere multi-targeted), in both normal and source-only mode. All affected packages were packed and unzipped: they containtasks/net,tasks/netframework,tools/netandtasks/net8.0as intended, with no TFM version strings in any package path. Every*TasksAssemblyPathproperty was evaluated and confirmed to resolve to a file that exists on disk.Fixes #123155
Note
This pull request was authored with the assistance of GitHub Copilot.