From 3918ced9f5c10fed604c77f2c27b4134068d3d29 Mon Sep 17 00:00:00 2001 From: Ujjwal Chadha Date: Wed, 27 Jul 2022 14:52:11 -0700 Subject: [PATCH 1/2] Allow winmdobj output type as CsWinRT component --- .../MSBuildConversionWorkspace.cs | 5 +++++ src/MSBuild.Abstractions/ProjectOutputType.cs | 1 + .../ProjectPropertyHelpers.cs | 7 +++++++ src/MSBuild.Conversion.Facts/MSBuildFacts.cs | 4 ++++ src/MSBuild.Conversion.Project/Converter.cs | 1 + .../ProjectRootElementExtensionsForConversion.cs | 16 ++++++++++++++++ 6 files changed, 34 insertions(+) diff --git a/src/MSBuild.Abstractions/MSBuildConversionWorkspace.cs b/src/MSBuild.Abstractions/MSBuildConversionWorkspace.cs index f9b8c14b2..0a189dd20 100644 --- a/src/MSBuild.Abstractions/MSBuildConversionWorkspace.cs +++ b/src/MSBuild.Abstractions/MSBuildConversionWorkspace.cs @@ -237,6 +237,7 @@ private bool IsSupportedOutputType(ProjectOutputType type) => ProjectOutputType.Library => true, ProjectOutputType.WinExe => true, ProjectOutputType.AppContainerExe => true, + ProjectOutputType.WinMdObj => true, _ => false }; @@ -283,6 +284,10 @@ private ProjectOutputType GetProjectOutputType(IProjectRootElement root, Project { return ProjectOutputType.AppContainerExe; } + else if (ProjectPropertyHelpers.IsWinMdObjProjectType(outputTypeNode)) + { + return ProjectOutputType.WinMdObj; + } else { return ProjectOutputType.Other; diff --git a/src/MSBuild.Abstractions/ProjectOutputType.cs b/src/MSBuild.Abstractions/ProjectOutputType.cs index 775347f5f..fdd8c8afc 100644 --- a/src/MSBuild.Abstractions/ProjectOutputType.cs +++ b/src/MSBuild.Abstractions/ProjectOutputType.cs @@ -13,6 +13,7 @@ public enum ProjectOutputType Exe, WinExe, AppContainerExe, + WinMdObj, Other, None } diff --git a/src/MSBuild.Abstractions/ProjectPropertyHelpers.cs b/src/MSBuild.Abstractions/ProjectPropertyHelpers.cs index 5a424c876..39c4c381c 100644 --- a/src/MSBuild.Abstractions/ProjectPropertyHelpers.cs +++ b/src/MSBuild.Abstractions/ProjectPropertyHelpers.cs @@ -170,6 +170,13 @@ public static bool IsWinExeOutputType(ProjectPropertyElement prop) => prop.ElementName.Equals(MSBuildFacts.OutputTypeNodeName, StringComparison.OrdinalIgnoreCase) && prop.Value.Equals(MSBuildFacts.WinExeOutputType, StringComparison.OrdinalIgnoreCase); + /// + /// Checks if an OutputType node is Exe. + /// + public static bool IsWinMdObjProjectType(ProjectPropertyElement prop) => + prop.ElementName.Equals(MSBuildFacts.OutputTypeNodeName, StringComparison.OrdinalIgnoreCase) + && prop.Value.Equals(MSBuildFacts.WinMdObjOutputType, StringComparison.OrdinalIgnoreCase); + public static bool IsVisualBasicProject(ProjectPropertyElement prop) => IsProjectTypeGuidsNode(prop) && prop.Value.Split(';').Any(guidString => Guid.Parse(guidString) == MSBuildFacts.LanguageProjectTypeVisualBasic); diff --git a/src/MSBuild.Conversion.Facts/MSBuildFacts.cs b/src/MSBuild.Conversion.Facts/MSBuildFacts.cs index af19f2b3a..362eaa888 100644 --- a/src/MSBuild.Conversion.Facts/MSBuildFacts.cs +++ b/src/MSBuild.Conversion.Facts/MSBuildFacts.cs @@ -259,6 +259,8 @@ public static class MSBuildFacts Guid.Parse("{F2A71F9B-5D33-465A-A702-920D77279786}") // F# ); + public static readonly (string Name, string Version) CsWinRTPackageReference = (Name: "Microsoft.Windows.CsWinRT", Version: "1.6.4"); + public const string DefaultSDKAttribute = "Microsoft.NET.Sdk"; public const string LowestFrameworkVersionWithSystemValueTuple = "net47"; public const string SharedProjectsImportLabel = "Shared"; @@ -290,6 +292,7 @@ public static class MSBuildFacts public const string ExeOutputType = "Exe"; public const string WinExeOutputType = "WinExe"; public const string AppContainerExeOutputType = "AppContainerExe"; + public const string WinMdObjOutputType = "winmdobj"; public const string NuGetPackageImportStampNodeName = "NuGetPackageImportStamp"; public const string ReferencePathNodeName = "ReferencePath"; public const string LegacyTargetFrameworkPropertyNodeName = "TargetFrameworkIdentifier"; @@ -313,5 +316,6 @@ public static class MSBuildFacts public const string TargetPlatformIdentifierNodeName = "TargetPlatformIdentifier"; public const string UapValue = "UAP"; public const string TargetPlatformVersionNodeName = "TargetPlatformVersion"; + public const string CsWinRTComponentName = "CsWinRTComponent"; } } diff --git a/src/MSBuild.Conversion.Project/Converter.cs b/src/MSBuild.Conversion.Project/Converter.cs index 5e4725875..a0573d8e5 100644 --- a/src/MSBuild.Conversion.Project/Converter.cs +++ b/src/MSBuild.Conversion.Project/Converter.cs @@ -42,6 +42,7 @@ public void Convert(string outputPath) // Now we can convert the project over .ChangeImportsAndAddSdkAttribute(_sdkBaselineProject, _forceRemoveCustomImports) + .AddCsWinRTReferenceAndComponentProperty(_sdkBaselineProject) .UpdateOutputTypeProperty(_sdkBaselineProject) .RemoveDefaultedProperties(_sdkBaselineProject, _differs) .RemoveUnnecessaryPropertiesNotInSDKByDefault(_sdkBaselineProject.ProjectStyle) diff --git a/src/MSBuild.Conversion.Project/ProjectRootElementExtensionsForConversion.cs b/src/MSBuild.Conversion.Project/ProjectRootElementExtensionsForConversion.cs index ad802ac98..e46400f00 100644 --- a/src/MSBuild.Conversion.Project/ProjectRootElementExtensionsForConversion.cs +++ b/src/MSBuild.Conversion.Project/ProjectRootElementExtensionsForConversion.cs @@ -65,6 +65,21 @@ public static IProjectRootElement ChangeImportsAndAddSdkAttribute(this IProjectR return projectRootElement; } + public static IProjectRootElement AddCsWinRTReferenceAndComponentProperty(this IProjectRootElement projectRootElement, BaselineProject baselineProject) + { + if (baselineProject.OutputType == ProjectOutputType.WinMdObj) + { + var topLevelPropGroup = MSBuildHelpers.GetOrCreateTopLevelPropertyGroup(baselineProject, projectRootElement); + topLevelPropGroup.AddProperty(MSBuildFacts.CsWinRTComponentName, "true"); + + var itemGroup = projectRootElement.ItemGroups.Where(ig => ig.Items.Where(i => i.ItemType == MSBuildFacts.MSBuildPackageReferenceName).Any()) + .FirstOrDefault() ?? projectRootElement.AddItemGroup(); + AddPackageReferenceElement(itemGroup, MSBuildFacts.CsWinRTPackageReference.Name, MSBuildFacts.CsWinRTPackageReference.Version); + } + + return projectRootElement; + } + public static IProjectRootElement UpdateOutputTypeProperty(this IProjectRootElement projectRootElement, BaselineProject baselineProject) { var outputTypeNode = projectRootElement.GetOutputTypeNode(); @@ -76,6 +91,7 @@ public static IProjectRootElement UpdateOutputTypeProperty(this IProjectRootElem ProjectOutputType.Library => MSBuildFacts.LibraryOutputType, ProjectOutputType.WinExe => MSBuildFacts.WinExeOutputType, ProjectOutputType.AppContainerExe => MSBuildFacts.WinExeOutputType, + ProjectOutputType.WinMdObj => MSBuildFacts.LibraryOutputType, _ => throw new InvalidOperationException("Unsupported output type: " + baselineProject.OutputType) }; } From f033110287737f131ebf93c0e23991e3d686edbe Mon Sep 17 00:00:00 2001 From: Ujjwal Chadha Date: Mon, 1 Aug 2022 13:17:12 -0700 Subject: [PATCH 2/2] Minor: cleanup names and code --- .../ProjectRootElementExtensionsForConversion.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/MSBuild.Conversion.Project/ProjectRootElementExtensionsForConversion.cs b/src/MSBuild.Conversion.Project/ProjectRootElementExtensionsForConversion.cs index e46400f00..fa245f103 100644 --- a/src/MSBuild.Conversion.Project/ProjectRootElementExtensionsForConversion.cs +++ b/src/MSBuild.Conversion.Project/ProjectRootElementExtensionsForConversion.cs @@ -72,9 +72,9 @@ public static IProjectRootElement AddCsWinRTReferenceAndComponentProperty(this I var topLevelPropGroup = MSBuildHelpers.GetOrCreateTopLevelPropertyGroup(baselineProject, projectRootElement); topLevelPropGroup.AddProperty(MSBuildFacts.CsWinRTComponentName, "true"); - var itemGroup = projectRootElement.ItemGroups.Where(ig => ig.Items.Where(i => i.ItemType == MSBuildFacts.MSBuildPackageReferenceName).Any()) + var packageReferenceItemGroup = projectRootElement.ItemGroups.Where(ig => ig.Items.Any(i => i.ItemType == MSBuildFacts.MSBuildPackageReferenceName)) .FirstOrDefault() ?? projectRootElement.AddItemGroup(); - AddPackageReferenceElement(itemGroup, MSBuildFacts.CsWinRTPackageReference.Name, MSBuildFacts.CsWinRTPackageReference.Version); + AddPackageReferenceElement(packageReferenceItemGroup, MSBuildFacts.CsWinRTPackageReference.Name, MSBuildFacts.CsWinRTPackageReference.Version); } return projectRootElement;