Skip to content

Commit 28033ad

Browse files
committed
Start the pruning documentation
1 parent abda464 commit 28033ad

7 files changed

Lines changed: 256 additions & 15 deletions

File tree

docs/consume-packages/Package-References-in-Project-Files.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,60 @@ namespace PackageReferenceAliasesExample
239239

240240
```
241241

242+
## Multi-targeting with duplicate frameworks
243+
244+
*This feature requires [NuGet 7.6](../release-notes/NuGet-7.6.md) / .NET SDK 10.0.300 or later.*
245+
246+
SDK-style projects support [multi-targeting](../create-packages/multiple-target-frameworks-project-file.md) by listing multiple values in the `TargetFrameworks` property. Because [TargetFramework values are aliases](../reference/target-frameworks.md#targetframework-values-are-aliases), multiple aliases can resolve to the *same* effective framework. Starting with [NuGet 7.6](../release-notes/NuGet-7.6.md) / .NET SDK 10.0.300, NuGet and the .NET SDK support this scenario.
247+
248+
This enables use cases such as:
249+
250+
- **Multi-RID builds**: Build platform-specific assemblies from a single project.
251+
252+
```xml
253+
<Project Sdk="Microsoft.NET.Sdk">
254+
<PropertyGroup>
255+
<TargetFrameworks>apple;banana</TargetFrameworks>
256+
</PropertyGroup>
257+
258+
<PropertyGroup>
259+
<TargetFrameworkIdentifier>.NETCoreApp</TargetFrameworkIdentifier>
260+
<TargetFrameworkVersion>v10.0</TargetFrameworkVersion>
261+
<TargetFrameworkMoniker>.NETCoreApp,Version=v10.0</TargetFrameworkMoniker>
262+
</PropertyGroup>
263+
</Project>
264+
```
265+
266+
- **Multi-version extensions**: Target multiple versions of a host application, such as Visual Studio.
267+
268+
```xml
269+
<Project Sdk="Microsoft.VisualStudio.Extensibility.Sdk">
270+
<PropertyGroup>
271+
<TargetFrameworks>vs18;vs17.14</TargetFrameworks>
272+
</PropertyGroup>
273+
</Project>
274+
```
275+
276+
In this example, the Visual Studio Extensibility SDK is responsible for setting the canonical moniker properties for each alias.
277+
278+
### Pack
279+
280+
A NuGet package can only contain one set of build output and one dependency group per effective framework. When you pack a project with duplicate effective frameworks, you must tell NuGet which alias contributes these assets or the pack raises [NU5051](../reference/errors-and-warnings/NU5051.md). See [NU5051](../reference/errors-and-warnings/NU5051.md) for resolution steps and examples.
281+
282+
### Lock file
283+
284+
When a project uses duplicate effective frameworks, the [packages lock file](#locking-dependencies) is automatically upgraded to a format that uses the alias as the key instead of the effective framework. This upgrade happens transparently — locked mode and CI/CD scenarios continue to work as before.
285+
286+
### Project references
287+
288+
When a project references another project that has multiple aliases resolving to the same framework, NuGet uses the alias name as a tiebreaker. If the referencing project has an alias with the same name as one in the referenced project, that alias is preferred. If there's no matching name and multiple candidates exist, NuGet reports an error.
289+
290+
### Limitations
291+
292+
- Only SDK-style projects support duplicate effective frameworks.
293+
- Aliases that contain path separator characters (`/` or `\`) are blocked.
294+
- Visual Studio's Package Manager UI doesn't have special support for duplicate frameworks, but you can manage packages by editing the project file directly or using the `dotnet` CLI.
295+
242296
## NuGet warnings and errors
243297

244298
*This feature is available with NuGet **4.3** or above and with Visual Studio 2017 **15.3** or above.*

docs/create-packages/multiple-target-frameworks-project-file.md

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,19 @@
11
---
22
title: Multi-targeting for NuGet Packages in your project file
3-
description: Description of the various methods to target multiple .NET Framework versions from within a single NuGet package in your project file.
3+
description: Description of the various methods to target multiple .NET frameworks from within a single NuGet package in your project file.
44
author: JonDouglas
55
ms.author: jodou
66
ms.date: 07/15/2019
77
ms.topic: how-to
88
---
99

10-
# Support multiple .NET Framework versions in your project file
10+
# Support multiple .NET frameworks in your project file
1111

1212
When you first create a project, we recommend you create a .NET Standard class library, as it provides compatibility with the widest range of consuming projects. By using .NET Standard, you add [cross-platform support](/dotnet/standard/library-guidance/cross-platform-targeting) to a .NET library by default. However, in some scenarios, you may also need to include code that targets a particular framework. This article shows you how to do that for [SDK-style](../resources/check-project-format.md) projects.
1313

1414
For SDK-style projects, you can configure support for multiple targets frameworks ([TFM](/dotnet/standard/frameworks)) in your project file, then use `dotnet pack` or `msbuild /t:pack` to create the package.
1515

16-
> [!NOTE]
17-
> nuget.exe CLI does not support packing SDK-style projects, so you should only use `dotnet pack` or `msbuild /t:pack`. We recommend that you [include all the properties](../reference/msbuild-targets.md#pack-target) that are usually in the `.nuspec` file in the project file instead. To target multiple .NET Framework versions in a non-SDK-style project, see [Supporting multiple .NET Framework versions](supporting-multiple-target-frameworks.md).
18-
19-
## Create a project that supports multiple .NET Framework versions
16+
## Create a project that supports multiple .NET frameworks
2017

2118
1. Create a new .NET Standard class library either in Visual Studio or use `dotnet new classlib`.
2219

@@ -69,7 +66,14 @@ Here is the *.csproj* file that is generated using the preceding steps and .NET
6966
</Project>
7067
```
7168

