diff --git a/src/Cli/dotnet/CommonOptions.cs b/src/Cli/dotnet/CommonOptions.cs index d2502163f8bf..03625ba7ff7b 100644 --- a/src/Cli/dotnet/CommonOptions.cs +++ b/src/Cli/dotnet/CommonOptions.cs @@ -261,13 +261,6 @@ public static string GetCurrentRuntimeId() private static IEnumerable ForwardSelfContainedOptions(bool isSelfContained, ParseResult parseResult) { IEnumerable selfContainedProperties = new string[] { $"-property:SelfContained={isSelfContained}", "-property:_CommandLineDefinedSelfContained=true" }; - - if (!UserSpecifiedRidOption(parseResult) && isSelfContained) - { - var ridProperties = RuntimeArgFunc(GetCurrentRuntimeId()); - selfContainedProperties = selfContainedProperties.Concat(ridProperties); - } - return selfContainedProperties; } diff --git a/src/Tasks/Common/Resources/Strings.resx b/src/Tasks/Common/Resources/Strings.resx index 5eb21ba1bd5a..1372774cef27 100644 --- a/src/Tasks/Common/Resources/Strings.resx +++ b/src/Tasks/Common/Resources/Strings.resx @@ -1,4 +1,4 @@ - + + ResourceName="ImplicitRuntimeIdentifierResolutionForPublishPropertyFailed" + FormatArguments="SelfContained"/> + + + + + + + diff --git a/src/Tests/Microsoft.NET.Build.Tests/GlobalPropertyFlowTests.cs b/src/Tests/Microsoft.NET.Build.Tests/GlobalPropertyFlowTests.cs index d90d5ea403f6..c374a94b123a 100644 --- a/src/Tests/Microsoft.NET.Build.Tests/GlobalPropertyFlowTests.cs +++ b/src/Tests/Microsoft.NET.Build.Tests/GlobalPropertyFlowTests.cs @@ -45,7 +45,7 @@ public GlobalPropertyFlowTests(ITestOutputHelper log) : base(log) TestAsset Build(bool passSelfContained, bool passRuntimeIdentifier, [CallerMemberName] string callingMethod = "", string identifier = "") { - var testAsset = _testAssetsManager.CreateTestProject(_testProject, callingMethod: callingMethod, identifier:identifier); + var testAsset = _testAssetsManager.CreateTestProject(_testProject, callingMethod: callingMethod, identifier: identifier); var arguments = GetDotnetArguments(passSelfContained, passRuntimeIdentifier); @@ -228,7 +228,7 @@ public void TestGlobalPropertyFlowInSolution(bool passSelfContained, bool passRu var arguments = GetDotnetArguments(passSelfContained, passRuntimeIdentifier); - if (passSelfContained || passRuntimeIdentifier) + if (passRuntimeIdentifier) { new DotnetBuildCommand(Log, arguments.ToArray()) .WithWorkingDirectory(testAsset.TestRoot) @@ -252,7 +252,7 @@ private static void ValidateProperties(TestAsset testAsset, TestProject testProj { targetFramework = targetFramework ?? testProject.TargetFrameworks; - + if (string.IsNullOrEmpty(expectedRuntimeIdentifier) && (expectSelfContained || expectRuntimeIdentifier)) { // RuntimeIdentifier might be inferred, so look at the output path to figure out what the actual value used was @@ -269,7 +269,7 @@ private static void ValidateProperties(TestAsset testAsset, TestProject testProj { properties["SelfContained"].ToLowerInvariant().Should().BeOneOf("false", ""); } - + properties["RuntimeIdentifier"].Should().Be(expectedRuntimeIdentifier); } diff --git a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAHelloWorldProject.cs b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAHelloWorldProject.cs index 98656fcb8eca..979965fc3b69 100644 --- a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAHelloWorldProject.cs +++ b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAHelloWorldProject.cs @@ -1051,6 +1051,29 @@ public void It_publishes_with_full_path_publish_profile() .Pass(); } + [Theory] + [InlineData("--p:PublishReadyToRun=true")] + [InlineData("-p:PublishSingleFile=true")] + [InlineData("")] + public void It_publishes_with_implicit_rid_with_rid_specific_properties(string executeOptionsAndProperties) + { + var testProject = new TestProject() + { + Name = "PublishImplicitRid", + TargetFrameworks = $"net472;{ToolsetInfo.CurrentTargetFramework}", + }; + testProject.AdditionalProperties.Add("IsPublishable", "false"); + var testAsset = _testAssetsManager.CreateTestProject(testProject, identifier: executeOptionsAndProperties); + + var publishCommand = new PublishCommand(testAsset); + publishCommand + .Execute(executeOptionsAndProperties) + .Should() + .Pass() + .And + .NotHaveStdErrContaining("NETSDK1191"); // Publish Properties Requiring RID Checks + } + [Fact] public void IsPublishableIsRespectedWhenMultitargeting() { diff --git a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishASelfContainedApp.cs b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishASelfContainedApp.cs index a9506f11b46d..6ef5bcdfe3ce 100644 --- a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishASelfContainedApp.cs +++ b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishASelfContainedApp.cs @@ -24,24 +24,6 @@ public GivenThatWeWantToPublishASelfContainedApp(ITestOutputHelper log) : base(l { } - [Fact] - public void It_errors_when_publishing_self_contained_app_without_rid() - { - var testAsset = _testAssetsManager - .CopyTestAsset(TestProjectName) - .WithSource(); - - var publishCommand = new PublishCommand(testAsset); - publishCommand - .Execute( - "/p:SelfContained=true", - $"/p:TargetFramework={TargetFramework}") - .Should() - .Fail() - .And - .HaveStdOutContaining(Strings.CannotHaveSelfContainedWithoutRuntimeIdentifier); - } - [Fact] public void It_errors_when_publishing_self_contained_without_apphost() { @@ -129,7 +111,7 @@ public void It_can_make_a_Windows_GUI_exe() .Be(2); } - [Fact] + [RequiresMSBuildVersionFact("17.4.0.41702")] public void It_publishes_an_app_with_a_netcoreapp_lib_reference() { var testAsset = _testAssetsManager @@ -248,9 +230,9 @@ public void It_publishes_runtime_pack_resources_for_specific_languages() [RequiresMSBuildVersionFact("17.0.0.32901")] public void NoStaticLibs() { - var testAsset = _testAssetsManager - .CopyTestAsset(TestProjectName) - .WithSource(); + var testAsset = _testAssetsManager + .CopyTestAsset(TestProjectName) + .WithSource(); var publishCommand = new PublishCommand(testAsset); var tfm = ToolsetInfo.CurrentTargetFramework; diff --git a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishASingleFileApp.cs b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishASingleFileApp.cs index 3904f29cd5a4..29d3464e072e 100644 --- a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishASingleFileApp.cs +++ b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishASingleFileApp.cs @@ -125,17 +125,6 @@ public void Incremental_add_single_file() .HaveStdOutContaining("Hello World"); } - [Fact] - public void It_errors_when_publishing_single_file_app_without_rid() - { - GetPublishCommand() - .Execute(PublishSingleFile) - .Should() - .Fail() - .And - .HaveStdOutContaining(Strings.CannotHaveSingleFileWithoutRuntimeIdentifier); - } - [Fact] public void It_errors_when_publishing_single_file_without_apphost() { diff --git a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAnAotApp.cs b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAnAotApp.cs index f4a88b1db5f8..64c7127452ad 100644 --- a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAnAotApp.cs +++ b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAnAotApp.cs @@ -243,10 +243,10 @@ public void NativeAot_app_builds_with_config_when_PublishAot_is_enabled(string t .WithProjectChanges(project => AddRuntimeConfigOption(project)); var buildCommand = new BuildCommand(testAsset); - buildCommand.Execute() + buildCommand.Execute($"/p:RuntimeIdentifier={rid}") .Should().Pass(); - var outputDirectory = buildCommand.GetOutputDirectory(targetFramework).FullName; + var outputDirectory = buildCommand.GetOutputDirectory(targetFramework, runtimeIdentifier: rid).FullName; var assemblyPath = Path.Combine(outputDirectory, $"{projectName}{Constants.ExeSuffix}"); var runtimeConfigPath = Path.Combine(outputDirectory, $"{projectName}.runtimeconfig.json"); var depsPath = Path.Combine(outputDirectory, $"{projectName}.deps.json"); @@ -644,6 +644,24 @@ public void NativeAotSharedLib_only_runs_when_switch_is_enabled(string targetFra } } + [RequiresMSBuildVersionTheory("17.0.0.32901")] + [InlineData(ToolsetInfo.CurrentTargetFramework)] + public void It_publishes_with_implicit_rid_with_NativeAotApp(string targetFramework) + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + var projectName = "ImplicitRidNativeAotApp"; + var testProject = CreateHelloWorldTestProject(targetFramework, projectName, true); + testProject.AdditionalProperties["PublishAot"] = "true"; + var testAsset = _testAssetsManager.CreateTestProject(testProject); + + var publishCommand = new PublishCommand(Log, Path.Combine(testAsset.TestRoot, testProject.Name)); + publishCommand + .Execute() + .Should().Pass(); + } + } + private TestProject CreateHelloWorldTestProject(string targetFramework, string projectName, bool isExecutable) { var testProject = new TestProject() diff --git a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToRunILLink.cs b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToRunILLink.cs index af5d1bb17f7f..b91a5c3bac65 100644 --- a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToRunILLink.cs +++ b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToRunILLink.cs @@ -215,10 +215,13 @@ public void ILLink_respects_global_TrimMode(string targetFramework, string trimM File.Exists(publishedDll).Should().BeTrue(); File.Exists(isTrimmableDll).Should().BeTrue(); DoesImageHaveMethod(isTrimmableDll, "UnusedMethodToRoot").Should().BeTrue(); - if (trimMode is "link" or "full" or "partial") { + if (trimMode is "link" or "full" or "partial") + { // Check that the assembly was trimmed at the member level DoesImageHaveMethod(isTrimmableDll, "UnusedMethod").Should().BeFalse(); - } else { + } + else + { // Check that the assembly was trimmed at the assembxly level DoesImageHaveMethod(isTrimmableDll, "UnusedMethod").Should().BeTrue(); } @@ -228,7 +231,7 @@ public void ILLink_respects_global_TrimMode(string targetFramework, string trimM [MemberData(nameof(Net5Plus), MemberType = typeof(PublishTestUtils))] public void ILLink_roots_IntermediateAssembly(string targetFramework) { - var projectName = "HelloWorld"; + var projectName = "HelloWorld"; var rid = EnvironmentInfo.GetCompatibleRid(targetFramework); var testProject = CreateTestProjectForILLinkTesting(targetFramework, projectName); @@ -582,7 +585,8 @@ public void ILLink_can_show_single_warning_per_assembly(string targetFramework) var testAsset = _testAssetsManager .CopyTestAsset(testAssetName, identifier: targetFramework) .WithSource() - .WithProjectChanges(project => { + .WithProjectChanges(project => + { SetMetadata(project, "PackageReference", "TrimmerSingleWarn", "false"); SetMetadata(project, "ProjectReference", "TrimmerSingleWarn", "true"); SetMetadata(project, "App", "TrimmerSingleWarn", "true"); @@ -681,7 +685,7 @@ public void ILLink_verify_analysis_warnings_hello_world_app_trim_mode_link(strin ValidateWarningsOnHelloWorldApp(publishCommand, result, Array.Empty(), targetFramework, rid); } - private void ValidateWarningsOnHelloWorldApp (PublishCommand publishCommand, CommandResult result, string[] expectedOutput, string targetFramework, string rid) + private void ValidateWarningsOnHelloWorldApp(PublishCommand publishCommand, CommandResult result, string[] expectedOutput, string targetFramework, string rid) { // This checks that there are no unexpected warnings, but does not cause failures for missing expected warnings. var warnings = result.StdOut.Split('\n', '\r').Where(line => line.Contains("warning IL")); @@ -1453,7 +1457,8 @@ public void Build_respects_IsTrimmable_property(string targetFramework, bool isE // just setting IsTrimmable doesn't enable feature settings // (these only affect apps, and wouldn't make sense for libraries either) - if (isExe) { + if (isExe) + { JObject runtimeConfig = JObject.Parse(File.ReadAllText(runtimeConfigPath)); JToken configProperties = runtimeConfig["runtimeOptions"]["configProperties"]; if (configProperties != null) @@ -1466,18 +1471,18 @@ public void Build_respects_IsTrimmable_property(string targetFramework, bool isE public void Build_respects_PublishTrimmed_property(string targetFramework) { var projectName = "AnalysisWarnings"; - + var rid = EnvironmentInfo.GetCompatibleRid(targetFramework); var testProject = CreateTestProjectWithAnalysisWarnings(targetFramework, projectName); testProject.AdditionalProperties["PublishTrimmed"] = "true"; var testAsset = _testAssetsManager.CreateTestProject(testProject, identifier: targetFramework); var buildCommand = new BuildCommand(testAsset); // PublishTrimmed enables analysis warnings during build - buildCommand.Execute() + buildCommand.Execute($"-p:RuntimeIdentifier={rid}") .Should().Pass() .And.HaveStdOutMatching("warning IL2026.*Program.IL_2026.*Testing analysis warning IL2026"); - var outputDirectory = buildCommand.GetOutputDirectory(targetFramework).FullName; + var outputDirectory = buildCommand.GetOutputDirectory(targetFramework, runtimeIdentifier: rid).FullName; var assemblyPath = Path.Combine(outputDirectory, $"{projectName}.dll"); var runtimeConfigPath = Path.Combine(outputDirectory, $"{projectName}.runtimeconfig.json"); @@ -1577,7 +1582,8 @@ private void SetMetadata(XDocument project, string assemblyName, string key, str .Where(e => e.Attribute("Name")?.Value == targetName) .FirstOrDefault(); - if (target == null) { + if (target == null) + { target = new XElement(ns + "Target", new XAttribute("BeforeTargets", "PrepareForILLink"), new XAttribute("Name", targetName)); @@ -1646,8 +1652,9 @@ private void AddFeatureDefinition(TestProject testProject, string assemblyName) "; - - testProject.AddItem("EmbeddedResource", new Dictionary { + + testProject.AddItem("EmbeddedResource", new Dictionary + { ["Include"] = substitutionsFilename, ["LogicalName"] = substitutionsFilename }); @@ -1728,7 +1735,7 @@ public override void IL_2046() {} return testProject; } - private TestProject CreateTestProjectWithIsTrimmableAttributes ( + private TestProject CreateTestProjectWithIsTrimmableAttributes( string targetFramework, string projectName) { @@ -1772,7 +1779,7 @@ public static void UnusedMethod() { } }"; - testProject.ReferencedProjects.Add (trimmableProject); + testProject.ReferencedProjects.Add(trimmableProject); var nonTrimmableProject = new TestProject() { @@ -1791,7 +1798,7 @@ public static void UnusedMethod() { } }"; - testProject.ReferencedProjects.Add (nonTrimmableProject); + testProject.ReferencedProjects.Add(nonTrimmableProject); var unusedTrimmableProject = new TestProject() { @@ -1811,7 +1818,7 @@ public static void UnusedMethod() } } "; - testProject.ReferencedProjects.Add (unusedTrimmableProject); + testProject.ReferencedProjects.Add(unusedTrimmableProject); var unusedNonTrimmableProject = new TestProject() { @@ -1827,7 +1834,7 @@ public static void UnusedMethod() } } "; - testProject.ReferencedProjects.Add (unusedNonTrimmableProject); + testProject.ReferencedProjects.Add(unusedNonTrimmableProject); return testProject; } @@ -1871,7 +1878,9 @@ public static void UseClassLib() ClassLib.UsedMethod(); } }"; - } else { + } + else + { testProject.SourceFiles[$"{mainProjectName}.cs"] += @"}"; } diff --git a/src/Tests/dotnet-build.Tests/GivenDotnetBuildBuildsCsproj.cs b/src/Tests/dotnet-build.Tests/GivenDotnetBuildBuildsCsproj.cs index e1e34c69ff5d..c2871b869b4b 100644 --- a/src/Tests/dotnet-build.Tests/GivenDotnetBuildBuildsCsproj.cs +++ b/src/Tests/dotnet-build.Tests/GivenDotnetBuildBuildsCsproj.cs @@ -204,7 +204,7 @@ public void It_does_not_warn_on_rid_with_self_contained_set_in_project() TargetFrameworks = ToolsetInfo.CurrentTargetFramework, }; testProject.AdditionalProperties["SelfContained"] = "true"; - + var testInstance = _testAssetsManager.CreateTestProject(testProject); new DotnetBuildCommand(Log) @@ -252,8 +252,11 @@ public void It_does_not_warn_on_rid_with_self_contained_options_prior_to_net6() .NotHaveStdOutContaining("NETSDK1179"); } - [Fact] - public void It_builds_with_implicit_rid_with_self_contained_option() + [Theory] + [InlineData("--self-contained")] + [InlineData("-p:PublishTrimmed=true")] + [InlineData("")] + public void It_builds_with_implicit_rid_with_rid_specific_properties(string executeOptionsAndProperties) { var testInstance = _testAssetsManager.CopyTestAsset("HelloWorld") .WithSource() @@ -262,11 +265,13 @@ public void It_builds_with_implicit_rid_with_self_contained_option() new DotnetBuildCommand(Log) .WithWorkingDirectory(testInstance.Path) - .Execute("--self-contained") + .Execute(executeOptionsAndProperties) .Should() .Pass() .And - .NotHaveStdOutContaining("NETSDK1031"); + .NotHaveStdOutContaining("NETSDK1031") // Self Contained Checks + .And + .NotHaveStdErrContaining("NETSDK1190"); // Check that publish properties don't interfere with build either } [RequiresMSBuildVersionFact("17.4.0.41702")] diff --git a/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetOsArchOptions.cs b/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetOsArchOptions.cs index 6f68a648b745..49ca2bd8fffe 100644 --- a/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetOsArchOptions.cs +++ b/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetOsArchOptions.cs @@ -155,8 +155,7 @@ public void ItUsesImplicitRidWhenNoneIsSpecifiedForSelfContained() command.GetArgumentsToMSBuild() .Should() .StartWith($"{ExpectedPrefix} -restore -consoleloggerparameters:Summary " + - $"-property:SelfContained=True -property:_CommandLineDefinedSelfContained=true " + - $"-property:RuntimeIdentifier={currentRid} -property:_CommandLineDefinedRuntimeIdentifier=true"); + $"-property:SelfContained=True -property:_CommandLineDefinedSelfContained=true"); }); }