Skip to content

Commit 702e250

Browse files
authored
Add restore support for C++/CLI .NET Core projects (#4076)
1 parent a82d6f2 commit 702e250

File tree

32 files changed

+926
-44
lines changed

32 files changed

+926
-44
lines changed

src/NuGet.Clients/NuGet.SolutionRestoreManager/VSNominationUtilities.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,12 +160,14 @@ internal static NuGetFramework GetTargetFramework(IVsProjectProperties propertie
160160
var targetFrameworkMoniker = GetPropertyValueOrNull(properties, ProjectBuildProperties.TargetFrameworkMoniker);
161161
var targetPlatformMoniker = GetPropertyValueOrNull(properties, ProjectBuildProperties.TargetPlatformMoniker);
162162
var targetPlatformMinVersion = GetPropertyValueOrNull(properties, ProjectBuildProperties.TargetPlatformMinVersion);
163+
var clrSupport = GetPropertyValueOrNull(properties, ProjectBuildProperties.CLRSupport);
163164

164165
return MSBuildProjectFrameworkUtility.GetProjectFramework(
165166
projectFullPath,
166167
targetFrameworkMoniker,
167168
targetPlatformMoniker,
168-
targetPlatformMinVersion);
169+
targetPlatformMinVersion,
170+
clrSupport);
169171
}
170172

171173
internal static ProjectRestoreMetadataFrameworkInfo ToProjectRestoreMetadataFrameworkInfo(

src/NuGet.Core/NuGet.Build.Tasks.Console/MSBuildStaticGraphRestore.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,8 @@ internal static List<TargetFrameworkInformation> GetTargetFrameworkInfos(IReadOn
570570
projectFilePath: projectInnerNode.Value.FullPath,
571571
targetFrameworkMoniker: msBuildProjectInstance.GetProperty("TargetFrameworkMoniker"),
572572
targetPlatformMoniker: msBuildProjectInstance.GetProperty("TargetPlatformMoniker"),
573-
targetPlatformMinVersion: msBuildProjectInstance.GetProperty("TargetPlatformMinVersion"));
573+
targetPlatformMinVersion: msBuildProjectInstance.GetProperty("TargetPlatformMinVersion"),
574+
clrSupport: msBuildProjectInstance.GetProperty("CLRSupport"));
574575

