Skip to content

Commit 3bef5b2

Browse files
committed
Match pre-3.0 SDK behavior for selecting default PlatformTarget
1 parent 2ec7eb3 commit 3bef5b2

File tree

3 files changed

+90
-18
lines changed

3 files changed

+90
-18
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using Microsoft.Build.Framework;
6+
7+
namespace Microsoft.NET.Build.Tasks
8+
{
9+
public class GetDefaultPlatformTargetForNetFramework : TaskBase
10+
{
11+
public ITaskItem[] PackageDependencies { get; set; }
12+
13+
public ITaskItem[] NativeCopyLocalItems { get; set; }
14+
15+
[Output]
16+
public string DefaultPlatformTarget { get; private set; }
17+
18+
private const string X86 = "x86";
19+
private const string AnyCPU = "AnyCPU";
20+
21+
protected override void ExecuteCore()
22+
{
23+
// For .NET Framework projects, the SDK will select a default RuntimeIdentifier and PlatformTarget. If no
24+
// native assets are found from NuGet packages, then the PlatformTarget will be reset to AnyCPU. See the
25+
// comments in Microsoft.NET.RuntimeIdentifierInference.targets for details.
26+
//
27+
// Prior to the .NET Core 3.0 SDK, .NET Framework projects would only have a RuntimeIdentifier graph if the
28+
// Microsoft.NETCore.Platforms package was (transitively) referenced. This meant that native assets would
29+
// only be selected if the platforms package was referenced or if the RuntimeIdentifier matched exactly.
30+
//
31+
// Now that the RuntimeIdentifier graph is provided in the SDK, the logic in this task preserves the PlatformTarget
32+
// behavior from earlier SDKs, even though with the RuntimeIdentifier graph supplied, there may be native
33+
// assets selected where in prior SDKs there would not have been.
34+
35+
if (NativeCopyLocalItems == null || NativeCopyLocalItems.Length == 0)
36+
{
37+
DefaultPlatformTarget = AnyCPU;
38+
return;
39+
}
40+
41+
foreach (var packageDependency in PackageDependencies ?? Enumerable.Empty<ITaskItem>())
42+
{
43+
// If the Platforms package is in the dependencies, then any native assets imply an X86 default PlatformTarget
44+
if (packageDependency.ItemSpec.Equals("Microsoft.NETCore.Platforms", StringComparison.OrdinalIgnoreCase))
45+
{
46+
DefaultPlatformTarget = X86;
47+
return;
48+
}
49+
}
50+
51+
foreach (var nativeItem in NativeCopyLocalItems)
52+
{
53+
// If the Platforms package was not referenced, but there are native assets for the exact RID win7-x86,
54+
// then the default PlatformTarget should be x86.
55+
string pathInPackage = nativeItem.GetMetadata(MetadataKeys.PathInPackage);
56+
if (pathInPackage.StartsWith("runtimes/win7-x86/", StringComparison.OrdinalIgnoreCase))
57+
{
58+
DefaultPlatformTarget = X86;
59+
return;
60+
}
61+
}
62+
63+
// Otherwise, there would have been no native assets selected on pre-3.0 SDKs, so use AnyCPU as the
64+
// default PlatformTarget
65+
DefaultPlatformTarget = AnyCPU;
66+
}
67+
}
68+
}

Diff for: src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.RuntimeIdentifierInference.targets

+10-13
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,10 @@ Copyright (c) .NET Foundation. All rights reserved.
174174
<OutputPath>$(OutputPath)$(RuntimeIdentifier)\</OutputPath>
175175
</PropertyGroup>
176176

177+
<UsingTask TaskName="Microsoft.NET.Build.Tasks.GetDefaultPlatformTargetForNetFramework"
178+
AssemblyFile="$(MicrosoftNETBuildTasksAssembly)" />
179+
180+
177181
<!--
178182
Switch our default .NETFramework CPU architecture choice back to AnyCPU before
179183
compiling the exe if no copy-local native dependencies were resolved from NuGet
@@ -184,19 +188,12 @@ Copyright (c) .NET Foundation. All rights reserved.
184188
Condition="'$(_UsingDefaultPlatformTarget)' == 'true' and
185189
'$(_UsingDefaultRuntimeIdentifier)' == 'true'">
186190

