diff --git a/eng/restore-toolset.sh b/eng/restore-toolset.sh index 9c1d80d7d28e..bc6f17b927e4 100644 --- a/eng/restore-toolset.sh +++ b/eng/restore-toolset.sh @@ -15,6 +15,8 @@ function InitializeCustomSDKToolset { InstallDotNetSharedFramework "2.1.0" InstallDotNetSharedFramework "2.2.8" InstallDotNetSharedFramework "3.1.0" + + CreateBuildEnvScript } # Installs additional shared frameworks for testing purposes @@ -37,4 +39,22 @@ function InstallDotNetSharedFramework { fi } +function CreateBuildEnvScript { + mkdir -p $artifacts_dir + scriptPath="$artifacts_dir/sdk-build-env.sh" + scriptContents=" +#!/bin/bash +export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 +export DOTNET_MULTILEVEL_LOOKUP=0 + +export DOTNET_ROOT=$DOTNET_INSTALL_DIR +export DOTNET_MSBUILD_SDK_RESOLVER_CLI_DIR=$DOTNET_INSTALL_DIR + +export PATH=$DOTNET_INSTALL_DIR:\$PATH +export NUGET_PACKAGES=$NUGET_PACKAGES +" + + echo "$scriptContents" > ${scriptPath} +} + InitializeCustomSDKToolset diff --git a/src/Tasks/Common/MetadataKeys.cs b/src/Tasks/Common/MetadataKeys.cs index 1094ed793725..8422b77f5cc7 100644 --- a/src/Tasks/Common/MetadataKeys.cs +++ b/src/Tasks/Common/MetadataKeys.cs @@ -32,6 +32,7 @@ internal static class MetadataKeys public const string OriginalItemSpec = "OriginalItemSpec"; public const string SDKRootFolder = "SDKRootFolder"; public const string ShimRuntimeIdentifier = "ShimRuntimeIdentifier"; + public const string RuntimePackAlwaysCopyLocal = "RuntimePackAlwaysCopyLocal"; // Foreign Keys public const string ParentTarget = "ParentTarget"; diff --git a/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/GivenAGenerateRuntimeConfigurationFiles.cs b/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/GivenAGenerateRuntimeConfigurationFiles.cs index a3426a2dc87f..cf6dd6d337f4 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/GivenAGenerateRuntimeConfigurationFiles.cs +++ b/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/GivenAGenerateRuntimeConfigurationFiles.cs @@ -2,11 +2,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; -using System.Collections; using System.Collections.Generic; using System.IO; using FluentAssertions; -using Microsoft.Build.Framework; using Xunit; namespace Microsoft.NET.Build.Tasks.UnitTests @@ -40,7 +38,7 @@ public void ItCanGenerateWithoutAssetFile() { var task = new TestableGenerateRuntimeConfigurationFiles { - BuildEngine = new MockBuildEngine4(), + BuildEngine = new MockNeverCacheBuildEngine4(), TargetFrameworkMoniker = ".NETCoreApp,Version=v3.0", TargetFramework = "netcoreapp3.0", RuntimeConfigPath = _runtimeConfigPath, @@ -82,7 +80,7 @@ public void Given3RuntimeFrameworksItCanGenerateWithoutAssetFile() { var task = new TestableGenerateRuntimeConfigurationFiles { - BuildEngine = new MockBuildEngine4(), + BuildEngine = new MockNeverCacheBuildEngine4(), TargetFrameworkMoniker = ".NETCoreApp,Version=v3.0", TargetFramework = "netcoreapp3.0", RuntimeConfigPath = _runtimeConfigPath, @@ -143,7 +141,7 @@ public void Given2RuntimeFrameworksItCanGenerateWithoutAssetFile() { var task = new TestableGenerateRuntimeConfigurationFiles { - BuildEngine = new MockBuildEngine4(), + BuildEngine = new MockNeverCacheBuildEngine4(), TargetFrameworkMoniker = ".NETCoreApp,Version=v3.0", TargetFramework = "netcoreapp3.0", RuntimeConfigPath = _runtimeConfigPath, @@ -194,55 +192,5 @@ public void PublicExecuteCore() base.ExecuteCore(); } } - - private class MockBuildEngine4 : MockBuildEngine, IBuildEngine4 - { - public bool IsRunningMultipleNodes => throw new NotImplementedException(); - - public bool BuildProjectFile(string projectFileName, string[] targetNames, IDictionary globalProperties, - IDictionary targetOutputs, string toolsVersion) - { - throw new NotImplementedException(); - } - - public BuildEngineResult BuildProjectFilesInParallel(string[] projectFileNames, string[] targetNames, - IDictionary[] globalProperties, IList[] removeGlobalProperties, string[] toolsVersion, - bool returnTargetOutputs) - { - throw new NotImplementedException(); - } - - public bool BuildProjectFilesInParallel(string[] projectFileNames, string[] targetNames, - IDictionary[] globalProperties, IDictionary[] targetOutputsPerProject, string[] toolsVersion, - bool useResultsCache, bool unloadProjectsOnCompletion) - { - throw new NotImplementedException(); - } - - public object GetRegisteredTaskObject(object key, RegisteredTaskObjectLifetime lifetime) - { - return null; - } - - public void Reacquire() - { - throw new NotImplementedException(); - } - - public void RegisterTaskObject(object key, object obj, RegisteredTaskObjectLifetime lifetime, - bool allowEarlyCollection) - { - } - - public object UnregisterTaskObject(object key, RegisteredTaskObjectLifetime lifetime) - { - throw new NotImplementedException(); - } - - public void Yield() - { - throw new NotImplementedException(); - } - } } } diff --git a/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/MockNeverCacheBuildEngine4.cs b/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/MockNeverCacheBuildEngine4.cs new file mode 100644 index 000000000000..dc6185d84e68 --- /dev/null +++ b/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/MockNeverCacheBuildEngine4.cs @@ -0,0 +1,60 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections; +using System.Collections.Generic; +using Microsoft.Build.Framework; + +namespace Microsoft.NET.Build.Tasks.UnitTests +{ + internal class MockNeverCacheBuildEngine4 : MockBuildEngine, IBuildEngine4 + { + public bool IsRunningMultipleNodes => throw new NotImplementedException(); + + public bool BuildProjectFile(string projectFileName, string[] targetNames, IDictionary globalProperties, + IDictionary targetOutputs, string toolsVersion) + { + throw new NotImplementedException(); + } + + public BuildEngineResult BuildProjectFilesInParallel(string[] projectFileNames, string[] targetNames, + IDictionary[] globalProperties, IList[] removeGlobalProperties, string[] toolsVersion, + bool returnTargetOutputs) + { + throw new NotImplementedException(); + } + + public bool BuildProjectFilesInParallel(string[] projectFileNames, string[] targetNames, + IDictionary[] globalProperties, IDictionary[] targetOutputsPerProject, string[] toolsVersion, + bool useResultsCache, bool unloadProjectsOnCompletion) + { + throw new NotImplementedException(); + } + + public object GetRegisteredTaskObject(object key, RegisteredTaskObjectLifetime lifetime) + { + return null; + } + + public void Reacquire() + { + throw new NotImplementedException(); + } + + public void RegisterTaskObject(object key, object obj, RegisteredTaskObjectLifetime lifetime, + bool allowEarlyCollection) + { + } + + public object UnregisterTaskObject(object key, RegisteredTaskObjectLifetime lifetime) + { + throw new NotImplementedException(); + } + + public void Yield() + { + throw new NotImplementedException(); + } + } +} diff --git a/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/Mocks/MockTaskItem.cs b/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/Mocks/MockTaskItem.cs index ad926d93e04a..eec69e9f15a3 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/Mocks/MockTaskItem.cs +++ b/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/Mocks/MockTaskItem.cs @@ -50,7 +50,10 @@ public IDictionary CloneCustomMetadata() public void CopyMetadataTo(ITaskItem destinationItem) { - throw new NotImplementedException(); + foreach (var kv in _metadata) + { + destinationItem.SetMetadata(kv.Key, kv.Value); + } } public string GetMetadata(string metadataName) diff --git a/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/ProcessFrameworkReferencesTests.cs b/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/ProcessFrameworkReferencesTests.cs index a734b32cad47..bd05d14a325c 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/ProcessFrameworkReferencesTests.cs +++ b/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/ProcessFrameworkReferencesTests.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.IO; -using System.Text; +using System.Linq; using FluentAssertions; using Xunit; @@ -9,6 +9,37 @@ namespace Microsoft.NET.Build.Tasks.UnitTests { public class ProcessFrameworkReferencesTests { + private MockTaskItem _validWindowsSDKKnownFrameworkReference + = new MockTaskItem("Microsoft.Windows.SDK.NET.Ref", + new Dictionary + { + {"TargetFramework", "net5.0-windows10.0.18362"}, + {"RuntimeFrameworkName", "Microsoft.Windows.SDK.NET.Ref"}, + {"DefaultRuntimeFrameworkVersion", "10.0.18362.1-preview"}, + {"LatestRuntimeFrameworkVersion", "10.0.18362.1-preview"}, + {"TargetingPackName", "Microsoft.Windows.SDK.NET.Ref"}, + {"TargetingPackVersion", "10.0.18362.1-preview"}, + {"RuntimePackNamePatterns", "Microsoft.Windows.SDK.NET.Ref"}, + {"RuntimePackRuntimeIdentifiers", "any"}, + {MetadataKeys.RuntimePackAlwaysCopyLocal, "true"}, + {"IsWindowsOnly", "true"}, + }); + + + private MockTaskItem _netcoreAppKnownFrameworkReference = + new MockTaskItem("Microsoft.NETCore.App", + new Dictionary + { + {"TargetFramework", "net5.0"}, + {"RuntimeFrameworkName", "Microsoft.NETCore.App"}, + {"DefaultRuntimeFrameworkVersion", "5.0.0-preview.4.20251.6"}, + {"LatestRuntimeFrameworkVersion", "5.0.0-preview.4.20251.6"}, + {"TargetingPackName", "Microsoft.NETCore.App.Ref"}, + {"TargetingPackVersion", "5.0.0-preview.4.20251.6"}, + {"RuntimePackNamePatterns", "Microsoft.NETCore.App.Runtime.**RID**"}, + {"RuntimePackRuntimeIdentifiers", "win-x64"}, + }); + [Fact] public void It_resolves_FrameworkReferences() { @@ -27,12 +58,50 @@ public void It_resolves_FrameworkReferences() new MockTaskItem("Microsoft.AspNetCore.App", new Dictionary() { - { "TargetFramework", "netcoreapp3.0" }, - { "RuntimeFrameworkName", "Microsoft.AspNetCore.App" }, - { "DefaultRuntimeFrameworkVersion", "1.9.5" }, - { "LatestRuntimeFrameworkVersion", "1.9.6" }, - { "TargetingPackName", "Microsoft.AspNetCore.App" }, - { "TargetingPackVersion", "1.9.0" } + {"TargetFramework", "netcoreapp3.0"}, + {"RuntimeFrameworkName", "Microsoft.AspNetCore.App"}, + {"DefaultRuntimeFrameworkVersion", "1.9.5"}, + {"LatestRuntimeFrameworkVersion", "1.9.6"}, + {"TargetingPackName", "Microsoft.AspNetCore.App"}, + {"TargetingPackVersion", "1.9.0"} + }) + }; + + task.Execute().Should().BeTrue(); + + task.PackagesToDownload.Length.Should().Be(1); + + task.RuntimeFrameworks.Length.Should().Be(1); + task.RuntimeFrameworks[0].ItemSpec.Should().Be("Microsoft.AspNetCore.App"); + task.RuntimeFrameworks[0].GetMetadata(MetadataKeys.Version).Should().Be("1.9.5"); + } + + [Fact] + public void Given_targetPlatform_and_targetPlatform_version_It_resolves_FrameworkReferences_() + { + var task = new ProcessFrameworkReferences(); + + task.EnableTargetingPackDownload = true; + task.TargetFrameworkIdentifier = ".NETCoreApp"; + task.TargetFrameworkVersion = "3.0"; + task.TargetPlatformIdentifier = "Windows"; + task.TargetPlatformVersion = "10.0.18362"; + task.FrameworkReferences = new[] + { + new MockTaskItem("Microsoft.AspNetCore.App", new Dictionary()) + }; + + task.KnownFrameworkReferences = new[] + { + new MockTaskItem("Microsoft.AspNetCore.App", + new Dictionary() + { + {"TargetFramework", "netcoreapp3.0"}, + {"RuntimeFrameworkName", "Microsoft.AspNetCore.App"}, + {"DefaultRuntimeFrameworkVersion", "1.9.5"}, + {"LatestRuntimeFrameworkVersion", "1.9.6"}, + {"TargetingPackName", "Microsoft.AspNetCore.App"}, + {"TargetingPackVersion", "1.9.0"} }) }; @@ -62,12 +131,12 @@ public void It_does_not_resolve_FrameworkReferences_if_targetframework_doesnt_ma new MockTaskItem("Microsoft.AspNetCore.App", new Dictionary() { - { "TargetFramework", "netcoreapp3.0" }, - { "RuntimeFrameworkName", "Microsoft.AspNetCore.App" }, - { "DefaultRuntimeFrameworkVersion", "1.9.5" }, - { "LatestRuntimeFrameworkVersion", "1.9.6" }, - { "TargetingPackName", "Microsoft.AspNetCore.App" }, - { "TargetingPackVersion", "1.9.0" } + {"TargetFramework", "netcoreapp3.0"}, + {"RuntimeFrameworkName", "Microsoft.AspNetCore.App"}, + {"DefaultRuntimeFrameworkVersion", "1.9.5"}, + {"LatestRuntimeFrameworkVersion", "1.9.6"}, + {"TargetingPackName", "Microsoft.AspNetCore.App"}, + {"TargetingPackVersion", "1.9.0"} }) }; @@ -76,5 +145,177 @@ public void It_does_not_resolve_FrameworkReferences_if_targetframework_doesnt_ma task.PackagesToDownload.Should().BeNull(); task.RuntimeFrameworks.Should().BeNull(); } + + [Fact] + public void Given_KnownFrameworkReferences_with_RuntimePackAlwaysCopyLocal_It_resolves_FrameworkReferences() + { + const string minimalRuntimeGraphPathContent = + "{\"runtimes\":{\"any\":{\"#import\":[\"base\"]},\"base\":{\"#import\":[]}}}"; + var runtimeGraphPathPath = Path.GetTempFileName(); + File.WriteAllText(runtimeGraphPathPath, minimalRuntimeGraphPathContent); + + var task = new ProcessFrameworkReferences + { + BuildEngine = new MockNeverCacheBuildEngine4(), + EnableTargetingPackDownload = true, + TargetFrameworkIdentifier = ".NETCoreApp", + TargetFrameworkVersion = "5.0", + TargetPlatformIdentifier = "Windows", + TargetPlatformVersion = "10.0.18362", + RuntimeGraphPath = + runtimeGraphPathPath, + FrameworkReferences = + new[] {new MockTaskItem("Microsoft.Windows.SDK.NET.Ref", new Dictionary())}, + KnownFrameworkReferences = new[] + { + new MockTaskItem("Microsoft.Windows.SDK.NET.Ref", + new Dictionary + { + {"TargetFramework", "net5.0-windows10.0.17760"}, + {"RuntimeFrameworkName", "Microsoft.Windows.SDK.NET.Ref"}, + {"DefaultRuntimeFrameworkVersion", "10.0.17760.1-preview"}, + {"LatestRuntimeFrameworkVersion", "10.0.17760.1-preview"}, + {"TargetingPackName", "Microsoft.Windows.SDK.NET.Ref"}, + {"TargetingPackVersion", "10.0.17760.1-preview"}, + {"RuntimePackNamePatterns", "Microsoft.Windows.SDK.NET.Ref"}, + {"RuntimePackRuntimeIdentifiers", "any"}, + {MetadataKeys.RuntimePackAlwaysCopyLocal, "true"}, + {"IsWindowsOnly", "true"}, + }), + _validWindowsSDKKnownFrameworkReference, + } + }; + + if (Environment.OSVersion.Platform != PlatformID.Win32NT) + { + task.Execute().Should().BeFalse("IsWindowsOnly=true"); + return; + } + + task.Execute().Should().BeTrue(); + + task.PackagesToDownload.Length.Should().Be(1); + + task.RuntimeFrameworks.Should().BeNullOrEmpty( + "Should not contain RuntimePackAlwaysCopyLocal framework, or it will be put into runtimeconfig.json"); + + task.TargetingPacks.Length.Should().Be(1); + task.TargetingPacks[0].ItemSpec.Should().Be("Microsoft.Windows.SDK.NET.Ref"); + task.TargetingPacks[0].GetMetadata(MetadataKeys.NuGetPackageId).Should() + .Be("Microsoft.Windows.SDK.NET.Ref"); + task.TargetingPacks[0].GetMetadata(MetadataKeys.NuGetPackageVersion).Should().Be("10.0.18362.1-preview"); + task.TargetingPacks[0].GetMetadata(MetadataKeys.PackageConflictPreferredPackages).Should() + .Be("Microsoft.Windows.SDK.NET.Ref"); + task.TargetingPacks[0].GetMetadata(MetadataKeys.RuntimeFrameworkName).Should() + .Be("Microsoft.Windows.SDK.NET.Ref"); + task.TargetingPacks[0].GetMetadata(MetadataKeys.RuntimeIdentifier).Should().Be(""); + + task.RuntimePacks.Length.Should().Be(1); + task.RuntimePacks[0].ItemSpec.Should().Be("Microsoft.Windows.SDK.NET.Ref"); + task.RuntimePacks[0].GetMetadata(MetadataKeys.FrameworkName).Should().Be("Microsoft.Windows.SDK.NET.Ref"); + task.RuntimePacks[0].GetMetadata(MetadataKeys.NuGetPackageVersion).Should().Be("10.0.18362.1-preview"); + task.RuntimePacks[0].GetMetadata(MetadataKeys.RuntimePackAlwaysCopyLocal).Should().Be("true"); + } + + [Fact] + public void It_resolves_self_contained_FrameworkReferences_to_download() + { + const string minimalRuntimeGraphPathContent = + "{\"runtimes\":{\"any\":{\"#import\":[\"base\"]},\"base\":{\"#import\":[]},\"win\":{\"#import\":[\"any\"]},\"win-x64\":{\"#import\":[\"win\"]}}}"; + var runtimeGraphPathPath = Path.GetTempFileName(); + File.WriteAllText(runtimeGraphPathPath, minimalRuntimeGraphPathContent); + + var task = new ProcessFrameworkReferences + { + BuildEngine = new MockNeverCacheBuildEngine4(), + EnableTargetingPackDownload = true, + TargetFrameworkIdentifier = ".NETCoreApp", + TargetFrameworkVersion = "5.0", + TargetPlatformIdentifier = "Windows", + TargetPlatformVersion = "10.0.18362", + NETCoreSdkRuntimeIdentifier = "win-x64", + RuntimeIdentifier = "win-x64", + RuntimeGraphPath = + runtimeGraphPathPath, + SelfContained = true, + TargetLatestRuntimePatch = true, + TargetLatestRuntimePatchIsDefault = true, + FrameworkReferences = + new[] + { + new MockTaskItem("Microsoft.NETCore.App", new Dictionary()), + new MockTaskItem("Microsoft.Windows.SDK.NET.Ref", new Dictionary()) + }, + KnownFrameworkReferences = new[] + { + _netcoreAppKnownFrameworkReference, _validWindowsSDKKnownFrameworkReference, + } + }; + if (Environment.OSVersion.Platform == PlatformID.Win32NT) + { + task.Execute().Should().BeTrue(); + + task.PackagesToDownload.Length.Should().Be(3); + task.PackagesToDownload.Should().Contain(p => p.ItemSpec == "Microsoft.Windows.SDK.NET.Ref"); + task.PackagesToDownload.Should().Contain(p => p.ItemSpec == "Microsoft.NETCore.App.Ref"); + task.PackagesToDownload.Should().Contain(p => p.ItemSpec == "Microsoft.NETCore.App.Runtime.win-x64"); + } + else + { + task.Execute().Should().BeFalse("IsWindowsOnly=true"); + } + } + + [Fact] + public void Given_reference_to_NETCoreApp_It_should_not_resolve_runtime_pack() + { + const string minimalRuntimeGraphPathContent = + "{\"runtimes\":{\"any\":{\"#import\":[\"base\"]},\"base\":{\"#import\":[]},\"win\":{\"#import\":[\"any\"]},\"win-x64\":{\"#import\":[\"win\"]}}}"; + var runtimeGraphPathPath = Path.GetTempFileName(); + File.WriteAllText(runtimeGraphPathPath, minimalRuntimeGraphPathContent); + + var task = new ProcessFrameworkReferences + { + BuildEngine = new MockNeverCacheBuildEngine4(), + EnableTargetingPackDownload = true, + TargetFrameworkIdentifier = ".NETCoreApp", + TargetFrameworkVersion = "5.0", + TargetPlatformIdentifier = "Windows", + TargetPlatformVersion = "10.0.18362", + NETCoreSdkRuntimeIdentifier = "win-x64", + RuntimeGraphPath = + runtimeGraphPathPath, + TargetLatestRuntimePatch = true, + TargetLatestRuntimePatchIsDefault = true, + FrameworkReferences = + new[] + { + new MockTaskItem("Microsoft.NETCore.App", new Dictionary()), + new MockTaskItem("Microsoft.Windows.SDK.NET.Ref", new Dictionary()) + }, + KnownFrameworkReferences = new[] + { + _netcoreAppKnownFrameworkReference, _validWindowsSDKKnownFrameworkReference, + } + }; + + if (Environment.OSVersion.Platform != PlatformID.Win32NT) + { + task.Execute().Should().BeFalse("IsWindowsOnly=true"); + return; + } + + task.Execute().Should().BeTrue(); + + task.TargetingPacks.Length.Should().Be(2); + task.TargetingPacks.Should().Contain(p => + p.GetMetadata(MetadataKeys.NuGetPackageId) == "Microsoft.Windows.SDK.NET.Ref"); + task.TargetingPacks.Should() + .Contain(p => p.GetMetadata(MetadataKeys.NuGetPackageId) == "Microsoft.NETCore.App.Ref"); + + task.RuntimePacks.Length.Should().Be(1); + task.RuntimePacks[0].ItemSpec.Should().Be("Microsoft.Windows.SDK.NET.Ref", + "it should not resolve runtime pack for Microsoft.NETCore.App"); + } } } diff --git a/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/ResolveTargetingPackAssetsTests.cs b/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/ResolveTargetingPackAssetsTests.cs new file mode 100644 index 000000000000..2acc9a23df23 --- /dev/null +++ b/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/ResolveTargetingPackAssetsTests.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using FluentAssertions; +using Xunit; + +namespace Microsoft.NET.Build.Tasks.UnitTests +{ + public class ResolveTargetingPackAssetsTests + { + [Fact] + public void Given_ResolvedTargetingPacks_with_valid_PATH_in_PlatformManifest_It_resolves_TargetingPack() + { + string mockPackageDirectory = Path.Combine(Path.GetTempPath(), "dotnetSdkTests", Path.GetRandomFileName()); + + string dataDir = Path.Combine(mockPackageDirectory, "data"); + Directory.CreateDirectory(dataDir); + + File.WriteAllText(Path.Combine(dataDir, "FrameworkList.xml"), _frameworkList); + File.WriteAllText(Path.Combine(dataDir, "PlatformManifest.txt"), ""); + + var task = new ResolveTargetingPackAssets(); + + task.FrameworkReferences = new[] + { + new MockTaskItem("Microsoft.Windows.SDK.NET.Ref", new Dictionary()) + }; + + task.ResolvedTargetingPacks = new[] + { + new MockTaskItem("Microsoft.Windows.SDK.NET.Ref", + new Dictionary() + { + {MetadataKeys.NuGetPackageId, "Microsoft.Windows.SDK.NET.Ref"}, + {MetadataKeys.NuGetPackageVersion, "5.0.0-preview1"}, + {MetadataKeys.PackageConflictPreferredPackages, "Microsoft.Windows.SDK.NET.Ref;"}, + {MetadataKeys.PackageDirectory, mockPackageDirectory}, + {MetadataKeys.Path, mockPackageDirectory}, + {"TargetFramework", "net5.0"} + }) + }; + + task.Execute().Should().BeTrue(); + + task.ReferencesToAdd[0].ItemSpec.Should().Be(Path.Combine(mockPackageDirectory, "lib/Microsoft.Windows.SDK.NET.dll")); + task.PlatformManifests[0].ItemSpec.Should().Be(Path.Combine(mockPackageDirectory, $"data{Path.DirectorySeparatorChar}PlatformManifest.txt")); + } + + private readonly string _frameworkList = + " "; + } +} diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/GenerateDepsFile.cs b/src/Tasks/Microsoft.NET.Build.Tasks/GenerateDepsFile.cs index 277fcb28532d..04ac5a087d5a 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/GenerateDepsFile.cs +++ b/src/Tasks/Microsoft.NET.Build.Tasks/GenerateDepsFile.cs @@ -168,13 +168,28 @@ private void WriteDepsFile(string depsFilePath) ReferenceInfo.CreateDependencyReferenceInfos(ReferenceDependencyPaths, ReferenceSatellitePaths, isUserRuntimeAssembly); Dictionary referenceProjects = - SingleProjectInfo.CreateProjectReferenceInfos(ReferencePaths, ReferenceSatellitePaths, isUserRuntimeAssembly); + SingleProjectInfo.CreateProjectReferenceInfos(ReferencePaths, ReferenceSatellitePaths, + isUserRuntimeAssembly); + + bool ShouldIncludeRuntimeAsset(ITaskItem item) + { + if (IsSelfContained) + { + if (!IsSingleFile || !item.GetMetadata(MetadataKeys.DropFromSingleFile).Equals("true")) + { + return true; + } + } + else if (item.HasMetadataValue(MetadataKeys.RuntimePackAlwaysCopyLocal, "true")) + { + return true; + } + + return false; + } IEnumerable runtimePackAssets = - IsSelfContained ? - RuntimePackAssets.Where(item => !IsSingleFile || !item.GetMetadata(MetadataKeys.DropFromSingleFile).Equals("true")) - .Select(item => RuntimePackAssetInfo.FromItem(item)) : - Enumerable.Empty(); + RuntimePackAssets.Where(ShouldIncludeRuntimeAsset).Select(RuntimePackAssetInfo.FromItem); DependencyContextBuilder builder; if (projectContext != null) diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/ProcessFrameworkReferences.cs b/src/Tasks/Microsoft.NET.Build.Tasks/ProcessFrameworkReferences.cs index 19c9670a2192..a6697c8dbe83 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/ProcessFrameworkReferences.cs +++ b/src/Tasks/Microsoft.NET.Build.Tasks/ProcessFrameworkReferences.cs @@ -6,6 +6,7 @@ using System.IO; using System.Linq; using System.Runtime.InteropServices; +using System.Text.RegularExpressions; using Microsoft.Build.Framework; using Microsoft.Build.Utilities; using Newtonsoft.Json; @@ -24,6 +25,10 @@ public class ProcessFrameworkReferences : TaskBase public string TargetFrameworkVersion { get; set; } + public string TargetPlatformIdentifier { get; set; } + + public string TargetPlatformVersion { get; set; } + public string TargetingPackRoot { get; set; } [Required] @@ -77,6 +82,8 @@ public class ProcessFrameworkReferences : TaskBase [Output] public ITaskItem[] UnavailableRuntimePacks { get; set; } + private Version _normalizedTargetFrameworkVersion; + protected override void ExecuteCore() { // Perf optimization: If there are no FrameworkReference items, then don't do anything @@ -86,17 +93,18 @@ protected override void ExecuteCore() return; } - var normalizedTargetFrameworkVersion = NormalizeVersion(new Version(TargetFrameworkVersion)); + _normalizedTargetFrameworkVersion = NormalizeVersion(new Version(TargetFrameworkVersion)); - var knownFrameworkReferencesForTargetFramework = KnownFrameworkReferences.Select(item => new KnownFrameworkReference(item)) - .Where(kfr => kfr.TargetFramework.Framework.Equals(TargetFrameworkIdentifier, StringComparison.OrdinalIgnoreCase) && - NormalizeVersion(kfr.TargetFramework.Version) == normalizedTargetFrameworkVersion) - .ToList(); + var knownFrameworkReferencesForTargetFramework = + KnownFrameworkReferences + .Select(item => new KnownFrameworkReference(item)) + .Where(KnownFrameworkReferenceAppliesToTargetFramework) + .ToList(); // Get known runtime packs from known framework references. // Only use items where the framework reference name matches the RuntimeFrameworkName. // This will filter out known framework references for "profiles", ie WindowsForms and WPF - var knownRuntimePacksForTargetFramework = + var knownRuntimePacksForTargetFramework = knownFrameworkReferencesForTargetFramework .Where(kfr => kfr.Name.Equals(kfr.RuntimeFrameworkName, StringComparison.OrdinalIgnoreCase)) .Select(kfr => kfr.ToKnownRuntimePack()) @@ -106,7 +114,7 @@ protected override void ExecuteCore() knownRuntimePacksForTargetFramework.AddRange( KnownRuntimePacks.Select(item => new KnownRuntimePack(item)) .Where(krp => krp.TargetFramework.Framework.Equals(TargetFrameworkIdentifier, StringComparison.OrdinalIgnoreCase) && - NormalizeVersion(krp.TargetFramework.Version) == normalizedTargetFrameworkVersion)); + NormalizeVersion(krp.TargetFramework.Version) == _normalizedTargetFrameworkVersion)); var frameworkReferenceMap = FrameworkReferences.ToDictionary(fr => fr.ItemSpec, StringComparer.OrdinalIgnoreCase); @@ -142,7 +150,7 @@ protected override void ExecuteCore() // Add targeting pack and all known runtime packs to "preferred packages" list. // These are packages that will win in conflict resolution for assets that have identical assembly and file versions - List preferredPackages = new List(); + var preferredPackages = new HashSet(StringComparer.InvariantCultureIgnoreCase); preferredPackages.Add(knownFrameworkReference.TargetingPackName); if (selectedRuntimePack != null) @@ -157,7 +165,7 @@ protected override void ExecuteCore() } } } - + TaskItem targetingPack = new TaskItem(knownFrameworkReference.Name); targetingPack.SetMetadata(MetadataKeys.NuGetPackageId, knownFrameworkReference.TargetingPackName); targetingPack.SetMetadata(MetadataKeys.PackageConflictPreferredPackages, string.Join(";", preferredPackages)); @@ -213,7 +221,7 @@ protected override void ExecuteCore() targetingPacks.Add(targetingPack); var runtimeFrameworkVersion = GetRuntimeFrameworkVersion( - frameworkReference, + frameworkReference, knownFrameworkReference, selectedRuntimePack, out string runtimePackVersion); @@ -253,12 +261,16 @@ protected override void ExecuteCore() bool processedPrimaryRuntimeIdentifier = false; - if ((SelfContained || ReadyToRunEnabled) && - !string.IsNullOrEmpty(RuntimeIdentifier) && - selectedRuntimePack != null && - !string.IsNullOrEmpty(selectedRuntimePack?.RuntimePackNamePatterns)) - { + var hasRuntimePackAlwaysCopyLocal = + selectedRuntimePack != null && selectedRuntimePack.Value.RuntimePackAlwaysCopyLocal; + var runtimeRequiredByDeployment + = (SelfContained || ReadyToRunEnabled) && + !string.IsNullOrEmpty(RuntimeIdentifier) && + selectedRuntimePack != null && + !string.IsNullOrEmpty(selectedRuntimePack.Value.RuntimePackNamePatterns); + if (hasRuntimePackAlwaysCopyLocal || runtimeRequiredByDeployment) + { // Find other KnownFrameworkReferences that map to the same runtime pack, if any List additionalFrameworkReferencesForRuntimePack = null; foreach (var additionalKnownFrameworkReference in knownFrameworkReferencesForTargetFramework) @@ -274,7 +286,7 @@ protected override void ExecuteCore() } } - ProcessRuntimeIdentifier(RuntimeIdentifier, runtimePackForRuntimeIDProcessing, runtimePackVersion, additionalFrameworkReferencesForRuntimePack, + ProcessRuntimeIdentifier(hasRuntimePackAlwaysCopyLocal ? "any" : RuntimeIdentifier, runtimePackForRuntimeIDProcessing, runtimePackVersion, additionalFrameworkReferencesForRuntimePack, unrecognizedRuntimeIdentifiers, unavailableRuntimePacks, runtimePacks, packagesToDownload, isTrimmable, includeInPackageDownload); processedPrimaryRuntimeIdentifier = true; @@ -297,7 +309,7 @@ protected override void ExecuteCore() } } - if (!string.IsNullOrEmpty(knownFrameworkReference.RuntimeFrameworkName)) + if (!string.IsNullOrEmpty(knownFrameworkReference.RuntimeFrameworkName) && !knownFrameworkReference.RuntimePackAlwaysCopyLocal) { TaskItem runtimeFramework = new TaskItem(knownFrameworkReference.RuntimeFrameworkName); @@ -315,7 +327,7 @@ protected override void ExecuteCore() Log.LogError(Strings.Crossgen2RequiresSelfContained); return; } - if (!AddCrossgen2Package(normalizedTargetFrameworkVersion, packagesToDownload)) + if (!AddCrossgen2Package(_normalizedTargetFrameworkVersion, packagesToDownload)) { Log.LogError(Strings.ReadyToRunNoValidRuntimePackageError); return; @@ -324,7 +336,7 @@ protected override void ExecuteCore() if (packagesToDownload.Any()) { - PackagesToDownload = packagesToDownload.ToArray(); + PackagesToDownload = packagesToDownload.Distinct(new PackageToDownloadComparer()).ToArray(); } if (runtimeFrameworks.Any()) @@ -348,6 +360,27 @@ protected override void ExecuteCore() } } + private bool KnownFrameworkReferenceAppliesToTargetFramework(KnownFrameworkReference kfr) + { + if (!kfr.TargetFramework.Framework.Equals(TargetFrameworkIdentifier, StringComparison.OrdinalIgnoreCase) + || NormalizeVersion(kfr.TargetFramework.Version) != _normalizedTargetFrameworkVersion) + { + return false; + } + + if (!string.IsNullOrEmpty(kfr.TargetFramework.Platform) + && !string.IsNullOrEmpty(kfr.TargetFramework.PlatformVersion)) + { + if (!kfr.TargetFramework.PlatformVersion.Equals(TargetPlatformVersion, StringComparison.OrdinalIgnoreCase) + || NormalizeVersion(kfr.TargetFramework.Version) != _normalizedTargetFrameworkVersion) + { + return false; + } + } + + return true; + } + private KnownRuntimePack? SelectRuntimePack(ITaskItem frameworkReference, KnownFrameworkReference knownFrameworkReference, List knownRuntimePacks) { var requiredLabelsMetadata = frameworkReference?.GetMetadata(MetadataKeys.RuntimePackLabels) ?? ""; @@ -355,7 +388,7 @@ protected override void ExecuteCore() HashSet requiredRuntimePackLabels = null; if (frameworkReference != null) { - requiredRuntimePackLabels = new HashSet(requiredLabelsMetadata.Split(new [] { ';' }, StringSplitOptions.RemoveEmptyEntries), StringComparer.OrdinalIgnoreCase); + requiredRuntimePackLabels = new HashSet(requiredLabelsMetadata.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries), StringComparer.OrdinalIgnoreCase); } // The runtime pack name matches the RuntimeFrameworkName on the KnownFrameworkReference @@ -402,7 +435,7 @@ private void ProcessRuntimeIdentifier( List unavailableRuntimePacks, List runtimePacks, List packagesToDownload, - string isTrimmable, + string isTrimmable, bool addToPackageDownload) { var runtimeGraph = new RuntimeGraphCache(this).GetRuntimeGraph(RuntimeGraphPath); @@ -449,6 +482,11 @@ private void ProcessRuntimeIdentifier( runtimePackItem.SetMetadata(MetadataKeys.RuntimeIdentifier, runtimePackRuntimeIdentifier); runtimePackItem.SetMetadata(MetadataKeys.IsTrimmable, isTrimmable); + if (selectedRuntimePack.RuntimePackAlwaysCopyLocal) + { + runtimePackItem.SetMetadata(MetadataKeys.RuntimePackAlwaysCopyLocal, "true"); + } + if (additionalFrameworkReferencesForRuntimePack != null) { runtimePackItem.SetMetadata(MetadataKeys.AdditionalFrameworkReferences, string.Join(";", additionalFrameworkReferencesForRuntimePack)); @@ -510,7 +548,7 @@ private bool AddCrossgen2Package(Version normalizedTargetFrameworkVersion, List< } private string GetRuntimeFrameworkVersion( - ITaskItem frameworkReference, + ITaskItem frameworkReference, KnownFrameworkReference knownFrameworkReference, KnownRuntimePack? knownRuntimePack, out string runtimePackVersion) @@ -572,6 +610,34 @@ private enum RuntimePatchRequest UseLatestVersion, } + /// + /// Compare PackageToDownload by name and version. + /// Used to deduplicate PackageToDownloads + /// + private class PackageToDownloadComparer : IEqualityComparer where T : ITaskItem + { + public bool Equals(T x, T y) + { + if (x is null || y is null) + { + return false; + } + + return x.ItemSpec.Equals(y.ItemSpec, + StringComparison.OrdinalIgnoreCase) && + x.GetMetadata(MetadataKeys.Version).Equals( + y.GetMetadata(MetadataKeys.Version), StringComparison.OrdinalIgnoreCase); + } + + public int GetHashCode(T obj) + { + var hashCode = -1923861349; + hashCode = hashCode * -1521134295 + obj.ItemSpec.GetHashCode(); + hashCode = hashCode * -1521134295 + obj.GetMetadata(MetadataKeys.Version).GetHashCode(); + return hashCode; + } + } + private RuntimePatchRequest GetRuntimePatchRequest(ITaskItem frameworkReference) { string value = frameworkReference?.GetMetadata("TargetLatestRuntimePatch"); @@ -627,7 +693,7 @@ private struct KnownFrameworkReference public KnownFrameworkReference(ITaskItem item) { _item = item; - TargetFramework = NuGetFramework.Parse(item.GetMetadata("TargetFramework")); + TargetFramework = new NuGetFrameworkTemp(item.GetMetadata("TargetFramework")); } // The name / itemspec of the FrameworkReference used in the project @@ -645,10 +711,13 @@ public KnownFrameworkReference(ITaskItem item) public string RuntimePackRuntimeIdentifiers => _item.GetMetadata(MetadataKeys.RuntimePackRuntimeIdentifiers); public bool IsWindowsOnly => _item.HasMetadataValue("IsWindowsOnly", "true"); + + public bool RuntimePackAlwaysCopyLocal => + _item.HasMetadataValue(MetadataKeys.RuntimePackAlwaysCopyLocal, "true"); public string Profile => _item.GetMetadata("Profile"); - public NuGetFramework TargetFramework { get; } + public NuGetFrameworkTemp TargetFramework { get; } public KnownRuntimePack ToKnownRuntimePack() { @@ -656,6 +725,42 @@ public KnownRuntimePack ToKnownRuntimePack() } } + // TODO replace with the proper impl from nuget + internal class NuGetFrameworkTemp + { + public NuGetFrameworkTemp(string targetFramework) + { + Match match = Regex.Match(targetFramework, "([^-]+)"); + var beforeDash = match.Value; + + var nuGetFramework = NuGetFramework.Parse(beforeDash); + Framework = nuGetFramework.Framework; + Version = nuGetFramework.Version; + ShortFolderName = nuGetFramework.GetShortFolderName(); + + if (beforeDash != targetFramework) + { + var afterDash = targetFramework.Substring(match.Length + 1); + Match matchPlatform = Regex.Match(afterDash, "^[A-Za-z]+"); + Platform = matchPlatform.Value; + PlatformVersion = afterDash.Substring(matchPlatform.Length); + } + } + + public string Framework { get; } + public Version Version { get; } + public string Platform { get; } + + public string PlatformVersion { get; } + + private string ShortFolderName { get; } + + public string GetShortFolderName() + { + return ShortFolderName; + } + } + private struct KnownRuntimePack { ITaskItem _item; @@ -689,7 +794,10 @@ public KnownRuntimePack(ITaskItem item) public bool IsWindowsOnly => _item.HasMetadataValue("IsWindowsOnly", "true"); - public string [] RuntimePackLabels { get; } + public bool RuntimePackAlwaysCopyLocal => + _item.HasMetadataValue(MetadataKeys.RuntimePackAlwaysCopyLocal, "true"); + + public string[] RuntimePackLabels { get; } public NuGetFramework TargetFramework { get; } } diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/ResolveRuntimePackAssets.cs b/src/Tasks/Microsoft.NET.Build.Tasks/ResolveRuntimePackAssets.cs index d5f955eb0bc7..3411b1e3663e 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/ResolveRuntimePackAssets.cs +++ b/src/Tasks/Microsoft.NET.Build.Tasks/ResolveRuntimePackAssets.cs @@ -83,7 +83,9 @@ protected override void ExecuteCore() if (File.Exists(runtimeListPath)) { - AddRuntimePackAssetsFromManifest(runtimePackAssets, runtimePackRoot, runtimeListPath, runtimePack); + var runtimePackAlwaysCopyLocal = runtimePack.HasMetadataValue(MetadataKeys.RuntimePackAlwaysCopyLocal, "true"); + + AddRuntimePackAssetsFromManifest(runtimePackAssets, runtimePackRoot, runtimeListPath, runtimePack, runtimePackAlwaysCopyLocal); } else { @@ -95,7 +97,7 @@ protected override void ExecuteCore() } private void AddRuntimePackAssetsFromManifest(List runtimePackAssets, string runtimePackRoot, - string runtimeListPath, ITaskItem runtimePack) + string runtimeListPath, ITaskItem runtimePack, bool runtimePackAlwaysCopyLocal) { var assetSubPaths = new HashSet(StringComparer.OrdinalIgnoreCase); @@ -149,6 +151,10 @@ private void AddRuntimePackAssetsFromManifest(List runtimePackAssets, assetItem.SetMetadata("FileVersion", fileElement.Attribute("FileVersion")?.Value); assetItem.SetMetadata("PublicKeyToken", fileElement.Attribute("PublicKeyToken")?.Value); assetItem.SetMetadata("DropFromSingleFile", fileElement.Attribute("DropFromSingleFile")?.Value); + if (runtimePackAlwaysCopyLocal) + { + assetItem.SetMetadata(MetadataKeys.RuntimePackAlwaysCopyLocal, "true"); + } runtimePackAssets.Add(assetItem); } diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/ResolveTargetingPackAssets.cs b/src/Tasks/Microsoft.NET.Build.Tasks/ResolveTargetingPackAssets.cs index 211cb9c21f69..768f270113ed 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/ResolveTargetingPackAssets.cs +++ b/src/Tasks/Microsoft.NET.Build.Tasks/ResolveTargetingPackAssets.cs @@ -1,9 +1,11 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; using System.Text; +using System.Threading; using System.Xml.Linq; using Microsoft.Build.Framework; using Microsoft.Build.Utilities; @@ -88,7 +90,7 @@ protected override void ExecuteCore() string targetingPackDataPath = Path.Combine(targetingPackRoot, "data"); string targetingPackDllFolder = Path.Combine(targetingPackRoot, "ref", targetingPackTargetFramework); - + // Fall back to netcoreapp5.0 folder if looking for net5.0 and it's not found if (!Directory.Exists(targetingPackDllFolder) && targetingPackTargetFramework.Equals("net5.0", StringComparison.OrdinalIgnoreCase)) @@ -103,7 +105,7 @@ protected override void ExecuteCore() string frameworkListPath = Path.Combine(targetingPackDataPath, "FrameworkList.xml"); - AddReferencesFromFrameworkList(frameworkListPath, targetingPackDllFolder, + AddReferencesFromFrameworkList(frameworkListPath, targetingPackRoot, targetingPackDllFolder, targetingPack, referencesToAdd); if (File.Exists(platformManifestPath)) @@ -175,17 +177,19 @@ private void AddNetStandardTargetingPackAssets(ITaskItem targetingPack, string t } } - private void AddReferencesFromFrameworkList(string frameworkListPath, string targetingPackDllFolder, + private void AddReferencesFromFrameworkList(string frameworkListPath, string targetingPackRoot, + string targetingPackDllFolder, ITaskItem targetingPack, List referenceItems) { XDocument frameworkListDoc = XDocument.Load(frameworkListPath); string profile = targetingPack.GetMetadata("Profile"); + bool usePathElementsInFrameworkListAsFallBack = + TestFirstFileInFrameworkListUsingAssemblyNameConvention(targetingPackDllFolder, frameworkListDoc); + foreach (var fileElement in frameworkListDoc.Root.Elements("File")) { - string assemblyName = fileElement.Attribute("AssemblyName").Value; - if (!string.IsNullOrEmpty(profile)) { var profileAttributeValue = fileElement.Attribute("Profile")?.Value; @@ -212,7 +216,10 @@ private void AddReferencesFromFrameworkList(string frameworkListPath, string tar continue; } - var dllPath = Path.Combine(targetingPackDllFolder, assemblyName + ".dll"); + string dllPath = usePathElementsInFrameworkListAsFallBack ? + Path.Combine(targetingPackRoot, fileElement.Attribute("Path").Value) : + GetDllPathViaAssemblyName(targetingPackDllFolder, fileElement); + var referenceItem = CreateReferenceItem(dllPath, targetingPack); referenceItem.SetMetadata("AssemblyVersion", fileElement.Attribute("AssemblyVersion").Value); @@ -223,6 +230,37 @@ private void AddReferencesFromFrameworkList(string frameworkListPath, string tar } } + /// + /// Due to https://github.com/dotnet/sdk/issues/12098 we fall back to use "Path" when "AssemblyName" will + /// not resolve the actual dll. + /// + /// if use we should use "Path" element in frameworkList as a fallback + private static bool TestFirstFileInFrameworkListUsingAssemblyNameConvention(string targetingPackDllFolder, + XDocument frameworkListDoc) + { + bool usePathElementsInFrameworkListPathAsFallBack; + var firstFileElement = frameworkListDoc.Root.Elements("File").FirstOrDefault(); + if (firstFileElement == null) + { + usePathElementsInFrameworkListPathAsFallBack = false; + } + else + { + string dllPath = GetDllPathViaAssemblyName(targetingPackDllFolder, firstFileElement); + + usePathElementsInFrameworkListPathAsFallBack = !File.Exists(dllPath); + } + + return usePathElementsInFrameworkListPathAsFallBack; + } + + private static string GetDllPathViaAssemblyName(string targetingPackDllFolder, XElement fileElement) + { + string assemblyName = fileElement.Attribute("AssemblyName").Value; + var dllPath = Path.Combine(targetingPackDllFolder, assemblyName + ".dll"); + return dllPath; + } + private TaskItem CreateReferenceItem(string dll, ITaskItem targetingPack) { var reference = new TaskItem(dll); 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 669a778dcd3a..cc8600174ea8 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 @@ -61,6 +61,8 @@ Copyright (c) .NET Foundation. All rights reserved. KnownRuntimePacks="@(KnownRuntimePack)" TargetFrameworkIdentifier="$(TargetFrameworkIdentifier)" TargetFrameworkVersion="$(_TargetFrameworkVersionWithoutV)" + TargetPlatformIdentifier="$(TargetPlatformIdentifier)" + TargetPlatformVersion="$(TargetPlatformVersion)" TargetingPackRoot="$(NetCoreTargetingPackRoot)" RuntimeGraphPath="$(BundledRuntimeIdentifierGraphFile)" SelfContained="$(SelfContained)" @@ -384,7 +386,7 @@ Copyright (c) .NET Foundation. All rights reserved. + Condition="'$(CopyLocalLockFileAssemblies)' == 'true' and ('$(SelfContained)' == 'true' or '%(RuntimePackAsset.RuntimePackAlwaysCopyLocal)' == 'true')" /> diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.props b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.props index 3851d91edcdd..19db4dd00443 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.props +++ b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.props @@ -126,4 +126,5 @@ Copyright (c) .NET Foundation. All rights reserved. + diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.targets b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.targets index 36e7074135e0..c5c9408f4ce1 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.targets +++ b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.targets @@ -960,4 +960,5 @@ Copyright (c) .NET Foundation. All rights reserved. + diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Windows.props b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Windows.props new file mode 100644 index 000000000000..85278c086cd5 --- /dev/null +++ b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Windows.props @@ -0,0 +1,17 @@ + + + + + + + diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Windows.targets b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Windows.targets new file mode 100644 index 000000000000..6ca558e700d3 --- /dev/null +++ b/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Windows.targets @@ -0,0 +1,17 @@ + + + + + <_IncludeWindowsSDKRefFrameworkReferences>true + + diff --git a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildALibrary.cs b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildALibrary.cs index ef98b64c861d..fd410e21fcbd 100644 --- a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildALibrary.cs +++ b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildALibrary.cs @@ -442,6 +442,8 @@ public void It_implicitly_defines_compilation_constants_for_the_target_platform( propGroup.Add(platformIdentifier); var platformVersion = new XElement(ns + "TargetPlatformVersion", targetPlatformVersion); propGroup.Add(platformVersion); + var disableUnnecessaryImplicitFrameworkReferencesForThisTest = new XElement(ns + "DisableImplicitFrameworkReferences", "true"); + propGroup.Add(disableUnnecessaryImplicitFrameworkReferencesForThisTest); }); AssertDefinedConstantsOutput(testAsset, targetFramework, new[] { "NETCOREAPP", "NET", "NET5_0", "NETCOREAPP3_1" }.Concat(expectedDefines).ToArray());