diff --git a/src/Assets/TestProjects/TrimmableNetstandardLibrary/TrimmableNetstandardLibrary.csproj b/src/Assets/TestProjects/TrimmableNetstandardLibrary/TrimmableNetstandardLibrary.csproj index 0f3ed99f87eb..1afebd15f542 100644 --- a/src/Assets/TestProjects/TrimmableNetstandardLibrary/TrimmableNetstandardLibrary.csproj +++ b/src/Assets/TestProjects/TrimmableNetstandardLibrary/TrimmableNetstandardLibrary.csproj @@ -12,6 +12,10 @@ + + + <_FirstTargetFrameworkVersionToSupportTrimAnalyzer>2.0 + true true + + <_FirstTargetFrameworkToSupportTrimming>net6.0 + <_FirstTargetFrameworkToSupportAot>net7.0 + <_FirstTargetFrameworkToSupportSingleFile>net6.0 + + <_FirstTargetFrameworkVersionToSupportTrimAnalyzer>$([MSBuild]::GetTargetFrameworkVersion('$(_FirstTargetFrameworkToSupportTrimming)')) + <_FirstTargetFrameworkVersionToSupportAotAnalyzer>$([MSBuild]::GetTargetFrameworkVersion('$(_FirstTargetFrameworkToSupportAot)')) + <_FirstTargetFrameworkVersionToSupportSingleFileAnalyzer>$([MSBuild]::GetTargetFrameworkVersion('$(_FirstTargetFrameworkToSupportSingleFile)')) @@ -43,7 +51,6 @@ Copyright (c) .NET Foundation. All rights reserved. <_RequiresILLinkPack Condition="'$(_RequiresILLinkPack)' == ''">false - - <_FirstTargetFrameworkToSupportTrimming>net6.0 - <_FirstTargetFrameworkToSupportAot>net7.0 - <_FirstTargetFrameworkToSupportSingleFile>net6.0 <_MinNonEolTargetFrameworkForTrimming>$(_MinimumNonEolSupportedNetCoreTargetFramework) <_MinNonEolTargetFrameworkForSingleFile>$(_MinimumNonEolSupportedNetCoreTargetFramework) diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.Analyzers.targets b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.Analyzers.targets index 6b71c3d0422c..00ba8b71b046 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.Analyzers.targets +++ b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.Analyzers.targets @@ -74,14 +74,26 @@ Copyright (c) .NET Foundation. All rights reserved. true + ( + ('$(PublishSingleFile)' == 'true' And '$(TargetFrameworkIdentifier)' == '.NETCoreApp' And $([MSBuild]::VersionGreaterThanOrEquals($(_TargetFrameworkVersionWithoutV), '$(_FirstTargetFrameworkVersionToSupportSingleFileAnalyzer)'))) Or + ('$(PublishAot)' == 'true' And '$(TargetFrameworkIdentifier)' == '.NETCoreApp' And $([MSBuild]::VersionGreaterThanOrEquals($(_TargetFrameworkVersionWithoutV), '$(_FirstTargetFrameworkVersionToSupportAotAnalyzer)'))) Or + '$(IsAotCompatible)' == 'true' + )">true true + ( + ('$(PublishTrimmed)' == 'true' And '$(TargetFrameworkIdentifier)' == '.NETCoreApp' And $([MSBuild]::VersionGreaterThanOrEquals($(_TargetFrameworkVersionWithoutV), '$(_FirstTargetFrameworkVersionToSupportTrimAnalyzer)'))) Or + ('$(PublishAot)' == 'true' And '$(TargetFrameworkIdentifier)' == '.NETCoreApp' And $([MSBuild]::VersionGreaterThanOrEquals($(_TargetFrameworkVersionWithoutV), '$(_FirstTargetFrameworkVersionToSupportAotAnalyzer)'))) Or + '$(IsTrimmable)' == 'true' + )">true - true + true false diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets index 0cf0b6cc48c4..63be500baa07 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets +++ b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.FrameworkReferenceResolution.targets @@ -105,12 +105,15 @@ Copyright (c) .NET Foundation. All rights reserved. SilenceIsAotCompatibleUnsupportedWarning="$(_SilenceIsAotCompatibleUnsupportedWarning)" MinNonEolTargetFrameworkForAot="$(_MinNonEolTargetFrameworkForAot)" EnableAotAnalyzer="$(EnableAotAnalyzer)" + FirstTargetFrameworkVersionToSupportAotAnalyzer="$(_FirstTargetFrameworkVersionToSupportAotAnalyzer)" PublishTrimmed="$(PublishTrimmed)" IsTrimmable="$(IsTrimmable)" + FirstTargetFrameworkVersionToSupportTrimAnalyzer="$(_FirstTargetFrameworkVersionToSupportTrimAnalyzer)" SilenceIsTrimmableUnsupportedWarning="$(_SilenceIsTrimmableUnsupportedWarning)" MinNonEolTargetFrameworkForTrimming="$(_MinNonEolTargetFrameworkForTrimming)" EnableTrimAnalyzer="$(EnableTrimAnalyzer)" EnableSingleFileAnalyzer="$(EnableSingleFileAnalyzer)" + FirstTargetFrameworkVersionToSupportSingleFileAnalyzer="$(_FirstTargetFrameworkVersionToSupportSingleFileAnalyzer)" SilenceEnableSingleFileAnalyzerUnsupportedWarning="$(_SilenceEnableSingleFileAnalyzerUnsupportedWarning)" MinNonEolTargetFrameworkForSingleFile="$(_MinNonEolTargetFrameworkForSingleFile)" AotUseKnownRuntimePackForTarget="$(PublishAotUsingRuntimePack)" diff --git a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishASingleFileApp.cs b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishASingleFileApp.cs index f1300ba8eed8..5c29ab485a47 100644 --- a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishASingleFileApp.cs +++ b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishASingleFileApp.cs @@ -633,8 +633,45 @@ public void ILLink_analyzer_warnings_are_produced_using_EnableSingleFileAnalyzer .And.HaveStdOutContaining("(10,13): warning IL3001"); } + + [RequiresMSBuildVersionTheory("17.0.0.32901")] + [InlineData("netcoreapp2.1", true)] + [InlineData("netcoreapp3.0", false)] + [InlineData("netcoreapp3.1", false)] + [InlineData("net5.0", false)] + [InlineData("net6.0", false)] + [InlineData("net7.0", false)] + public void PublishSingleFile_fails_for_unsupported_target_framework(string targetFramework, bool shouldFail) + { + var testProject = new TestProject() + { + Name = "HelloWorld", + IsExe = true, + TargetFrameworks = targetFramework + }; + testProject.AdditionalProperties["PublishSingleFile"] = "true"; + testProject.AdditionalProperties["SelfContained"] = "true"; + testProject.AdditionalProperties["NoWarn"] = "NETSDK1138"; // Silence warning about targeting EOL TFMs + var testAsset = _testAssetsManager.CreateTestProject(testProject, identifier: targetFramework); + + var publishCommand = new PublishCommand(testAsset); + var result = publishCommand.Execute(RuntimeIdentifier); + if (shouldFail) + { + result.Should().Fail() + .And.HaveStdOutContaining(Strings.PublishSingleFileRequiresVersion30); + } + else + { + result.Should().Pass() + .And.NotHaveStdOutContaining("warning"); + } + } + [RequiresMSBuildVersionTheory("17.8.0")] [InlineData("netstandard2.0", true)] + [InlineData("net5.0", true)] + [InlineData("net6.0", false)] [InlineData("netstandard2.0;net5.0", true)] // None of these TFMs are supported for single-file [InlineData("netstandard2.0;net6.0", false)] // Net6.0 is the min TFM supported for single-file and targeting. [InlineData("netstandard2.0;net8.0", true)] // Net8.0 is supported for single-file, but leaves a "gap" for the supported net6./net7.0 TFMs. diff --git a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAnAotApp.cs b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAnAotApp.cs index 60c761787054..26eb016f5e44 100644 --- a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAnAotApp.cs +++ b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAnAotApp.cs @@ -3,6 +3,7 @@ using System.Reflection.PortableExecutable; using Microsoft.DotNet.Cli.Utils; +using Microsoft.NET.Build.Tasks; using Newtonsoft.Json.Linq; using static Microsoft.NET.Publish.Tests.PublishTestUtils; @@ -590,13 +591,49 @@ public void IsAotCompatible_implies_enable_analyzers(string targetFramework) .And.NotHaveStdOutContaining("warning IL3002"); } + [RequiresMSBuildVersionTheory("17.0.0.32901")] + [InlineData("net5.0", true)] + [InlineData("net6.0", true)] + [InlineData("net7.0", false)] + public void PublishAot_fails_for_unsupported_target_framework(string targetFramework, bool shouldFail) + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + // OSX wasn't supported before net8 + return; + } + + var rid = EnvironmentInfo.GetCompatibleRid(targetFramework); + + var testProject = new TestProject() + { + Name = "HelloWorld", + TargetFrameworks = targetFramework + }; + testProject.AdditionalProperties["PublishAot"] = "true"; + var testAsset = _testAssetsManager.CreateTestProject(testProject, identifier: targetFramework); + + var publishCommand = new PublishCommand(testAsset); + var result = publishCommand.Execute($"/p:RuntimeIdentifier={rid}"); + if (shouldFail) { + result.Should().Fail() + .And.HaveStdOutContaining(Strings.AotUnsupportedTargetFramework); + } else { + result.Should().Pass() + .And.NotHaveStdOutContaining("warning"); + } + } + [RequiresMSBuildVersionTheory("17.8.0")] [InlineData("netstandard2.0", true)] + [InlineData("net6.0", true)] + [InlineData("net7.0", false)] [InlineData("netstandard2.0;net5.0", true)] // None of these TFMs are supported for AOT [InlineData("netstandard2.0;net7.0", false)] // Net7.0 is the min TFM supported for AOT and targeting. [InlineData("netstandard2.0;net8.0", true)] // Net8.0 is supported for AOT, but leaves a "gap" for the supported net7.0 TFMs. [InlineData("alias-ns2", true)] - [InlineData("alias-n6", false)] + [InlineData("alias-n6", true)] + [InlineData("alias-n7", false)] [InlineData("alias-n7;alias-n8", false)] // If all TFMs are supported, there's no warning even though the project uses aliases. [InlineData("alias-ns2;alias-n7", true)] // This is correctly multi-targeted, but the logic can't detect this due to the alias so it still warns. public void IsAotCompatible_warns_when_expected_for_not_correctly_multitarget_libraries(string targetFrameworks, bool shouldWarn) diff --git a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToRunILLink.cs b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToRunILLink.cs index f0b4eb23abf4..79e752789ded 100644 --- a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToRunILLink.cs +++ b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToRunILLink.cs @@ -148,25 +148,39 @@ public void PublishTrimmed_fails_when_no_matching_pack_is_found(string targetFra } [RequiresMSBuildVersionTheory("17.0.0.32901")] - [InlineData("netcoreapp2.0")] - [InlineData("netcoreapp2.1")] - [InlineData("netstandard2.1")] - public void PublishTrimmed_fails_for_unsupported_target_framework(string targetFramework) + [InlineData("netcoreapp2.0", true)] + [InlineData("netcoreapp2.1", true)] + [InlineData("netstandard2.1", true)] + [InlineData("netcoreapp3.0", false)] + [InlineData("netcoreapp3.1", false)] + [InlineData("net5.0", false)] + [InlineData("net6.0", false)] + public void PublishTrimmed_fails_for_unsupported_target_framework(string targetFramework, bool shouldFail) { var projectName = "HelloWorld"; var rid = EnvironmentInfo.GetCompatibleRid(targetFramework); var testProject = CreateTestProjectForILLinkTesting(targetFramework, projectName); + testProject.AdditionalProperties["PublishTrimmed"] = "true"; + testProject.AdditionalProperties["NoWarn"] = "NETSDK1138"; // Silence warning about targeting EOL TFMs var testAsset = _testAssetsManager.CreateTestProject(testProject, identifier: targetFramework); var publishCommand = new PublishCommand(testAsset); - publishCommand.Execute($"/p:RuntimeIdentifier={rid}", "/p:PublishTrimmed=true") - .Should().Fail() - .And.HaveStdOutContaining($"error {Strings.PublishTrimmedRequiresVersion30}"); + var result = publishCommand.Execute($"/p:RuntimeIdentifier={rid}"); + if (shouldFail) { + result.Should().Fail() + .And.HaveStdOutContaining($"error {Strings.PublishTrimmedRequiresVersion30}"); + } else { + result.Should().Pass() + .And.NotHaveStdOutContaining("warning"); + } } [RequiresMSBuildVersionTheory("17.8.0")] [InlineData("netstandard2.0", true)] [InlineData("netstandard2.1", true)] + [InlineData("netcoreapp3.1", true)] + [InlineData("net5.0", true)] + [InlineData("net6.0", false)] [InlineData("netstandard2.0;net5.0", true)] // None of these TFMs are supported for trimming [InlineData("netstandard2.0;net6.0", false)] // Net6.0 is the min TFM supported for trimming and targeting. [InlineData("netstandard2.0;net8.0", true)] // Net8.0 is supported for trimming, but leaves a "gap" for the supported net6.0/net7.0 TFMs. @@ -181,6 +195,7 @@ public void IsTrimmable_warns_when_expected_for_not_correctly_multitargeted_libr var testProject = CreateTestProjectForILLinkTesting(targetFrameworks, projectName); testProject.AdditionalProperties["IsTrimmable"] = "true"; + testProject.AdditionalProperties["NoWarn"] = "NETSDK1138"; // Silence warning about targeting EOL TFMs var testAsset = _testAssetsManager.CreateTestProject(testProject, identifier: targetFrameworks) .WithProjectChanges(AddTargetFrameworkAliases);