diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.PackTool.targets b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.PackTool.targets
index 9a0559a03a4d..6566bebb20ef 100644
--- a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.PackTool.targets
+++ b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.PackTool.targets
@@ -51,28 +51,38 @@ NOTE: This file is imported from the following contexts, so be aware when writin
<_UserSpecifiedToolPackageRids Condition="'$(_UserSpecifiedToolPackageRids)' == ''">$(RuntimeIdentifiers)
<_HasRIDSpecificTools Condition=" '$(_UserSpecifiedToolPackageRids)' != '' ">true
<_HasRIDSpecificTools Condition="'$(_HasRIDSpecificTools)' == ''">false
+
+
$(_UserSpecifiedToolPackageRids);$(PackAsToolShimRuntimeIdentifiers)
<_IsRidSpecific>false
<_IsRidSpecific Condition="'$(RuntimeIdentifier)' != '' and '$(RuntimeIdentifier)' != 'any'">true
-
-
-
-
- false
-
- false
- false
- false
- false
-
+ Knowing this lets us correctly decide to create the RID-specific inner tools or not when packaging the outer tool. -->
<_InnerToolsPublishAot>false
<_InnerToolsPublishAot Condition="$(_HasRIDSpecificTools) and '$(PublishAot)' == 'true'">true
- false
+
+
+ <_IsImplicitRestore>false
+ <_IsImplicitRestore Condition="'$(MSBuildIsRestoring)' == 'true'">true
+ <_IsPacking Condition="'$(_IsPacking)' == ''">false
+
+
+ false
+ false
+ false
+ false
+ false
+ false
@@ -82,11 +92,13 @@ NOTE: This file is imported from the following contexts, so be aware when writin
<_ToolPackageShouldIncludeImplementation Condition="'$(_ToolPackageShouldIncludeImplementation)' == ''">false
- <_PackToolPublishDependency Condition=" '$(_ToolPackageShouldIncludeImplementation)' != '' and '$(GeneratePackageOnBuild)' != 'true' and $(IsPublishable) == 'true' ">Publish
+ <_PackToolPublishDependency Condition=" $(_ToolPackageShouldIncludeImplementation) and '$(GeneratePackageOnBuild)' != 'true' and $(IsPublishable) == 'true' ">Publish
- <_PackToolPublishDependency Condition=" '$(_ToolPackageShouldIncludeImplementation)' != '' and '$(GeneratePackageOnBuild)' == 'true' and $(IsPublishable) == 'true' ">$(_PublishNoBuildAlternativeDependsOn)
+ <_PackToolPublishDependency Condition=" $(_ToolPackageShouldIncludeImplementation) and '$(GeneratePackageOnBuild)' == 'true' and $(IsPublishable) == 'true' ">$(_PublishNoBuildAlternativeDependsOn)
+
+ <_PackToolPublishDependency Condition="!$(_ToolPackageShouldIncludeImplementation)">
@@ -105,7 +105,7 @@ Copyright (c) .NET Foundation. All rights reserved.
'$(RuntimeIdentifier)' == '' and
'$(_IsExecutable)' == 'true' and
'$(IsRidAgnostic)' != 'true' and
- '$(PackAsTool)' != true and
+ ('$(PackAsTool)' != 'true' or '$(_IsPacking)' != 'true') and
(
'$(SelfContained)' == 'true' or
('$(_IsPublishing)' == 'true' and
@@ -216,10 +216,8 @@ Copyright (c) .NET Foundation. All rights reserved.
$([MSBuild]::VersionLessThan('$(_TargetFrameworkVersionWithoutV)', '5.0'))">$(DefaultAppHostRuntimeIdentifier.Replace("arm64", "x64"))
-
-
+
+
+
+
+
+
false
false
false
+
false
false
false
diff --git a/test/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildAnAppWithoutTransitiveProjectRefs.cs b/test/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildAnAppWithoutTransitiveProjectRefs.cs
index 74de1a348826..57f2fc797cdc 100644
--- a/test/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildAnAppWithoutTransitiveProjectRefs.cs
+++ b/test/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildAnAppWithoutTransitiveProjectRefs.cs
@@ -29,6 +29,9 @@ public void It_builds_the_project_successfully_with_static_graph_and_isolation()
public void It_cleans_the_project_successfully_with_static_graph_and_isolation()
{
var (testAsset, outputDirectories) = BuildAppWithTransitiveDependenciesAndTransitiveCompileReference(new[] { "/graph", "/bl:build-{}.binlog" });
+ var binlogDestPath = Environment.GetEnvironmentVariable("HELIX_WORKITEM_UPLOAD_ROOT") is { } ciOutputRoot && Environment.GetEnvironmentVariable("HELIX_WORKITEM_ID") is { } helixGuid ?
+ Path.Combine(ciOutputRoot, "binlog", helixGuid, $"{nameof(It_cleans_the_project_successfully_with_static_graph_and_isolation)}.binlog") :
+ "./msbuild.binlog";
var cleanCommand = new DotnetCommand(
Log,
@@ -36,7 +39,7 @@ public void It_cleans_the_project_successfully_with_static_graph_and_isolation()
Path.Combine(testAsset.TestRoot, "1", "1.csproj"),
"/t:clean",
"/graph",
- "/bl:clean-{}.binlog");
+ $"/bl:{binlogDestPath}");
cleanCommand
.Execute()
@@ -175,12 +178,16 @@ public void It_builds_the_project_successfully_when_RAR_does_not_find_all_refere
private (CommandResult BuildResult, IReadOnlyDictionary OutputDirectories) Build(
TestAsset testAsset,
IEnumerable targetFrameworks,
- string[] msbuildArguments
+ string[] msbuildArguments,
+ [CallerMemberName] string callingMethod = ""
)
{
var buildCommand = new BuildCommand(testAsset, "1");
buildCommand.WithWorkingDirectory(testAsset.TestRoot);
- var buildResult = buildCommand.ExecuteWithoutRestore(msbuildArguments);
+ var binlogDestPath = Environment.GetEnvironmentVariable("HELIX_WORKITEM_UPLOAD_ROOT") is { } ciOutputRoot && Environment.GetEnvironmentVariable("HELIX_WORKITEM_ID") is { } helixGuid ?
+ Path.Combine(ciOutputRoot, "binlog", helixGuid, $"{callingMethod}.binlog") :
+ "./msbuild.binlog";
+ var buildResult = buildCommand.ExecuteWithoutRestore([..msbuildArguments, $"/bl:{binlogDestPath}"]);
var outputDirectories = targetFrameworks.ToImmutableDictionary(tf => tf, tf => buildCommand.GetOutputDirectory(tf));
diff --git a/test/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishASingleFileApp.cs b/test/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishASingleFileApp.cs
index 6f917540cbc1..d8a821397e42 100644
--- a/test/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishASingleFileApp.cs
+++ b/test/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishASingleFileApp.cs
@@ -736,7 +736,7 @@ public void EnableSingleFile_warns_when_expected_for_not_correctly_multitargeted
testProject.AdditionalProperties["CheckEolTargetFramework"] = "false"; // Silence warning about targeting EOL TFMs
var testAsset = _testAssetsManager.CreateTestProject(testProject, identifier: targetFrameworks)
.WithProjectChanges(AddTargetFrameworkAliases);
-
+
var buildCommand = new BuildCommand(testAsset);
var resultAssertion = buildCommand.Execute("/p:CheckEolTargetFramework=false")
.Should().Pass();
@@ -853,9 +853,14 @@ public void It_can_disable_cetcompat(bool? cetCompat)
testProject.AdditionalProperties.Add("CetCompat", cetCompat.ToString());
}
+ var binlogDestPath = Environment.GetEnvironmentVariable("HELIX_WORKITEM_UPLOAD_ROOT") is { } ciOutputRoot && Environment.GetEnvironmentVariable("HELIX_WORKITEM_ID") is { } helixGuid ?
+ Path.Combine(ciOutputRoot, "binlog", helixGuid, $"{nameof(It_can_disable_cetcompat)}_{cetCompat?.ToString() ?? "null"}.binlog") :
+ "./msbuild.binlog";
+
+
var testAsset = _testAssetsManager.CreateTestProject(testProject, identifier: cetCompat.HasValue ? cetCompat.Value.ToString() : "default");
var publishCommand = new PublishCommand(testAsset);
- publishCommand.Execute(PublishSingleFile)
+ publishCommand.Execute(PublishSingleFile, "/bl:" + binlogDestPath)
.Should()
.Pass();
diff --git a/test/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAToolProject.cs b/test/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAToolProject.cs
index 18d4f9d2390a..b9bca0e339e7 100644
--- a/test/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAToolProject.cs
+++ b/test/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishAToolProject.cs
@@ -10,6 +10,12 @@ namespace Microsoft.NET.Publish.Tests
{
public class GivenThatWeWantToPublishAToolProject : SdkTest
{
+
+ public static string HostfxrName =
+ RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "hostfxr.dll" :
+ RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? "libhostfxr.so" :
+ "libhostfxr.dylib";
+
public GivenThatWeWantToPublishAToolProject(ITestOutputHelper log) : base(log)
{
}
@@ -37,5 +43,24 @@ public void It_can_publish_and_has_apphost()
publishCommand.GetOutputDirectory(targetFramework: ToolsetInfo.CurrentTargetFramework)
.Should().HaveFile("consoledemo" + Constants.ExeSuffix);
}
+
+ [Fact]
+ // this test verifies that we don't regress the 'normal' publish experience accidentally in the
+ // PackTool.targets
+ public void It_can_publish_selfcontained_and_has_apphost()
+ {
+ var testAsset = SetupTestAsset().SetProjProperty("PublishSelfContained", "true");
+ var publishCommand = new PublishCommand(testAsset);
+
+ var binlogDestPath = Environment.GetEnvironmentVariable("HELIX_WORKITEM_UPLOAD_ROOT") is { } ciOutputRoot ?
+ Path.Combine(ciOutputRoot, "binlog", $"{nameof(It_can_publish_selfcontained_and_has_apphost)}.binlog") :
+ "./msbuild.binlog";
+
+ publishCommand.WithWorkingDirectory(testAsset.Path).Execute($"-bl:{binlogDestPath}");
+
+ publishCommand.GetOutputDirectory(targetFramework: ToolsetInfo.CurrentTargetFramework, runtimeIdentifier: System.Runtime.InteropServices.RuntimeInformation.RuntimeIdentifier)
+ .Should().HaveFile("consoledemo" + Constants.ExeSuffix)
+ .And.HaveFile(HostfxrName);
+ }
}
}
diff --git a/test/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishIncrementally.cs b/test/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishIncrementally.cs
index c34806bd2fad..c47c60089692 100644
--- a/test/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishIncrementally.cs
+++ b/test/Microsoft.NET.Publish.Tests/GivenThatWeWantToPublishIncrementally.cs
@@ -62,11 +62,14 @@ public void It_cleans_between_renames()
};
var testAsset = _testAssetsManager.CreateTestProject(testProject, testProject.Name);
+ var binlogDestPath = Environment.GetEnvironmentVariable("HELIX_WORKITEM_UPLOAD_ROOT") is { } ciOutputRoot && Environment.GetEnvironmentVariable("HELIX_WORKITEM_ID") is { } helixGuid ?
+ Path.Combine(ciOutputRoot, "binlog", helixGuid, $"{nameof(It_cleans_between_renames)}.binlog") :
+ "./msbuild.binlog";
// Publish as a single file
var publishCommand = new PublishCommand(testAsset);
publishCommand
- .Execute(@"/p:PublishSingleFile=true")
+ .Execute(@"/p:PublishSingleFile=true", $"-bl:{binlogDestPath}")
.Should()
.Pass();
@@ -104,10 +107,14 @@ public void It_cleans_between_single_file_publishes()
};
var testAsset = _testAssetsManager.CreateTestProject(testProject, testProject.Name);
- // Publish as a single file
- var publishCommand = new PublishCommand(testAsset);
+ var binlogDestPath = Environment.GetEnvironmentVariable("HELIX_WORKITEM_UPLOAD_ROOT") is { } ciOutputRoot && Environment.GetEnvironmentVariable("HELIX_WORKITEM_ID") is { } helixGuid ?
+ Path.Combine(ciOutputRoot, "binlog", helixGuid, $"{nameof(It_cleans_between_single_file_publishes)}.binlog") :
+ "./msbuild.binlog";
+
+
+ var publishCommand = new PublishCommand(testAsset).WithWorkingDirectory(testAsset.Path) as PublishCommand;
publishCommand
- .Execute(@"/p:PublishSingleFile=true")
+ .Execute(@"/p:PublishSingleFile=true", $"-bl:{binlogDestPath}")
.Should()
.Pass();
diff --git a/test/Microsoft.NET.Publish.Tests/GivenThatWeWantToRunILLink.cs b/test/Microsoft.NET.Publish.Tests/GivenThatWeWantToRunILLink.cs
index 9722cd14b919..2a038cb9a679 100644
--- a/test/Microsoft.NET.Publish.Tests/GivenThatWeWantToRunILLink.cs
+++ b/test/Microsoft.NET.Publish.Tests/GivenThatWeWantToRunILLink.cs
@@ -1662,8 +1662,14 @@ public void ILLink_can_treat_warnings_as_errors_independently(string targetFrame
.And.NotHaveStdOutContaining("error IL2075");
}
+ ///
+ /// The reason we test this on net7 and below is because in net8 _IsPublishing was added which changes
+ /// the RID-defaulting behavior such that 8+ apps are not 'portable apps' when published for configurations that
+ /// require a RID (self-contained, or trimmed).
+ ///
+ ///
[RequiresMSBuildVersionTheory("17.0.0.32901")]
- [MemberData(nameof(SupportedTfms), MemberType = typeof(PublishTestUtils))]
+ [MemberData(nameof(TFMsThatDoNotInferPublishSelfContained), MemberType = typeof(PublishTestUtils))]
public void ILLink_error_on_portable_app(string targetFramework)
{
var projectName = "HelloWorld";
diff --git a/test/Microsoft.NET.Publish.Tests/PublishTestUtils.cs b/test/Microsoft.NET.Publish.Tests/PublishTestUtils.cs
index 53eb3fa79d4b..cadaff949c57 100644
--- a/test/Microsoft.NET.Publish.Tests/PublishTestUtils.cs
+++ b/test/Microsoft.NET.Publish.Tests/PublishTestUtils.cs
@@ -9,6 +9,9 @@ internal static class PublishTestUtils
{
#if NET10_0
+ ///
+ /// This list should contain the TFMs that we're interested in validating publishing support for
+ ///
public static IEnumerable