69+
## Multi-targeting with duplicate frameworks
70+
71+
Starting with [NuGet 7.6](../release-notes/NuGet-7.6.md) / .NET SDK 10.0.300, you can use multiple `TargetFrameworks` values that resolve to the same underlying framework. This enables scenarios like building for multiple runtimes or targeting multiple versions of a host application from a single project.
72+
73+
For details on how this works with restore and pack, see [Multi-targeting with duplicate frameworks](../consume-packages/package-references-in-project-files.md#multi-targeting-with-duplicate-frameworks).
74+
7275
## See also
7376

7477
* [How to specify target frameworks](/dotnet/standard/frameworks#how-to-specify-target-frameworks)
7578
* [Cross-platform targeting](/dotnet/standard/library-guidance/cross-platform-targeting)
79+
* [Target frameworks reference](../reference/target-frameworks.md)

docs/reference/Errors-and-Warnings.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ NuGet supports the following configuration properties.
3535
| NuGet source errors | [NU1301](./errors-and-warnings/NU1301.md), [NU1302](./errors-and-warnings/NU1302.md) |
3636
| NuGet internal errors | [NU1000](./errors-and-warnings/NU1000.md) |
3737
| Signed packages errors (creation and verification) | [NU3001](./errors-and-warnings/NU3001.md), [NU3004](./errors-and-warnings/NU3004.md), [NU3005](./errors-and-warnings/NU3005.md), [NU3008](./errors-and-warnings/NU3008.md), [NU3034](./errors-and-warnings/NU3034.md)|
38-
| Pack Errors | [NU5000](./errors-and-warnings/NU5000.md), [NU5001](./errors-and-warnings/NU5001.md), [NU5002](./errors-and-warnings/NU5002.md), [NU5003](./errors-and-warnings/NU5003.md), [NU5004](./errors-and-warnings/NU5004.md), [NU5005](./errors-and-warnings/NU5005.md), [NU5007](./errors-and-warnings/NU5007.md), [NU5008](./errors-and-warnings/NU5008.md), [NU5009](./errors-and-warnings/NU5009.md), [NU5010](./errors-and-warnings/NU5010.md), [NU5011](./errors-and-warnings/NU5011.md), [NU5012](./errors-and-warnings/NU5012.md), [NU5013](./errors-and-warnings/NU5013.md), [NU5014](./errors-and-warnings/NU5014.md), [NU5015](./errors-and-warnings/NU5015.md), [NU5016](./errors-and-warnings/NU5016.md), [NU5017](./errors-and-warnings/NU5017.md), [NU5018](./errors-and-warnings/NU5018.md), [NU5019](./errors-and-warnings/NU5019.md), [NU5020](./errors-and-warnings/NU5020.md), [NU5021](./errors-and-warnings/NU5021.md), [NU5022](./errors-and-warnings/NU5022.md), [NU5023](./errors-and-warnings/NU5023.md), [NU5024](./errors-and-warnings/NU5024.md), [NU5025](./errors-and-warnings/NU5025.md), [NU5026](./errors-and-warnings/NU5026.md), [NU5027](./errors-and-warnings/NU5027.md), [NU5028](./errors-and-warnings/NU5028.md), [NU5029](./errors-and-warnings/NU5029.md), [NU5036](./errors-and-warnings/NU5036.md), [NU5042](./errors-and-warnings/NU5042.md), [NU5049](./errors-and-warnings/NU5049.md) |
38+
| Pack Errors | [NU5000](./errors-and-warnings/NU5000.md), [NU5001](./errors-and-warnings/NU5001.md), [NU5002](./errors-and-warnings/NU5002.md), [NU5003](./errors-and-warnings/NU5003.md), [NU5004](./errors-and-warnings/NU5004.md), [NU5005](./errors-and-warnings/NU5005.md), [NU5007](./errors-and-warnings/NU5007.md), [NU5008](./errors-and-warnings/NU5008.md), [NU5009](./errors-and-warnings/NU5009.md), [NU5010](./errors-and-warnings/NU5010.md), [NU5011](./errors-and-warnings/NU5011.md), [NU5012](./errors-and-warnings/NU5012.md), [NU5013](./errors-and-warnings/NU5013.md), [NU5014](./errors-and-warnings/NU5014.md), [NU5015](./errors-and-warnings/NU5015.md), [NU5016](./errors-and-warnings/NU5016.md), [NU5017](./errors-and-warnings/NU5017.md), [NU5018](./errors-and-warnings/NU5018.md), [NU5019](./errors-and-warnings/NU5019.md), [NU5020](./errors-and-warnings/NU5020.md), [NU5021](./errors-and-warnings/NU5021.md), [NU5022](./errors-and-warnings/NU5022.md), [NU5023](./errors-and-warnings/NU5023.md), [NU5024](./errors-and-warnings/NU5024.md), [NU5025](./errors-and-warnings/NU5025.md), [NU5026](./errors-and-warnings/NU5026.md), [NU5027](./errors-and-warnings/NU5027.md), [NU5028](./errors-and-warnings/NU5028.md), [NU5029](./errors-and-warnings/NU5029.md), [NU5036](./errors-and-warnings/NU5036.md), [NU5042](./errors-and-warnings/NU5042.md), [NU5049](./errors-and-warnings/NU5049.md), [NU5051](./errors-and-warnings/NU5051.md) |
3939
| License specific Pack Errors | [NU5030](./errors-and-warnings/NU5030.md), [NU5031](./errors-and-warnings/NU5031.md), [NU5032](./errors-and-warnings/NU5032.md), [NU5033](./errors-and-warnings/NU5033.md), [NU5034](./errors-and-warnings/NU5034.md), [NU5035](./errors-and-warnings/NU5035.md) |
4040
| NuGetAudit specific warnings | [NU1014](./errors-and-warnings/NU1014.md), [NU1900](./errors-and-warnings/NU1900.md), [NU1901, NU1902, NU1903, NU1904](./errors-and-warnings/NU1901-NU1904.md), [NU1905](./errors-and-warnings/NU1905.md) |
4141

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
---
2+
title: NuGet Error NU5051
3+
description: NU5051 error code
4+
author: nkolev92
5+
ms.author: nikolev
6+
ms.date: 03/25/2026
7+
ms.topic: reference
8+
f1_keywords:
9+
- "NU5051"
10+
---
11+
12+
# NuGet Error NU5051
13+
14+
## Scenario 1
15+
16+
A project has multiple target framework aliases that resolve to the same effective framework, and pack can't determine which alias should contribute build output, dependencies, or framework references to the package.
17+
18+
### Issue
19+
20+
A project like the following has two aliases (`apple` and `banana`) that both resolve to `net10.0`:
21+
22+
```xml
23+
<Project Sdk="Microsoft.NET.Sdk">
24+
<PropertyGroup>
25+
<TargetFrameworks>apple;banana</TargetFrameworks>
26+
</PropertyGroup>
27+
28+
<PropertyGroup>
29+
<TargetFrameworkIdentifier>.NETCoreApp</TargetFrameworkIdentifier>
30+
<TargetFrameworkVersion>v10.0</TargetFrameworkVersion>
31+
<TargetFrameworkMoniker>.NETCoreApp,Version=v10.0</TargetFrameworkMoniker>
32+
</PropertyGroup>
33+
</Project>
34+
```
35+
36+
When you run `dotnet pack`, NuGet raises NU5051 because it can't include duplicate build output or dependency groups for the same framework in a single package.
37+
38+
### Solution
39+
40+
Set `IncludeBuildOutput` to `false` and `SuppressDependenciesWhenPacking` to `true` on all but one alias per effective framework. This tells NuGet which alias contributes the build output and dependencies.
41+
42+
```xml
43+
<!-- Let 'apple' contribute the build output and dependencies -->
44+
<PropertyGroup Condition="'$(TargetFramework)' == 'banana'">
45+
<IncludeBuildOutput>false</IncludeBuildOutput>
46+
<SuppressDependenciesWhenPacking>true</SuppressDependenciesWhenPacking>
47+
</PropertyGroup>
48+
```
49+
50+
If the aliases have different `FrameworkReference` items, use `PrivateAssets="all"` on the framework references in the secondary aliases to suppress them from the package.
51+
52+
## Scenario 2
53+
54+
A project has aliases for runtime-specific builds and wants to place each alias's build output into a custom package path (for example, `runtimes/<rid>/lib/<tfm>/`).
55+
56+
### Issue
57+
58+
A project like the following has `net10.0` as the primary alias and `linux` and `ios` as secondary aliases. All three resolve to the same effective framework:
59+
60+
```xml
61+
<Project Sdk="Microsoft.NET.Sdk">
62+
<PropertyGroup>
63+
<TargetFrameworks>net10.0;linux;ios</TargetFrameworks>
64+
</PropertyGroup>
65+
66+
<PropertyGroup Condition="'$(TargetFramework)' == 'linux' OR '$(TargetFramework)' == 'ios' OR '$(TargetFramework)' == 'net10.0'">
67+
<TargetFrameworkIdentifier>.NETCoreApp</TargetFrameworkIdentifier>
68+
<TargetFrameworkVersion>v10.0</TargetFrameworkVersion>
69+
<TargetFrameworkMoniker>.NETCoreApp,Version=v10.0</TargetFrameworkMoniker>
70+
</PropertyGroup>
71+
</Project>
72+
```
73+
74+
Running `dotnet pack` raises NU5051 because three aliases produce build output and dependencies for the same framework.
75+
76+
### Solution
77+
78+
Suppress the default build output and dependencies for the secondary aliases, and use `TargetsForTfmSpecificContentInPackage` to place the secondary aliases' assemblies into custom package paths:
79+
80+
```xml
81+
<PropertyGroup>
82+
<TargetsForTfmSpecificContentInPackage>$(TargetsForTfmSpecificContentInPackage);GetMyPackageFiles</TargetsForTfmSpecificContentInPackage>
83+
</PropertyGroup>
84+
85+
<PropertyGroup Condition="'$(TargetFramework)' == 'linux' OR '$(TargetFramework)' == 'ios'">
86+
<IncludeBuildOutput>false</IncludeBuildOutput>
87+
<SuppressDependenciesWhenPacking>true</SuppressDependenciesWhenPacking>
88+
</PropertyGroup>
89+
90+
<Target Name="GetMyPackageFiles">
91+
<ItemGroup Condition="'$(TargetFramework)' == 'linux' OR '$(TargetFramework)' == 'ios'">
92+
<TfmSpecificPackageFile Include="$(OutputPath)$(AssemblyName).dll">
93+
<PackagePath>runtimes/$(TargetFramework)/lib/net10.0</PackagePath>
94+
</TfmSpecificPackageFile>
95+
</ItemGroup>
96+
</Target>
97+
```
98+
99+
With this configuration, `net10.0` contributes the default `lib/net10.0/` build output and dependencies, while `linux` and `ios` place their assemblies under `runtimes/linux/lib/net10.0/` and `runtimes/ios/lib/net10.0/` respectively.
100+
101+
For more information about multi-targeting with duplicate frameworks, see [PackageReference in project files](../../consume-packages/package-references-in-project-files.md#multi-targeting-with-duplicate-frameworks). For more information about pack extensibility, see [pack target](../msbuild-targets.md#pack-target).

docs/reference/target-frameworks.md

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
---
22
title: Target Frameworks Reference for NuGet
3-
description: NuGet target framework references identify and isolate framework-dependent components of a package.
4-
author: JonDouglas
5-
ms.author: jodou
6-
ms.date: 12/11/2017
3+
description: NuGet target framework references identify and isolate framework-dependent components of a package, including support for multi-targeting with duplicate frameworks.
4+
author: nkolev92
5+
ms.author: nikolev
6+
ms.date: 03/25/2026
77
ms.topic: reference
8-
ms.reviewer: anangaur
98
---
109

1110
# Target frameworks
@@ -17,9 +16,38 @@ NuGet uses target framework references in a variety of places to specifically id
1716
- [.nupkg folder name](../create-packages/creating-a-package.md#from-a-convention-based-working-directory): The folders inside a package's `lib` folder can be named according to the target framework, each of which contains the DLLs and other content appropriate to that framework.
1817
- [packages.config](../reference/packages-config.md): The `targetframework` attribute of a dependency specifies the variant of a package to install.
1918

20-
> [!Note]
21-
> NuGet supports all of the modern .NET target frameworks:
22-
> - For a list of the latest target frameworks, see the [Target frameworks in SDK-style projects](/dotnet/standard/frameworks) documentation.
19+
For the canonical list of all supported target frameworks and their TFM syntax, see [Target frameworks in SDK-style projects](/dotnet/standard/frameworks).
20+
21+
## TargetFramework values are aliases
22+
23+
The `TargetFramework` property in a project file is a friendly name — an alias — that gets translated into a canonical framework identity. The .NET SDK performs this translation by setting the `TargetFrameworkMoniker` (TFM), and when applicable, the `TargetPlatformMoniker` properties.
24+
25+
For example, when you write `<TargetFramework>net10.0-windows</TargetFramework>`, the .NET SDK translates that into:
26+
27+
- `TargetFrameworkMoniker` = `.NETCoreApp,Version=v10.0`
28+
- `TargetPlatformMoniker` = `Windows,Version=7.0`
29+
30+
NuGet uses these moniker properties — not the `TargetFramework` string — for package compatibility checks. This means the `TargetFramework` value itself can be any string, as long as the moniker properties are set correctly. For example, the following project is valid:
31+
32+
```xml
33+
<Project Sdk="Microsoft.NET.Sdk">
34+
<PropertyGroup>
35+
<TargetFramework>banana</TargetFramework>
36+
</PropertyGroup>
37+
38+
<PropertyGroup Condition=" '$(TargetFramework)' == 'banana' ">
39+
<TargetFrameworkIdentifier>.NETFramework</TargetFrameworkIdentifier>
40+
<TargetFrameworkVersion>v10.0</TargetFrameworkVersion>
41+
<TargetFrameworkMoniker>.NETCoreApp,Version=v10.0</TargetFrameworkMoniker>
42+
</PropertyGroup>
43+
</Project>
44+
```
45+
46+
This project restores and builds for .NET 10.0, even though the `TargetFramework` value is `banana`. The .NET SDK already relies on this aliasing mechanism for OS-specific TFMs like `net8.0-ios` and `net8.0-android`, where the short TFM is translated into the full moniker with platform information.
47+
48+
## Multi-targeting with duplicate frameworks
49+
50+
Starting with [NuGet 7.6](../release-notes/NuGet-7.6.md) / .NET SDK 10.0.300, multiple `TargetFrameworks` aliases can resolve to the same effective framework. This enables scenarios like multi-RID builds and multi-version extension targeting. For details on how this works with restore, pack, lock files, and project references, see [Multi-targeting with duplicate frameworks](../consume-packages/package-references-in-project-files.md#multi-targeting-with-duplicate-frameworks).
2351

2452
## Supported frameworks
2553

@@ -89,6 +117,8 @@ Universal Windows Platform | uap | uap [uap10.0] |
89117
| | | net6.0 |
90118
| | | net7.0 |
91119
| | | net8.0 |
120+
| | | net9.0 |
121+
| | | net10.0 |
92122
Tizen | tizen | tizen3 |
93123
| | | tizen4 |
94124
| Native | native | native |

docs/release-notes/NuGet-7.5.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
title: NuGet 7.5 Release Notes
3+
description: Release notes for NuGet 7.5 including new features, bug fixes, and DCRs.
4+
author: nikolev
5+
ms.topic: conceptual
6+
---
7+
# NuGet 7.5 Release Notes
8+
9+
<!--
10+
This is intentionally not yet added to TOC.md.
11+
When this version is ready for release:
12+
1. Rename this file to the next version
13+
2. Change the version strings in this file to the next version
14+
3. Use the release tool to create the real release notes for the version ready for release
15+
4. Add the release notes to TOC.yml
16+
-->
17+
18+
NuGet distribution vehicles:
19+
20+
| NuGet version | Available in Visual Studio version | Available in .NET SDK(s) |
21+
|:---|:---|:---|
22+
| [**7.5**](https://nuget.org/downloads) | TBD | TBD |
23+
24+
## Not yet released
25+
26+
This version of NuGet is in preview and these release notes will be updated when it is released.

docs/release-notes/NuGet-7.6.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
title: NuGet 7.6 Release Notes
3+
description: Release notes for NuGet 7.5 6ncluding new features, bug fixes, and DCRs.
4+
author: nikolev
5+
ms.topic: release-notes
6+
---
7+
# NuGet 7.6 Release Notes
8+
9+
<!--
10+
This is intentionally not yet added to TOC.md.
11+
When this version is ready for release:
12+
1. Rename this file to the next version
13+
2. Change the version strings in this file to the next version
14+
3. Use the release tool to create the real release notes for the version ready for release
15+
4. Add the release notes to TOC.yml
16+
-->
17+
18+
NuGet distribution vehicles:
19+
20+
| NuGet version | Available in Visual Studio version | Available in .NET SDK(s) |
21+
|:---|:---|:---|
22+
| [**7.5**](https://nuget.org/downloads) | TBD | TBD |
23+
24+
## Not yet released
25+
26+
This version of NuGet is in preview and these release notes will be updated when it is released.

0 commit comments

Comments
 (0)