dotnet / command-line-api

Command line parsing, invocation, and rendering of terminal output.
https://github.com/dotnet/command-line-api/wiki
MIT License
3.41k stars 382 forks source link

Multi-target to include down level `net4x` binaries in Nuget package #1194

Open mjcheetham opened 3 years ago

mjcheetham commented 3 years ago

Problem Background

When consuming a .NET Standard (netstandardx.y) package from a .NET Framework (net4x) project that's below .NET Framework 4.7.2 (for example net461) a bunch of extra support and shim binaries must be distributed due to some compatibility issues. This can balloon the size of the application that must be distributed to customers.

See https://docs.microsoft.com/en-us/dotnet/standard/net-standard#net-implementation-support, table footnote [2]:

The versions listed here represent the rules that NuGet uses to determine whether a given .NET Standard library is applicable. While NuGet considers .NET Framework 4.6.1 as supporting .NET Standard 1.5 through 2.0, there are several issues with consuming .NET Standard libraries that were built for those versions from .NET Framework 4.6.1 projects. For .NET Framework projects that need to use such libraries, we recommend that you upgrade the project to target .NET Framework 4.7.2 or higher.

In the multi-targeting documentation it is recommended that library authors should:

✔️ CONSIDER adding a target for net461 when you're offering a netstandard2.0 target.

Using .NET Standard 2.0 from .NET Framework has some issues that were addressed in .NET Framework 4.7.2. You can improve the experience for developers that are still on .NET Framework 4.6.1 - 4.7.1 by offering them a binary that is built for .NET Framework 4.6.1.

Source: https://docs.microsoft.com/en-us/dotnet/standard/library-guidance/cross-platform-targeting#multi-targeting

When application authors wish to consume System.CommandLine, but are unable to target .NET Frameworks newer than 4.7.2 they must ship all these extra DLLs because the System.CommandLine package only supports .NET Standard 2.0 (netstandard2.0)

Proposal

Introduce a net461 target framework in the System.CommandLine project so that consumers that must target .NET Framework have a better experience.

In src/System.CommandLine/System.CommandLine.csproj:

     <PackageId>System.CommandLine</PackageId>
-    <TargetFramework>netstandard2.0</TargetFramework>
+    <TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
     <LangVersion>8</LangVersion>
mjcheetham commented 3 years ago

Note that .NET Framework 4.7.2 was only first pre-installed in Windows 10 April 2018 Update (version 1803), and the last version of Windows to support 4.7.2 is Windows 7 SP1.

Source: https://docs.microsoft.com/en-us/dotnet/framework/get-started/system-requirements#supported-client-operating-systems

Consumers of System.CommandLine that must support Windows Vista cannot target .NET Core (not supported) and also cannot target any version of .NET Framework beyond 4.6, so it's open as to what the lowest reasonable .NET Framework version you'd want to try and support, be that 4.5, 4.6, 4.6.1, or newer.