Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Log msbuild warning for missing TargetFrameworks #175

Merged
merged 12 commits into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 21 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,27 @@ The package targets `netstandard2.0` and is designed to support the following ru
**See [Milestones](../../milestones?state=closed) for release notes.**


## TargetFrameworks

Some polyfills are implemented in a way that will not have the equivalent performance to the actual implementations.

For example the polyfill for `StringBuilder.Append(ReadOnlySpan<char>)` on netcore2 is:

```
public StringBuilder Append(ReadOnlySpan<char> value)
=> target.Append(value.ToString());
```

Which will result in a string allocation.

As Polyfill is implemented as a source only nuget, the implementation for each polyfill is compiled into the IL of the resulting assembly. As a side-effect that implementation will continue to be used even if that assembly is executed in a runtime that has a more efficient implementation available.

As a result, in the context of a project producing nuget package, that project should target all frameworks from the lowest TargetFramework up to and including the current framework. This way the most performant implementation will be used for each runtime. Take the following examples:

* If a nuget's minimum target is net6, then the resulting TargetFrameworks should also include net7.0 and net8.0
* If a nuget's minimum target is net471, then the resulting TargetFrameworks should also include net472 and net48"


## Nuget

https://nuget.org/packages/Polyfill/
Expand Down
1 change: 1 addition & 0 deletions src/Consume/Consume.csproj
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<NoWarn>$(NoWarn);PolyFillTargetsForNuget</NoWarn>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT'">net461;net462;net47;net471;net472;net48;net481;net6.0-windows</TargetFrameworks>
<TargetFrameworks>$(TargetFrameworks);netstandard2.0;netstandard2.1;netcoreapp2.0;netcoreapp2.1;netcoreapp2.2;netcoreapp3.0;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<NoWarn>$(NoWarn);PolyFillTargetsForNuget</NoWarn>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT'">net461;net462;net47;net471;net472;net48;net481;net6.0-windows</TargetFrameworks>
<TargetFrameworks>$(TargetFrameworks);netstandard2.0;netstandard2.1;netcoreapp2.0;netcoreapp2.1;netcoreapp2.2;netcoreapp3.0;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
Expand Down
1 change: 1 addition & 0 deletions src/ConsumeIndirect/ConsumeIndirect.csproj
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<NoWarn>$(NoWarn);PolyFillTargetsForNuget</NoWarn>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT'">net461;net462;net47;net471;net472;net48;net481;net6.0-windows</TargetFrameworks>
<TargetFrameworks>$(TargetFrameworks);netstandard2.0;netstandard2.1;netcoreapp2.0;netcoreapp2.1;netcoreapp2.2;netcoreapp3.0;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
Expand Down
1 change: 1 addition & 0 deletions src/ConsumeNoRefs/ConsumeNoRefs.csproj
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<NoWarn>$(NoWarn);PolyFillTargetsForNuget</NoWarn>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT'">net461;net462;net47;net471;net472;net48;net481;net6.0-windows</TargetFrameworks>
<TargetFrameworks>$(TargetFrameworks);netstandard2.0;netstandard2.1;netcoreapp2.0;netcoreapp2.1;netcoreapp2.2;netcoreapp3.0;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<NoWarn>$(NoWarn);PolyFillTargetsForNuget</NoWarn>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<TargetFrameworks>netstandard2.0</TargetFrameworks>
</PropertyGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<PropertyGroup>
<Version>4.9.0</Version>
<Version>5.0.0</Version>
<AssemblyVersion>1.0.0</AssemblyVersion>
<PackageTags>Polyfill</PackageTags>
<DisableImplicitNamespaceImports>true</DisableImplicitNamespaceImports>
Expand Down
1 change: 1 addition & 0 deletions src/NoRefsTests/NoRefsTests.csproj
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<NoWarn>$(NoWarn);PolyFillTargetsForNuget</NoWarn>
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT'">net462;net472;net48;net6.0-windows</TargetFrameworks>
<TargetFrameworks>$(TargetFrameworks);netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
</PropertyGroup>
Expand Down
6 changes: 6 additions & 0 deletions src/Polyfill.sln
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsumeNoRefs", "ConsumeNoR
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsumeTasksWithNoMemory", "ConsumeTasksWithNoMemory\ConsumeTasksWithNoMemory.csproj", "{96EF1E04-5862-4D9E-B800-A6402F1ADF7A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TargetFrameowkUsage", "TargetFrameowkUsage\TargetFrameowkUsage.csproj", "{41CB5A0C-E0F5-4C5C-B2FC-9A289E8CFDF8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -84,6 +86,10 @@ Global
{96EF1E04-5862-4D9E-B800-A6402F1ADF7A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{96EF1E04-5862-4D9E-B800-A6402F1ADF7A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{96EF1E04-5862-4D9E-B800-A6402F1ADF7A}.Release|Any CPU.Build.0 = Release|Any CPU
{41CB5A0C-E0F5-4C5C-B2FC-9A289E8CFDF8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{41CB5A0C-E0F5-4C5C-B2FC-9A289E8CFDF8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{41CB5A0C-E0F5-4C5C-B2FC-9A289E8CFDF8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{41CB5A0C-E0F5-4C5C-B2FC-9A289E8CFDF8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
38 changes: 38 additions & 0 deletions src/Polyfill/Polyfill.targets
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<PropertyGroup>
<PrepareForBuildDependsOn>$(PrepareForBuildDependsOn);PreparePolyfill</PrepareForBuildDependsOn>
<LowerFramework>$(TargetFramework.ToLower())</LowerFramework>
<LowerFrameworks>$(TargetFrameworks.ToLower())</LowerFrameworks>
</PropertyGroup>
<PropertyGroup Condition="$(AllowUnsafeBlocks) == 'true' ">
<DefineConstants>$(DefineConstants);AllowUnsafeBlocks</DefineConstants>
Expand Down Expand Up @@ -31,6 +32,43 @@
$(LowerFramework.StartsWith('netcoreapp3'))">
<DefineConstants>$(DefineConstants);NETCOREAPPX</DefineConstants>
</PropertyGroup>
<PropertyGroup>
<MaxNetRequired>false</MaxNetRequired>
<MaxNetRequired
Condition="$(LowerFrameworks.Contains('net5')) OR
$(LowerFrameworks.Contains('net6')) OR
$(LowerFrameworks.Contains('net7')) OR
$(LowerFrameworks.Contains('netstandard')) OR
$(LowerFrameworks.Contains('netcore'))"
>true</MaxNetRequired>

<MaxNetClassicRequired>false</MaxNetClassicRequired>
<MaxNetClassicRequired
Condition="(
$(LowerFrameworks.Contains('net4')) OR
$(LowerFrameworks.Contains('netstandard'))
)
AND
!$(LowerFramework.Contains('net48'))
AND
!$(LowerFrameworks.Contains('net48'))"
>true</MaxNetClassicRequired>
</PropertyGroup>
<Target
Name="PolyFillValidateNugetTargets"
AfterTargets="AfterBuild"
Condition="$(NoWarn.Contains('PolyFillTargetsForNuget')) != true">
<Warning
Code="PolyFillTargetsForNuget"
Text="Projects that produce a nuget and consume PolyFill:
For best performance all frameworks from the lowest TargetFramework up to and including net48 should be targeted.
For example:
* If a nuget's minimum target is net47, then the resulting TargetFrameworks should include net471, net472, and net48.
* If a nuget's minimum target net6, then the resulting TargetFrameworks should include net7.0 and net8.0."
HelpLink="https://github.com/SimonCropp/Polyfill#targetframeworks"
Condition="$(MaxNetClassicRequired) OR $(MaxNetRequired)" />
</Target>

<Target Name="PreparePolyfill" DependsOnTargets="ResolvePackageAssets">
<PropertyGroup>
<DefineConstants
Expand Down
1 change: 1 addition & 0 deletions src/PublicTests/PublicTests.csproj
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<NoWarn>$(NoWarn);PolyFillTargetsForNuget</NoWarn>
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT'">net462;net472;net48</TargetFrameworks>
<TargetFrameworks>$(TargetFrameworks);netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
<PolyPublic>true</PolyPublic>
Expand Down
8 changes: 8 additions & 0 deletions src/TargetFrameowkUsage/TargetFrameowkUsage.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<GeneratePackageOnBuild Condition="'$(Configuration)' == 'Debug'">true</GeneratePackageOnBuild>
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT'">net461</TargetFrameworks>
<TargetFrameworks>$(TargetFrameworks);net5.0</TargetFrameworks>
</PropertyGroup>
<Import Project="$(SolutionDir)\Polyfill\Polyfill.targets" />
</Project>
1 change: 1 addition & 0 deletions src/Tests/Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<NoWarn>$(NoWarn);PolyFillTargetsForNuget</NoWarn>
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT'">net462;net472;net48;net6.0-windows</TargetFrameworks>
<TargetFrameworks>$(TargetFrameworks);netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
</PropertyGroup>
Expand Down
1 change: 1 addition & 0 deletions src/UnsafeTests/UnsafeTests.csproj
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<NoWarn>$(NoWarn);PolyFillTargetsForNuget</NoWarn>
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT'">net462;net472;net48</TargetFrameworks>
<TargetFrameworks>$(TargetFrameworks);netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
Expand Down