Add DependencyOnlyTargetFrameworks to eliminate System.ValueTuple from net471 NuGet graph#126773
Add DependencyOnlyTargetFrameworks to eliminate System.ValueTuple from net471 NuGet graph#126773
DependencyOnlyTargetFrameworks to eliminate System.ValueTuple from net471 NuGet graph#126773Conversation
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/3ab46313-c615-4bf8-ab41-c39ac2b60d77 Co-authored-by: ericstj <8918108+ericstj@users.noreply.github.com>
…irect users (Option 2) Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/55b33308-5b6c-4b57-9bdb-81b49c84b6bf Co-authored-by: ericstj <8918108+ericstj@users.noreply.github.com>
…ref assets shipped) Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/55b33308-5b6c-4b57-9bdb-81b49c84b6bf Co-authored-by: ericstj <8918108+ericstj@users.noreply.github.com>
…n packaging.targets Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/474682a7-ecbe-4a65-b384-1477530033eb Co-authored-by: ericstj <8918108+ericstj@users.noreply.github.com>
|
@copilot can you fix the docs, can you also update this issue with the data we gathered by trying both option 1 and option 2. All of these measurements should be part of https://github.com/dotnet/runtime/tasks/1eacb5f4-97cd-4cc7-8fc3-812fe976ef9b?session_id=3ab46313-c615-4bf8-ab41-c39ac2b60d77 |
…ng.md Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/71fa89bc-7d12-4ed7-952e-31943b7bcf62 Co-authored-by: ericstj <8918108+ericstj@users.noreply.github.com>
|
Tagging subscribers to this area: @dotnet/area-infrastructure-libraries |
Added the documentation in commit 02fa65e ( |
net471 projects referencing these packages get
System.ValueTuplepulled into the NuGet graph via thenet462dependency group, even though net471 hasSystem.ValueTupleinbox. This adds anet471dependency group (with noSystem.ValueTuple) to the 12 packages that directly reference it, without shipping any additional assemblies.Description
Approach
Three options were evaluated. Size measurements are based on the 10.0.0 packages from the NuGet global cache.
Option 1 — Add
net471to all ~43 packages (transitive + direct) ❌ DiscardedEach of the 43 packages that transitively depends on
System.ValueTuplewould get alib/net471assembly added. The newnet471assemblies would be byte-for-byte identical to the existingnet462assemblies — pure overhead.lib/net462sizeTotal additional assembly size: ~4.1 MB (3,835 KB measured + ~300 KB estimated for System.Linq.AsyncEnumerable). 43 packages grow.
Option 2 — Add
net471only to the 12 packages with directSystem.ValueTuplereferences ❌ DiscardedNuGet resolves each package's dependency group independently, so fixing only the 12 packages that directly reference
System.ValueTupleis sufficient for net471 consumers. However, each of the 12 packages would still need alib/net471assembly — again byte-for-byte identical to thelib/net462assembly.lib/net462size (= addedlib/net471size)Total additional assembly size: ~2.4 MB (2,102 KB measured + ~300 KB estimated for System.Linq.AsyncEnumerable). 12 packages grow.
Option 3 (chosen) —
DependencyOnlyTargetFrameworks✅Same NuGet graph fix as Option 2 (a
net471dependency group is emitted in the nuspec for each of the 12 packages), butlib/net471is suppressed entirely. Consumers fall back tolib/net462for the assembly. Total additional assembly size: 0 bytes. No packages grow.Changes
eng/packaging.targets— IntroducesDependencyOnlyTargetFrameworks: a general-purpose semicolon-separated property for TFMs that should emit a NuGet dependency group but ship nolib/assembly. When set:TargetFrameworksso the SDK runs inner builds and generates dependency groupsIncludeBuildOutput=falsefor those inner builds (nolib/entry in the package)NU5128suppressed (intentional dep-group/lib mismatch)12 src
.csprojfiles — Replace$(NetFrameworkWithValueTuple)inTargetFrameworkswith a dedicatedDependencyOnlyTargetFrameworksproperty:Affected packages:
Microsoft.Bcl.Memory,Microsoft.Bcl.TimeProvider,Microsoft.Extensions.Caching.Memory,Microsoft.Extensions.Configuration.Abstractions,Microsoft.Extensions.Logging,Microsoft.Extensions.Options,System.Formats.Asn1,System.Formats.Cbor,System.Formats.Nrbf,System.Linq.AsyncEnumerable,System.Text.Encoding.CodePages,System.Text.Jsondocs/coding-guidelines/libraries-packaging.md— Added aDependencyOnlyTargetFrameworkssection documenting the feature: what it is, when to use it, a code example using$(NetFrameworkWithValueTuple), and how theeng/packaging.targetsinfrastructure implements it.Result
For each affected package, the nuspec gains an empty
.NETFramework4.7.1dependency group. net471 consumers resolve noSystem.ValueTupledependency and fall back tolib/net462for the assembly. No new assemblies ship; package sizes are unchanged.DependencyOnlyTargetFrameworksto 12 affected .csproj filesDependencyOnlyTargetFrameworksineng/packaging.targetsDependencyOnlyTargetFrameworksdocumentation todocs/coding-guidelines/libraries-packaging.md