575576
var targetFrameworkInformation = new TargetFrameworkInformation()
576577
{

src/NuGet.Core/NuGet.Build.Tasks/NuGet.targets

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -943,6 +943,7 @@ Copyright (c) .NET Foundation. All rights reserved.
943943
<TargetPlatformIdentifier>$(TargetPlatformIdentifier)</TargetPlatformIdentifier>
944944
<TargetPlatformVersion>$(TargetPlatformVersion)</TargetPlatformVersion>
945945
<TargetPlatformMinVersion>$(TargetPlatformMinVersion)</TargetPlatformMinVersion>
946+
<CLRSupport>$(CLRSupport)</CLRSupport>
946947
<RuntimeIdentifierGraphPath>$(RuntimeIdentifierGraphPath)</RuntimeIdentifierGraphPath>
947948
</_RestoreGraphEntry>
948949
</ItemGroup>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
NuGet.Commands.SignArgs.PackagePaths.get -> System.Collections.Generic.IReadOnlyList<string>
22
NuGet.Commands.SignArgs.PackagePaths.set -> void
3+
static NuGet.Commands.MSBuildProjectFrameworkUtility.GetProjectFramework(string projectFilePath, string targetFrameworkMoniker, string targetPlatformMoniker, string targetPlatformMinVersion, string clrSupport) -> NuGet.Frameworks.NuGetFramework
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
NuGet.Commands.SignArgs.PackagePaths.get -> System.Collections.Generic.IReadOnlyList<string>
22
NuGet.Commands.SignArgs.PackagePaths.set -> void
3+
static NuGet.Commands.MSBuildProjectFrameworkUtility.GetProjectFramework(string projectFilePath, string targetFrameworkMoniker, string targetPlatformMoniker, string targetPlatformMinVersion, string clrSupport) -> NuGet.Frameworks.NuGetFramework
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
NuGet.Commands.SignArgs.PackagePaths.get -> System.Collections.Generic.IReadOnlyList<string>
22
NuGet.Commands.SignArgs.PackagePaths.set -> void
3+
static NuGet.Commands.MSBuildProjectFrameworkUtility.GetProjectFramework(string projectFilePath, string targetFrameworkMoniker, string targetPlatformMoniker, string targetPlatformMinVersion, string clrSupport) -> NuGet.Frameworks.NuGetFramework

src/NuGet.Core/NuGet.Commands/RestoreCommand/SourceRepositoryDependencyProvider.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,11 @@ private IEnumerable<LibraryDependency> GetDependencies(
465465
targetFramework,
466466
item => item.TargetFramework);
467467

468+
if (dependencyGroup == null && DeconstructFallbackFrameworks(targetFramework) is DualCompatibilityFramework dualCompatibilityFramework)
469+
{
470+
dependencyGroup = NuGetFrameworkUtility.GetNearest(packageInfo.DependencyGroups, dualCompatibilityFramework.SecondaryFramework, item => item.TargetFramework);
471+
}
472+
468473
if (dependencyGroup != null)
469474
{
470475
return dependencyGroup.Packages.Select(PackagingUtility.GetLibraryDependencyFromNuspec).ToArray();
@@ -473,6 +478,21 @@ private IEnumerable<LibraryDependency> GetDependencies(
473478
return Enumerable.Empty<LibraryDependency>();
474479
}
475480

481+
private static NuGetFramework DeconstructFallbackFrameworks(NuGetFramework nuGetFramework)
482+
{
483+
if (nuGetFramework is AssetTargetFallbackFramework assetTargetFallbackFramework)
484+
{
485+
return assetTargetFallbackFramework.RootFramework;
486+
}
487+
488+
if (nuGetFramework is FallbackFramework fallbackFramework)
489+
{
490+
return fallbackFramework;
491+
}
492+
493+
return nuGetFramework;
494+
}
495+
476496
private async Task EnsureResource()
477497
{
478498
if (_findPackagesByIdResource == null)

src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/LockFileUtils.cs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ internal static List<List<SelectionCriteria>> CreateOrderedCriteriaSets(RestoreT
142142
// Create an ordered list of selection criteria. Each will be applied, if the result is empty
143143
// fallback frameworks from "imports" will be tried.
144144
// These are only used for framework/RID combinations where content model handles everything.
145-
// AssetTargetFallback frameworks will provide multiple criteria since all assets need to be
145+
// AssetTargetFallback and DualCompatbiility frameworks will provide multiple criteria since all assets need to be
146146
// evaluated before selecting the TFM to use.
147147
var orderedCriteriaSets = new List<List<SelectionCriteria>>(1);
148148

@@ -152,6 +152,11 @@ internal static List<List<SelectionCriteria>> CreateOrderedCriteriaSets(RestoreT
152152
{
153153
// Add the root project framework first.
154154
orderedCriteriaSets.Add(CreateCriteria(targetGraph, assetTargetFallback.RootFramework));
155+
// Add the secondary framework if dual compatibility framework.
156+
if (assetTargetFallback.RootFramework is DualCompatibilityFramework dualCompatibilityFramework)
157+
{
158+
orderedCriteriaSets.Add(CreateCriteria(targetGraph, dualCompatibilityFramework.SecondaryFramework));
159+
}
155160

156161
// Add all fallbacks in order.
157162
orderedCriteriaSets.AddRange(assetTargetFallback.Fallback.Select(e => CreateCriteria(targetGraph, e)));
@@ -160,6 +165,11 @@ internal static List<List<SelectionCriteria>> CreateOrderedCriteriaSets(RestoreT
160165
{
161166
// Add the current framework.
162167
orderedCriteriaSets.Add(CreateCriteria(targetGraph, framework));
168+
169+
if (framework is DualCompatibilityFramework dualCompatibilityFramework)
170+
{
171+
orderedCriteriaSets.Add(CreateCriteria(targetGraph, dualCompatibilityFramework.SecondaryFramework));
172+
}
163173
}
164174

165175
return orderedCriteriaSets;
@@ -458,9 +468,17 @@ private static void AddDependencies(IEnumerable<LibraryDependency> dependencies,
458468
{
459469
if (dependencies == null)
460470
{
461-
// AssetFallbackFramework does not apply to dependencies.
471+
// DualCompatibilityFramework & AssetFallbackFramework does not apply to dependencies.
462472
// Convert it to a fallback framework if needed.
463-
var currentFramework = (framework as AssetTargetFallbackFramework)?.AsFallbackFramework() ?? framework;
473+
NuGetFramework currentFramework = framework;
474+
if (framework is AssetTargetFallbackFramework atf)
475+
{
476+
currentFramework = atf.AsFallbackFramework();
477+
}
478+
else if (framework is DualCompatibilityFramework mcf)
479+
{
480+
currentFramework = mcf.AsFallbackFramework();
481+
}
464482

465483
var dependencySet = nuspec
466484
.GetDependencyGroups()

src/NuGet.Core/NuGet.Commands/RestoreCommand/Utility/MSBuildRestoreUtility.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ private static IEnumerable<TargetFrameworkInformation> GetTargetFrameworkInforma
425425
var targetFrameworkMoniker = item.GetProperty("TargetFrameworkMoniker");
426426
var targetPlatforMoniker = item.GetProperty("TargetPlatformMoniker");
427427
var targetPlatformMinVersion = item.GetProperty("TargetPlatformMinVersion");
428-
428+
var clrSupport = item.GetProperty("CLRSupport");
429429
var targetAlias = string.IsNullOrEmpty(frameworkString) ? string.Empty : frameworkString;
430430
if (uniqueIds.Contains(targetAlias))
431431
{
@@ -437,7 +437,8 @@ private static IEnumerable<TargetFrameworkInformation> GetTargetFrameworkInforma
437437
projectFilePath: filePath,
438438
targetFrameworkMoniker: targetFrameworkMoniker,
439439
targetPlatformMoniker: targetPlatforMoniker,
440-
targetPlatformMinVersion: targetPlatformMinVersion);
440+
targetPlatformMinVersion: targetPlatformMinVersion,
441+
clrSupport: clrSupport);
441442

442443
var targetFrameworkInfo = new TargetFrameworkInformation()
443444
{

src/NuGet.Core/NuGet.Commands/Utility/MSBuildProjectFrameworkUtility.cs

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,26 @@ public static NuGetFramework GetProjectFramework(
5858
targetPlatformIdentifier: null,
5959
targetPlatformVersion: null,
6060
targetPlatformMinVersion,
61+
clrSupport: null,
62+
isXnaWindowsPhoneProject: false,
63+
isManagementPackProject: false);
64+
}
65+
66+
public static NuGetFramework GetProjectFramework(
67+
string projectFilePath,
68+
string targetFrameworkMoniker,
69+
string targetPlatformMoniker,
70+
string targetPlatformMinVersion,
71+
string clrSupport)
72+
{
73+
return GetProjectFramework(
74+
projectFilePath,
75+
targetFrameworkMoniker,
76+
targetPlatformMoniker,
77+
targetPlatformIdentifier: null,
78+
targetPlatformVersion: null,
79+
targetPlatformMinVersion,
80+
clrSupport,
6181
isXnaWindowsPhoneProject: false,
6282
isManagementPackProject: false);
6383
}
@@ -89,6 +109,7 @@ public static IEnumerable<string> GetProjectFrameworkStrings(
89109
targetPlatformIdentifier,
90110
targetPlatformVersion,
91111
targetPlatformMinVersion,
112+
clrSupport: null,
92113
isXnaWindowsPhoneProject,
93114
isManagementPackProject);
94115
}
@@ -102,6 +123,7 @@ internal static IEnumerable<string> GetProjectFrameworks(
102123
string targetPlatformIdentifier,
103124
string targetPlatformVersion,
104125
string targetPlatformMinVersion,
126+
string clrSupport,
105127
bool isXnaWindowsPhoneProject,
106128
bool isManagementPackProject)
107129
{
@@ -132,6 +154,7 @@ internal static IEnumerable<string> GetProjectFrameworks(
132154
targetPlatformIdentifier,
133155
targetPlatformVersion,
134156
targetPlatformMinVersion,
157+
clrSupport,
135158
isXnaWindowsPhoneProject,
136159
isManagementPackProject).DotNetFrameworkName };
137160
}
@@ -143,15 +166,22 @@ internal static NuGetFramework GetProjectFramework(
143166
string targetPlatformIdentifier,
144167
string targetPlatformVersion,
145168
string targetPlatformMinVersion,
169+
string clrSupport,
146170
bool isXnaWindowsPhoneProject,
147171
bool isManagementPackProject)
148172
{
173+
bool isCppCliSet = clrSupport?.Equals("NetCore", StringComparison.OrdinalIgnoreCase) == true;
174+
bool isCppCli = false;
149175
// C++ check
150176
if (projectFilePath?.EndsWith(".vcxproj", StringComparison.OrdinalIgnoreCase) == true)
151177
{
152-
// The C++ project does not have a TargetFrameworkMoniker property set.
153-
// We hard-code the return value to Native.
154-
return NuGetFramework.Parse("Native, Version=0.0");
178+
if (!isCppCliSet)
179+
{
180+
// The C++ project does not have a TargetFrameworkMoniker property set.
181+
// We hard-code the return value to Native.
182+
return FrameworkConstants.CommonFrameworks.Native;
183+
}
184+
isCppCli = true;
155185
}
156186

157187
// The MP project does not have a TargetFrameworkMoniker property set.
@@ -227,6 +257,11 @@ internal static NuGetFramework GetProjectFramework(
227257
}
228258
NuGetFramework framework = NuGetFramework.ParseComponents(currentFrameworkString, platformMoniker);
229259

260+
if (isCppCli)
261+
{
262+
return new DualCompatibilityFramework(framework, FrameworkConstants.CommonFrameworks.Native);
263+
}
264+
230265
return framework;
231266
}
232267

0 commit comments

Comments
 (0)