187-
<ItemGroup>
188-
<_PlatformPackageDependency Include="@(PackageDependencies)" Condition="'%(Identity)' == 'Microsoft.NETCore.Platforms'" />
189-
</ItemGroup>
190-
191-
<!-- If there were no native assets, or if the Microsoft.NETCore.Platforms package was not referenced, then revert to AnyCPU.
192-
The reason we use AnyCPU if Microsoft.NETCore.Platforms is not referenced is to preserve behavior from before 3.0 when
193-
the RuntimeIdentifier graph wasn't included in the SDK, and assets where the RuntimeIdentifier didn't match exactly wouldn't
194-
be picked up unless the platforms package was referenced. -->
195-
196-
<PropertyGroup Condition="('@(NativeCopyLocalItems)' == '' or
197-
'@(_PlatformPackageDependency)' == '')">
198-
<PlatformTarget>AnyCPU</PlatformTarget>
199-
</PropertyGroup>
191+
<GetDefaultPlatformTargetForNetFramework PackageDependencies="@(PackageDependencies)"
192+
NativeCopyLocalItems="@(NativeCopyLocalItems)">
193+
194+
<Output TaskParameter="DefaultPlatformTarget" PropertyName="PlatformTarget" />
195+
196+
</GetDefaultPlatformTargetForNetFramework>
200197
</Target>
201198

202199
</Project>

Diff for: src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildADesktopExe.cs

+12-5
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,12 @@ public void It_builds_a_simple_desktop_app()
5555

5656
// Windows only because default RuntimeIdentifier only applies when current OS is Windows
5757
[WindowsOnlyTheory]
58-
[InlineData(false, "AnyCPU")]
59-
[InlineData(true, "x86")]
60-
public void RuntimeIdentifierIsOnlyInferredIfPlatformsPackageIsReferenced(bool referencePlatformPackage, string expectedPlatform)
58+
[InlineData("Microsoft.DiasymReader.Native/1.7.0", false, "AnyCPU")]
59+
[InlineData("Microsoft.DiasymReader.Native/1.7.0", true, "x86")]
60+
[InlineData("SQLite/3.13.0", false, "x86")]
61+
[InlineData("SQLite/3.13.0", true, "x86")]
62+
63+
public void PlatformTargetInferredCorrectly(string packageToReference, bool referencePlatformPackage, string expectedPlatform)
6164
{
6265
var testProject = new TestProject()
6366
{
@@ -67,13 +70,17 @@ public void RuntimeIdentifierIsOnlyInferredIfPlatformsPackageIsReferenced(bool r
6770
IsExe = true
6871
};
6972

70-
testProject.PackageReferences.Add(new TestPackageReference("Microsoft.DiasymReader.Native", "1.7.0"));
73+
var packageElements = packageToReference.Split('/');
74+
string packageName = packageElements[0];
75+
string packageVersion = packageElements[1];
76+
77+
testProject.PackageReferences.Add(new TestPackageReference(packageName, packageVersion));
7178
if (referencePlatformPackage)
7279
{
7380
testProject.PackageReferences.Add(new TestPackageReference("Microsoft.NETCore.Platforms", "2.1.0"));
7481
}
7582

76-
var testAsset = _testAssetsManager.CreateTestProject(testProject, identifier: referencePlatformPackage.ToString())
83+
var testAsset = _testAssetsManager.CreateTestProject(testProject, identifier: packageName + "_" + referencePlatformPackage.ToString())
7784
.Restore(Log, testProject.Name);
7885

7986
var buildCommand = new BuildCommand(Log, Path.Combine(testAsset.TestRoot, testProject.Name));

0 commit comments

Comments
 (0)