From 2e2bb926e51d8e9d890bc990f69e685b1080608b Mon Sep 17 00:00:00 2001 From: Andrei Borodin Date: Tue, 21 Jan 2020 16:54:43 -0800 Subject: [PATCH 1/7] Commiting ready changes. --- .../Assets/Dependencies.msb4u.csproj | 8 +- .../Assets/Project.Unity.msb4u.sln | 48 ++--- .../Exporters/IPlatformPropsExporter.cs | 2 +- .../ITopLevelDependenciesProjectExporter.cs | 52 ++++++ ...pLevelDependenciesProjectExporter.cs.meta} | 2 +- .../Exporters/IUnityProjectExporter.cs | 7 + .../TemplatedCommonPropsExporter.cs | 14 +- .../TemplatedExporterBase.cs | 46 ----- .../TemplatedPlatformPropsExporter.cs | 19 +- ...atedTopLevelDependenciesProjectExporter.cs | 67 +++++++ ...opLevelDependenciesProjectExporter.cs.meta | 11 ++ .../TemplatedUnityProjectExporter.cs | 37 +--- ...TemplatedWSAPlayerPlatformPropsExporter.cs | 4 +- .../TemplatedExporter/TemplatedWriter.cs | 26 ++- .../ProjectGenerator/Scripts/MSBuildTools.cs | 49 +++--- .../Scripts/MSBuildUnityProjectExporter.cs | 79 +++++++++ .../Scripts/UnityProjectInfo.cs | 164 ++++++++++-------- .../ProjectGenerator/Scripts/Utilities.cs | 54 ++++++ 18 files changed, 470 insertions(+), 219 deletions(-) create mode 100644 Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/ITopLevelDependenciesProjectExporter.cs rename Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/{TemplatedExporter/TemplatedExporterBase.cs.meta => ITopLevelDependenciesProjectExporter.cs.meta} (83%) delete mode 100644 Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedExporterBase.cs create mode 100644 Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedTopLevelDependenciesProjectExporter.cs create mode 100644 Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedTopLevelDependenciesProjectExporter.cs.meta diff --git a/Samples/IntegratedDependencies.Unity/Assets/Dependencies.msb4u.csproj b/Samples/IntegratedDependencies.Unity/Assets/Dependencies.msb4u.csproj index c492fa7..ffc3e86 100644 --- a/Samples/IntegratedDependencies.Unity/Assets/Dependencies.msb4u.csproj +++ b/Samples/IntegratedDependencies.Unity/Assets/Dependencies.msb4u.csproj @@ -6,11 +6,11 @@ It is different from the other generated C# Projects in that it will be the one gathering all dependencies and placing them into the Unity asset folder. You can add project level dependencies to this file, by placing them below: - - + - and before: - - + - - Do not add any source or compliation items. + Do not add any source or compilation items. Examples of how you can modify this file: - Add NuGet package references: @@ -36,7 +36,7 @@ - + \ No newline at end of file diff --git a/Samples/IntegratedDependencies.Unity/Assets/Project.Unity.msb4u.sln b/Samples/IntegratedDependencies.Unity/Assets/Project.Unity.msb4u.sln index 20b6ff8..34f0cee 100644 --- a/Samples/IntegratedDependencies.Unity/Assets/Project.Unity.msb4u.sln +++ b/Samples/IntegratedDependencies.Unity/Assets/Project.Unity.msb4u.sln @@ -155,12 +155,12 @@ Global {15A615C7-33AA-2409-09FE-0B28B0D5143C}.InEditor|WindowsStandalone64.Build.0 = InEditor|WindowsStandalone64 {15A615C7-33AA-2409-09FE-0B28B0D5143C}.InEditor|WSA.ActiveCfg = InEditor|WSA {15A615C7-33AA-2409-09FE-0B28B0D5143C}.InEditor|WSA.Build.0 = InEditor|WSA - {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|Android.ActiveCfg = InEditor|Android - {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|Any CPU.ActiveCfg = InEditor|Android - {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|iOS.ActiveCfg = InEditor|Android - {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|WindowsStandalone32.ActiveCfg = InEditor|Android - {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|WindowsStandalone64.ActiveCfg = InEditor|Android - {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|WSA.ActiveCfg = InEditor|Android + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|Android.ActiveCfg = Player|Android + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|Any CPU.ActiveCfg = Player|Android + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|iOS.ActiveCfg = Player|iOS + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|WindowsStandalone32.ActiveCfg = Player|WindowsStandalone32 + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|WindowsStandalone64.ActiveCfg = Player|WindowsStandalone64 + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|WSA.ActiveCfg = Player|WSA {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Release|Android.ActiveCfg = InEditor|Android {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Release|Any CPU.ActiveCfg = InEditor|Android {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Release|iOS.ActiveCfg = InEditor|Android @@ -184,12 +184,12 @@ Global {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.InEditor|WindowsStandalone64.Build.0 = InEditor|WindowsStandalone64 {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.InEditor|WSA.ActiveCfg = InEditor|WSA {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.InEditor|WSA.Build.0 = InEditor|WSA - {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|Android.ActiveCfg = InEditor|Android - {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|Any CPU.ActiveCfg = InEditor|Android - {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|iOS.ActiveCfg = InEditor|Android - {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|WindowsStandalone32.ActiveCfg = InEditor|Android - {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|WindowsStandalone64.ActiveCfg = InEditor|Android - {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|WSA.ActiveCfg = InEditor|Android + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|Android.ActiveCfg = Player|Android + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|Any CPU.ActiveCfg = Player|Android + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|iOS.ActiveCfg = Player|iOS + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|WindowsStandalone32.ActiveCfg = Player|WindowsStandalone32 + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|WindowsStandalone64.ActiveCfg = Player|WindowsStandalone64 + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|WSA.ActiveCfg = Player|WSA {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Release|Android.ActiveCfg = InEditor|Android {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Release|Any CPU.ActiveCfg = InEditor|Android {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Release|iOS.ActiveCfg = InEditor|Android @@ -213,12 +213,12 @@ Global {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.InEditor|WindowsStandalone64.Build.0 = InEditor|WindowsStandalone64 {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.InEditor|WSA.ActiveCfg = InEditor|WSA {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.InEditor|WSA.Build.0 = InEditor|WSA - {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|Android.ActiveCfg = InEditor|Android - {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|Any CPU.ActiveCfg = InEditor|Android - {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|iOS.ActiveCfg = InEditor|Android - {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|WindowsStandalone32.ActiveCfg = InEditor|Android - {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|WindowsStandalone64.ActiveCfg = InEditor|Android - {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|WSA.ActiveCfg = InEditor|Android + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|Android.ActiveCfg = Player|Android + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|Any CPU.ActiveCfg = Player|Android + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|iOS.ActiveCfg = Player|iOS + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|WindowsStandalone32.ActiveCfg = Player|WindowsStandalone32 + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|WindowsStandalone64.ActiveCfg = Player|WindowsStandalone64 + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|WSA.ActiveCfg = Player|WSA {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Release|Android.ActiveCfg = InEditor|Android {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Release|Any CPU.ActiveCfg = InEditor|Android {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Release|iOS.ActiveCfg = InEditor|Android @@ -276,12 +276,12 @@ Global {6546D776-5B41-65B4-0850-B3667F981C26}.InEditor|WindowsStandalone64.Build.0 = InEditor|WindowsStandalone64 {6546D776-5B41-65B4-0850-B3667F981C26}.InEditor|WSA.ActiveCfg = InEditor|WSA {6546D776-5B41-65B4-0850-B3667F981C26}.InEditor|WSA.Build.0 = InEditor|WSA - {6546D776-5B41-65B4-0850-B3667F981C26}.Player|Android.ActiveCfg = InEditor|Android - {6546D776-5B41-65B4-0850-B3667F981C26}.Player|Any CPU.ActiveCfg = InEditor|Android - {6546D776-5B41-65B4-0850-B3667F981C26}.Player|iOS.ActiveCfg = InEditor|Android - {6546D776-5B41-65B4-0850-B3667F981C26}.Player|WindowsStandalone32.ActiveCfg = InEditor|Android - {6546D776-5B41-65B4-0850-B3667F981C26}.Player|WindowsStandalone64.ActiveCfg = InEditor|Android - {6546D776-5B41-65B4-0850-B3667F981C26}.Player|WSA.ActiveCfg = InEditor|Android + {6546D776-5B41-65B4-0850-B3667F981C26}.Player|Android.ActiveCfg = Player|Android + {6546D776-5B41-65B4-0850-B3667F981C26}.Player|Any CPU.ActiveCfg = Player|Android + {6546D776-5B41-65B4-0850-B3667F981C26}.Player|iOS.ActiveCfg = Player|iOS + {6546D776-5B41-65B4-0850-B3667F981C26}.Player|WindowsStandalone32.ActiveCfg = Player|WindowsStandalone32 + {6546D776-5B41-65B4-0850-B3667F981C26}.Player|WindowsStandalone64.ActiveCfg = Player|WindowsStandalone64 + {6546D776-5B41-65B4-0850-B3667F981C26}.Player|WSA.ActiveCfg = Player|WSA {6546D776-5B41-65B4-0850-B3667F981C26}.Release|Android.ActiveCfg = InEditor|Android {6546D776-5B41-65B4-0850-B3667F981C26}.Release|Any CPU.ActiveCfg = InEditor|Android {6546D776-5B41-65B4-0850-B3667F981C26}.Release|iOS.ActiveCfg = InEditor|Android diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/IPlatformPropsExporter.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/IPlatformPropsExporter.cs index 7f5648f..bdef1ae 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/IPlatformPropsExporter.cs +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/IPlatformPropsExporter.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. See LICENSE in the project root for license information. #if UNITY_EDITOR diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/ITopLevelDependenciesProjectExporter.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/ITopLevelDependenciesProjectExporter.cs new file mode 100644 index 0000000..27d3315 --- /dev/null +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/ITopLevelDependenciesProjectExporter.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Microsoft.Build.Unity.ProjectGeneration.Exporters +{ + /// + /// Represents a project reference with a condition. + /// + public struct ProjectReference + { + /// + /// Path to the project. + /// + public Uri ReferencePath { get; set; } + + /// + /// Condition for this reference. + /// + public string Condition { get; set; } + + public override int GetHashCode() + { + return ReferencePath?.GetHashCode() ?? 0; + } + + public override bool Equals(object obj) + { + return obj is ProjectReference other && Equals(ReferencePath, other.ReferencePath); + } + } + + /// + /// Represents an exporter for the top-level project that is responsible for bringing in the MSB4U resovled dependencies into Unity. + /// + public interface ITopLevelDependenciesProjectExporter + { + /// + /// Gets or sets the Guid of the project. + /// + Guid Guid { get; set; } + + /// + /// Gets the set of references for this project. + /// + HashSet References { get; } + + void Write(); + } +} diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedExporterBase.cs.meta b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/ITopLevelDependenciesProjectExporter.cs.meta similarity index 83% rename from Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedExporterBase.cs.meta rename to Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/ITopLevelDependenciesProjectExporter.cs.meta index e737b3f..99d5d52 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedExporterBase.cs.meta +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/ITopLevelDependenciesProjectExporter.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 462fe66334a335241a4c4eb9ea9bf25e +guid: 5e298e6404f3ddd449e4c247ea3f57ca MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/IUnityProjectExporter.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/IUnityProjectExporter.cs index 5328ede..55797c1 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/IUnityProjectExporter.cs +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/IUnityProjectExporter.cs @@ -45,6 +45,13 @@ public interface IUnityProjectExporter /// The representing where this props file will be written. ICommonPropsExporter CreateCommonPropsExporter(FileInfo path); + /// + /// Creates an exporter for the top-level dependencies project that is responsible for bringing in the MSB4U resolved dependencies into the Unity project. + /// + /// The path to the project output. + /// The path to the generated project folder. + ITopLevelDependenciesProjectExporter CreateTopLevelDependenciesProjectExporter(FileInfo projectPath, DirectoryInfo generatedProjectFolder); + /// /// Creates the platform props file exporter. /// diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedCommonPropsExporter.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedCommonPropsExporter.cs index 2261f40..909a444 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedCommonPropsExporter.cs +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedCommonPropsExporter.cs @@ -7,7 +7,7 @@ namespace Microsoft.Build.Unity.ProjectGeneration.Exporters.TemplatedExporter { - internal class TemplatedCommonPropsExporter : TemplatedExporterBase, ICommonPropsExporter + internal class TemplatedCommonPropsExporter : ICommonPropsExporter { private const string UnityMajorVersionToken = "UNITY_MAJOR_VERSION"; private const string UnityMinorVersionToken = "UNITY_MINOR_VERSION"; @@ -16,6 +16,9 @@ internal class TemplatedCommonPropsExporter : TemplatedExporterBase, ICommonProp private const string GeneratedOutputDirectoryToken = "GENERATED_OUTPUT_DIRECTORY"; private const string UnityProjectAssetsDirectoryToken = "UNITY_PROJECT_ASSETS_PATH"; + private readonly FileTemplate fileTemplate; + private readonly FileInfo exportPath; + public string UnityMajorVersion { get; set; } public string UnityMinorVersion { get; set; } @@ -29,18 +32,23 @@ internal class TemplatedCommonPropsExporter : TemplatedExporterBase, ICommonProp public DirectoryInfo GeneratedProjectOutputPath { get; set; } internal TemplatedCommonPropsExporter(FileTemplate fileTemplate, FileInfo exportPath) - : base(fileTemplate, exportPath) { + this.fileTemplate = fileTemplate; + this.exportPath = exportPath; } - protected override void Export(TemplatedWriter writer) + public void Write() { + TemplatedWriter writer = new TemplatedWriter(fileTemplate); + writer.Write(UnityMajorVersionToken, UnityMajorVersion); writer.Write(UnityMinorVersionToken, UnityMinorVersion); writer.Write(CurrentUnityPlatformToken, CurrentUnityPlatform); writer.Write(CurrentTargetFrameworkToken, CurrentTargetFramework); writer.Write(UnityProjectAssetsDirectoryToken, UnityProjectAssetsDirectory.FullName); writer.Write(GeneratedOutputDirectoryToken, GeneratedProjectOutputPath.FullName); + + writer.Export(exportPath); } } } diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedExporterBase.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedExporterBase.cs deleted file mode 100644 index 1e76792..0000000 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedExporterBase.cs +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. See LICENSE in the project root for license information. - -#if UNITY_EDITOR -using Microsoft.Build.Unity.ProjectGeneration.Templates; -using System.IO; - -namespace Microsoft.Build.Unity.ProjectGeneration.Exporters.TemplatedExporter -{ - /// - /// Base class for file based exporters. - /// - internal abstract class TemplatedExporterBase - { - private readonly FileTemplate templateFile; - private readonly FileInfo exportPath; - - protected TemplatedExporterBase(FileTemplate templateFile, FileInfo exportPath) - { - this.templateFile = templateFile; - this.exportPath = exportPath; - } - - /// - /// Writes out the template data. - /// - public void Write() - { - // Ensure the parent directories are created - Directory.CreateDirectory(exportPath.Directory.FullName); - - TemplateReplacementSet replacementSet = templateFile.Root.CreateReplacementSet(); - - Export(new TemplatedWriter(templateFile.Root, replacementSet)); - - templateFile.Write(exportPath.FullName, replacementSet); - } - - /// - /// Override this method in a derived class to perform the export. - /// - /// The writer to use to export. - protected abstract void Export(TemplatedWriter writer); - } -} -#endif \ No newline at end of file diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedPlatformPropsExporter.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedPlatformPropsExporter.cs index e7762ea..783ccc3 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedPlatformPropsExporter.cs +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedPlatformPropsExporter.cs @@ -12,7 +12,7 @@ namespace Microsoft.Build.Unity.ProjectGeneration.Exporters.TemplatedExporter /// /// A class for exporting platform props using templates. /// - internal class TemplatedPlatformPropsExporter : TemplatedExporterBase, IPlatformPropsExporter + internal class TemplatedPlatformPropsExporter : IPlatformPropsExporter { private const string TargetFrameworkToken = "TARGET_FRAMEWORK"; private const string DefineConstantsToken = "PLATFORM_COMMON_DEFINE_CONSTANTS"; @@ -22,6 +22,9 @@ internal class TemplatedPlatformPropsExporter : TemplatedExporterBase, IPlatform private const string CommonReferencesSubTemplateReferenceToken = "REFERENCE"; private const string CommonReferencesSubTemplateHintPathToken = "HINT_PATH"; + private readonly FileTemplate fileTemplate; + private readonly FileInfo exportPath; + public string TargetFramework { get; set; } public HashSet DefineConstants { get; } = new HashSet(); // Guess at default size @@ -31,13 +34,15 @@ internal class TemplatedPlatformPropsExporter : TemplatedExporterBase, IPlatform public Dictionary References { get; } = new Dictionary(250); // Guess at default size public TemplatedPlatformPropsExporter(FileTemplate fileTemplate, FileInfo exportPath) - : base(fileTemplate, exportPath) { - + this.fileTemplate = fileTemplate; + this.exportPath = exportPath; } - protected override void Export(TemplatedWriter writer) + public void Write() { + TemplatedWriter writer = new TemplatedWriter(fileTemplate); + writer.Write(TargetFrameworkToken, TargetFramework, optional: true); writer.Write(DefineConstantsToken, DefineConstants); @@ -49,7 +54,13 @@ protected override void Export(TemplatedWriter writer) subTemplateWriter.Write(CommonReferencesSubTemplateReferenceToken, reference.Key); subTemplateWriter.Write(CommonReferencesSubTemplateHintPathToken, reference.Value.LocalPath); } + + OnWrite(writer); + + writer.Export(exportPath); } + + protected virtual void OnWrite(TemplatedWriter writer) { } } } #endif \ No newline at end of file diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedTopLevelDependenciesProjectExporter.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedTopLevelDependenciesProjectExporter.cs new file mode 100644 index 0000000..b8dd815 --- /dev/null +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedTopLevelDependenciesProjectExporter.cs @@ -0,0 +1,67 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +#if UNITY_EDITOR +using Microsoft.Build.Unity.ProjectGeneration.Templates; +using System; +using System.Collections.Generic; +using System.IO; + +namespace Microsoft.Build.Unity.ProjectGeneration.Exporters.TemplatedExporter +{ + /// + /// A class for exporting platform props using templates. + /// + internal class TemplatedTopLevelDependenciesProjectExporter : ITopLevelDependenciesProjectExporter + { + private const string ProjectGuidToken = "PROJECT_GUID"; + + private const string ProjectReferenceTemplate = "PROJECT_REFERENCE"; + private const string ProjectReferenceTemplate_ReferenceToken = "REFERENCE"; + private const string ProjectReferenceTemplate_ConditionToken = "CONDITION"; + + private readonly FileTemplate primaryTemplateFile; + private readonly FileTemplate propsTemplateFile; + private readonly FileTemplate targetsTemplateFile; + + private readonly FileInfo primaryExportPath; + private readonly FileInfo propsExportPath; + private readonly FileInfo targetsExportPath; + + public Guid Guid { get; set; } + + public HashSet References { get; } = new HashSet(); + + public TemplatedTopLevelDependenciesProjectExporter(FileTemplate primaryTemplateFile, FileTemplate propsTemplateFile, FileTemplate targetsTemplateFile, + FileInfo primaryExportPath, FileInfo propsExportPath, FileInfo targetsExportPath) + { + this.primaryTemplateFile = primaryTemplateFile; + this.propsTemplateFile = propsTemplateFile; + this.targetsTemplateFile = targetsTemplateFile; + + this.primaryExportPath = primaryExportPath; + this.propsExportPath = propsExportPath; + this.targetsExportPath = targetsExportPath; + } + + public void Write() + { + TemplatedWriter propsWriter = new TemplatedWriter(propsTemplateFile); + + propsWriter.Write(ProjectGuidToken, Guid.ToString().ToUpper()); + + foreach (ProjectReference projectReference in References) + { + TemplatedWriter referenceWriter = propsWriter.CreateWriterFor(ProjectReferenceTemplate); + referenceWriter.Write(ProjectReferenceTemplate_ReferenceToken, projectReference.ReferencePath.LocalPath); + referenceWriter.Write(ProjectReferenceTemplate_ConditionToken, projectReference.Condition ?? string.Empty); + } + + propsWriter.Export(propsExportPath); + + new TemplatedWriter(primaryTemplateFile).Export(primaryExportPath); + new TemplatedWriter(targetsTemplateFile).Export(targetsExportPath); + } + } +} +#endif \ No newline at end of file diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedTopLevelDependenciesProjectExporter.cs.meta b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedTopLevelDependenciesProjectExporter.cs.meta new file mode 100644 index 0000000..0a4282d --- /dev/null +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedTopLevelDependenciesProjectExporter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9b823f92863e07840b7e9c72899e0562 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedUnityProjectExporter.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedUnityProjectExporter.cs index 6bfc500..b233561 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedUnityProjectExporter.cs +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedUnityProjectExporter.cs @@ -270,8 +270,6 @@ public void ExportSolution(UnityProjectInfo unityProjectInfo, MSBuildToolsConfig ExportProject(unityProjectInfo, project); } - GenerateTopLevelDependenciesProject(unityProjectInfo, config.DependenciesProjectGuid); - // Delete before we write to minimize chance of just deleting in case above fails if (File.Exists(solutionFilePath)) { @@ -616,39 +614,14 @@ private void ProcessProjects(UnityProjectInfo unityProjectInfo, MSBuildToolsConf } } - private void GenerateTopLevelDependenciesProject(UnityProjectInfo unityProjectInfo, Guid dependenciesProjectGuid) + public ITopLevelDependenciesProjectExporter CreateTopLevelDependenciesProjectExporter(FileInfo projectPath, DirectoryInfo generatedProjectFolder) { - string projectPath = GetProjectFilePath(Utilities.AssetPath, "Dependencies"); - string propsPath = GetProjectFilePath(generatedOutputFolder.FullName, "Dependencies").Replace(".csproj", ".g.props"); - string targetsPath = GetProjectFilePath(generatedOutputFolder.FullName, "Dependencies").Replace(".csproj", ".g.targets"); - - ITemplatePart propsFileTemplate = dependenciesPropsTemplate.Root; - ITemplatePart projectReferenceTemplate = propsFileTemplate.Templates["PROJECT_REFERENCE"]; - - TemplateReplacementSet replacementSet = propsFileTemplate.CreateReplacementSet(); - - propsFileTemplate.Tokens["PROJECT_GUID"].AssignValue(replacementSet, dependenciesProjectGuid.ToString().ToUpper()); - - // We use this to emulate the platform support for all - Dictionary allPlatforms = unityProjectInfo.AvailablePlatforms.ToDictionary(t => t.BuildTarget, t => t); - foreach (CSProjectInfo projectInfo in unityProjectInfo.CSProjects.Values) - { - List platformConditions = GetPlatformConditions(allPlatforms, projectInfo.InEditorPlatforms.Keys); - ProcessProjectDependency(replacementSet, projectReferenceTemplate, projectInfo, platformConditions); - } + FileInfo propsFilePath = new FileInfo(Path.Combine(generatedProjectFolder.FullName, projectPath.Name.Replace(".csproj", ".g.props"))); + FileInfo targetsFilePath = new FileInfo(Path.Combine(generatedProjectFolder.FullName, projectPath.Name.Replace(".csproj", ".g.targets"))); - dependenciesPropsTemplate.Write(propsPath, replacementSet); - - ITemplatePart targetsFileTemplate = dependenciesTargetsTemplate.Root; - - dependenciesTargetsTemplate.Write(targetsPath, propsFileTemplate.CreateReplacementSet()); - - if (!File.Exists(projectPath)) - { - dependenciesProjectTemplate.Write(projectPath, dependenciesProjectTemplate.Root.CreateReplacementSet()); - } + return new TemplatedTopLevelDependenciesProjectExporter(dependenciesProjectTemplate, dependenciesPropsTemplate, dependenciesTargetsTemplate, projectPath, propsFilePath, targetsFilePath); } - + private void ProcessSolutionFolders(ITemplatePart rootTemplatePart, TemplateReplacementSet parentReplacementSet, List> folderNestedItems, HashSet generatedItems, SolutionFileInfo solutionFileInfo) { ITemplatePart folderTemplate = rootTemplatePart.Templates["FOLDER"]; diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedWSAPlayerPlatformPropsExporter.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedWSAPlayerPlatformPropsExporter.cs index b754d9b..f3e00d9 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedWSAPlayerPlatformPropsExporter.cs +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedWSAPlayerPlatformPropsExporter.cs @@ -25,9 +25,9 @@ public TemplatedWSAPlayerPlatformPropsExporter(FileTemplate fileTemplate, FileIn } - protected override void Export(TemplatedWriter writer) + protected override void OnWrite(TemplatedWriter writer) { - base.Export(writer); + base.OnWrite(writer); writer.Write(TargetUWPVersionToken, TargetUWPVersion); writer.Write(MinimumUWPVersionToken, MinimumUWPVersion); diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedWriter.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedWriter.cs index 7286ddf..2f42c6d 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedWriter.cs +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedWriter.cs @@ -3,7 +3,9 @@ #if UNITY_EDITOR using Microsoft.Build.Unity.ProjectGeneration.Templates; +using System; using System.Collections.Generic; +using System.IO; namespace Microsoft.Build.Unity.ProjectGeneration.Exporters.TemplatedExporter { @@ -12,14 +14,21 @@ namespace Microsoft.Build.Unity.ProjectGeneration.Exporters.TemplatedExporter /// internal ref struct TemplatedWriter { + private readonly FileTemplate fileTemplate; private readonly ITemplatePart template; private readonly TemplateReplacementSet replacementSet; /// /// Creates a new instance of the writer. /// - internal TemplatedWriter(ITemplatePart template, TemplateReplacementSet replacementSet) + internal TemplatedWriter(FileTemplate fileTemplate) + : this(fileTemplate, fileTemplate.Root, fileTemplate.Root.CreateReplacementSet()) { + } + + private TemplatedWriter(FileTemplate fileTemplate, ITemplatePart template, TemplateReplacementSet replacementSet) + { + this.fileTemplate = fileTemplate; this.template = template; this.replacementSet = replacementSet; } @@ -47,6 +56,19 @@ internal void Write(string token, string value, bool optional = false) Write(token, (object)value, optional); } + internal void Export(FileInfo exportPath) + { + if (fileTemplate == null) + { + throw new InvalidOperationException("Export must be called on the root templated writer."); + } + + // Ensure the parent directories are created + Directory.CreateDirectory(exportPath.Directory.FullName); + + fileTemplate.Write(exportPath.FullName, replacementSet); + } + /// /// Creates a writer for a sub-template. /// @@ -55,7 +77,7 @@ internal void Write(string token, string value, bool optional = false) internal TemplatedWriter CreateWriterFor(string subTemplateName) { ITemplatePart subTemplate = template.Templates[subTemplateName]; - return new TemplatedWriter(subTemplate, subTemplate.CreateReplacementSet(replacementSet)); + return new TemplatedWriter(null, subTemplate, subTemplate.CreateReplacementSet(replacementSet)); } private void Write(string token, object value, bool optional) diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/MSBuildTools.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/MSBuildTools.cs index dec5030..6f4d097 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/MSBuildTools.cs +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/MSBuildTools.cs @@ -184,10 +184,6 @@ public void OnActiveBuildTargetChanged(BuildTarget previousTarget, BuildTarget n private static UnityProjectInfo unityProjectInfo; - public static UnityProjectInfo UnityProject => unityProjectInfo ?? (unityProjectInfo = new UnityProjectInfo(SupportedBuildTargets, Config)); - - public static CompilationPlatformInfo CurrentPlayerPlatform => unityProjectInfo?.CurrentPlayerPlatform ?? UnityProjectInfo.GetCurrentPlayerPlatform(); - private static IUnityProjectExporter exporter = null; private static IUnityProjectExporter Exporter => exporter ?? (exporter = new TemplatedUnityProjectExporter(new DirectoryInfo(Utilities.MSBuildProjectFolder), @@ -237,7 +233,7 @@ public static void GenerateSDKProjects() public static void RegenerateSDKProjects() { - RegenerateEverything(reparseUnityData: true); + RegenerateEverything(unityProjectInfo = new UnityProjectInfo(SupportedBuildTargets, Config, true)); Debug.Log($"{nameof(RegenerateSDKProjects)} Completed Succesfully."); } @@ -291,20 +287,28 @@ private static void RefreshGeneratedOutput(bool forceGenerateEverything) bool doesTokenFileExist = File.Exists(TokenFilePath); + // We regenerate everything if: + // - We are forced to + // - AutoGenerateEnabled and token file doesn't exist or shouldClean is true + bool regenerateEverything = forceGenerateEverything || (Config.AutoGenerateEnabled && (!doesTokenFileExist || shouldClean)); + + if (regenerateEverything || unityProjectInfo == null) + { + // Create the project info only if it's null or we need to regenerate + unityProjectInfo = new UnityProjectInfo(SupportedBuildTargets, Config, regenerateEverything); + } + // We regenerate the common "directory" props file under the following conditions: // - Token file doesn't exist which means editor was just started // - EditorPrefs currentBuildTarget or targetFramework is different from current ones (same as for executing a clean) if (shouldClean || !doesTokenFileExist) { - MSBuildUnityProjectExporter.ExportCommonPropsFile(Exporter, CurrentPlayerPlatform); + MSBuildUnityProjectExporter.ExportCommonPropsFile(Exporter, unityProjectInfo.CurrentPlayerPlatform); } - // We regenerate everything if: - // - We are forced to - // - AutoGenerateEnabled and token file doesn't exist or shouldClean is true - if (forceGenerateEverything || (Config.AutoGenerateEnabled && (!doesTokenFileExist || shouldClean))) + if (regenerateEverything) { - RegenerateEverything(true); + RegenerateEverything(unityProjectInfo); } if (!doesTokenFileExist) @@ -323,20 +327,20 @@ private static void RefreshGeneratedOutput(bool forceGenerateEverything) } } - private static void ExportCoreUnityPropFiles() + private static void ExportCoreUnityPropFiles(UnityProjectInfo unityProjectInfo) { - foreach (CompilationPlatformInfo platform in UnityProject.AvailablePlatforms) + foreach (CompilationPlatformInfo platform in unityProjectInfo.AvailablePlatforms) { // Check for specialized template, otherwise get the common one MSBuildUnityProjectExporter.ExportCoreUnityPropFile(Exporter, platform, true); MSBuildUnityProjectExporter.ExportCoreUnityPropFile(Exporter, platform, false); } - MSBuildUnityProjectExporter.ExportCoreUnityPropFile(Exporter, UnityProject.EditorPlatform, true); + MSBuildUnityProjectExporter.ExportCoreUnityPropFile(Exporter, unityProjectInfo.EditorPlatform, true); } - private static void RegenerateEverything(bool reparseUnityData) + private static void RegenerateEverything(UnityProjectInfo unityProjectInfo) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); @@ -357,21 +361,16 @@ private static void RegenerateEverything(bool reparseUnityData) Directory.CreateDirectory(Utilities.MSBuildProjectFolder); } - if (reparseUnityData) - { - unityProjectInfo?.Dispose(); - unityProjectInfo = null; - } - postCleanupAndCopyStamp = stopwatch.ElapsedMilliseconds; propsFileGenerationStart = stopwatch.ElapsedMilliseconds; - MSBuildUnityProjectExporter.ExportCommonPropsFile(Exporter, UnityProject.CurrentPlayerPlatform); - ExportCoreUnityPropFiles(); + MSBuildUnityProjectExporter.ExportCommonPropsFile(Exporter, unityProjectInfo.CurrentPlayerPlatform); + ExportCoreUnityPropFiles(unityProjectInfo); propsFileGenerationEnd = stopwatch.ElapsedMilliseconds; solutionExportStart = stopwatch.ElapsedMilliseconds; - Exporter.ExportSolution(UnityProject, Config); + Exporter.ExportSolution(unityProjectInfo, Config); + MSBuildUnityProjectExporter.ExportTopLevelDependenciesProject(Exporter, new DirectoryInfo(Utilities.MSBuildProjectFolder), unityProjectInfo); solutionExportEnd = stopwatch.ElapsedMilliseconds; foreach (string otherFile in TemplateFiles.Instance.OtherFiles) @@ -382,7 +381,7 @@ private static void RegenerateEverything(bool reparseUnityData) string buildProjectsFile = "BuildProjects.proj"; if (!File.Exists(Path.Combine(Utilities.MSBuildOutputFolder, buildProjectsFile))) { - GenerateBuildProjectsFile(buildProjectsFile, Exporter.GetSolutionFilePath(UnityProject), UnityProject.AvailablePlatforms); + GenerateBuildProjectsFile(buildProjectsFile, Exporter.GetSolutionFilePath(unityProjectInfo), unityProjectInfo.AvailablePlatforms); } } finally diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/MSBuildUnityProjectExporter.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/MSBuildUnityProjectExporter.cs index 93f2c6b..1cc4aa1 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/MSBuildUnityProjectExporter.cs +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/MSBuildUnityProjectExporter.cs @@ -4,6 +4,7 @@ #if UNITY_EDITOR using Microsoft.Build.Unity.ProjectGeneration.Exporters; using System; +using System.Collections.Generic; using System.IO; using System.Linq; using UnityEditor; @@ -16,6 +17,8 @@ namespace Microsoft.Build.Unity.ProjectGeneration /// public static class MSBuildUnityProjectExporter { + private const string MSBuildFileSuffix = "msb4u"; + /// /// Exports the core Unity props file. /// @@ -75,6 +78,38 @@ public static void ExportCommonPropsFile(IUnityProjectExporter exporter, Compila propsExporter.Write(); } + public static void ExportTopLevelDependenciesProject(IUnityProjectExporter exporter, MSBuildToolsConfig config, DirectoryInfo generatedProjectFolder, UnityProjectInfo unityProjectInfo) + { + string projectPath = GetProjectFilePath(Utilities.AssetPath, "Dependencies"); + ITopLevelDependenciesProjectExporter projectExporter = exporter.CreateTopLevelDependenciesProjectExporter(new FileInfo(projectPath), generatedProjectFolder); + + projectExporter.Guid = config.DependenciesProjectGuid; + + if (unityProjectInfo != null) + { + Dictionary allPlatforms = unityProjectInfo.AvailablePlatforms.ToDictionary(t => t.BuildTarget, t => t); + foreach (CSProjectInfo projectInfo in unityProjectInfo.CSProjects.Values) + { + List platformConditions = GetPlatformConditions(allPlatforms, projectInfo.InEditorPlatforms.Keys); + projectExporter.References.Add(new ProjectReference() + { + ReferencePath = new Uri(GetProjectPath(projectInfo, generatedProjectFolder).FullName), + Condition = platformConditions.Count == 0 ? "false" : string.Join(" OR ", platformConditions) + }); + } + } + + foreach (string otherProjectFile in unityProjectInfo.ExistingCSProjects) + { + projectExporter.References.Add(new ProjectReference() + { + ReferencePath = new Uri(otherProjectFile) + }); + } + + projectExporter.Write(); + } + private static IPlatformPropsExporter CreateWSAPlayerExporter(IUnityProjectExporter exporter, FileInfo outputFile, ScriptingBackend scriptingBackend) { IWSAPlayerPlatformPropsExporter uwpExporter = exporter.CreateWSAPlayerPlatformPropsExporter(outputFile, scriptingBackend); @@ -96,6 +131,50 @@ private static IPlatformPropsExporter CreateWSAPlayerExporter(IUnityProjectExpor return uwpExporter; } + + private static string GetProjectFilePath(DirectoryInfo directory, CSProjectInfo projectInfo) + { + return GetProjectFilePath(directory.FullName, projectInfo.Name); + } + + private static string GetProjectFilePath(string directory, string projectName) + { + return Path.Combine(directory, $"{projectName}.{MSBuildFileSuffix}.csproj"); + } + + private static List GetPlatformConditions(IReadOnlyDictionary platforms, IEnumerable dependencyPlatforms) + { + List toReturn = new List(); + + foreach (BuildTarget platform in dependencyPlatforms) + { + if (platforms.TryGetValue(platform, out CompilationPlatformInfo platformInfo)) + { + string platformName = platformInfo.Name; + toReturn.Add($"'$(UnityPlatform)' == '{platformName}'"); + } + } + + return toReturn; + } + + /// + public static FileInfo GetProjectPath(CSProjectInfo projectInfo, DirectoryInfo generatedProjectFolder) + { + switch (projectInfo.AssemblyDefinitionInfo.AssetLocation) + { + case AssetLocation.BuiltInPackage: + case AssetLocation.External: + case AssetLocation.PackageLibraryCache: + return new FileInfo(GetProjectFilePath(generatedProjectFolder, projectInfo)); + case AssetLocation.Project: + case AssetLocation.Package: + return new FileInfo(GetProjectFilePath(projectInfo.AssemblyDefinitionInfo.Directory, projectInfo)); + default: + throw new InvalidOperationException("The project's assembly definition file is in an unknown location."); + } + } + } } #endif \ No newline at end of file diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/UnityProjectInfo.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/UnityProjectInfo.cs index 37da061..8c6f53a 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/UnityProjectInfo.cs +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/UnityProjectInfo.cs @@ -44,14 +44,6 @@ public class UnityProjectInfo : IDisposable { "UnityEngine.TestRunner", new List(){ "UNITY_INCLUDE_TESTS" } }, }; - public static CompilationPlatformInfo GetCurrentPlayerPlatform() - { - return CompilationPlatformInfo.GetCompilationPlatform( - CompilationPipeline.GetAssemblyDefinitionPlatforms() - .First(t => t.BuildTarget == EditorUserBuildSettings.activeBuildTarget)); - } - - /// /// Gets the name of this Unity Project. /// @@ -87,15 +79,37 @@ public static CompilationPlatformInfo GetCurrentPlayerPlatform() /// public IReadOnlyCollection WinMDs { get; private set; } - public UnityProjectInfo(Dictionary supportedBuildTargets, MSBuildToolsConfig config) + /// + /// Existing projects that are found under the Assets folder, or as part of a UPM Package. + /// + public IReadOnlyCollection ExistingCSProjects { get; private set; } + + /// + /// Parses the current state of the Unity project. + /// + /// BuildTargets that are considered supported. + /// Config for MSBuildTools. + /// If this is false, UnityProjectInfo will parse only the minimum required information about current project. Includes: . + public UnityProjectInfo(Dictionary supportedBuildTargets, MSBuildToolsConfig config, bool performCompleteParse = true) { - AvailablePlatforms = new ReadOnlyCollection(CompilationPipeline.GetAssemblyDefinitionPlatforms() - .Where(t => Utilities.IsPlatformInstalled(t.BuildTarget)) - .Where(t => supportedBuildTargets.ContainsKey(t.BuildTarget)) - .Select(CompilationPlatformInfo.GetCompilationPlatform) - .OrderBy(t => t.Name).ToList()); + if (performCompleteParse) + { + AvailablePlatforms = new ReadOnlyCollection(CompilationPipeline.GetAssemblyDefinitionPlatforms() + .Where(t => Utilities.IsPlatformInstalled(t.BuildTarget)) + .Where(t => supportedBuildTargets.ContainsKey(t.BuildTarget)) + .Select(CompilationPlatformInfo.GetCompilationPlatform) + .OrderBy(t => t.Name).ToList()); + + EditorPlatform = CompilationPlatformInfo.GetEditorPlatform(); - EditorPlatform = CompilationPlatformInfo.GetEditorPlatform(); + CurrentPlayerPlatform = AvailablePlatforms.First(t => t.BuildTarget == EditorUserBuildSettings.activeBuildTarget); + } + else + { + CurrentPlayerPlatform = CompilationPlatformInfo.GetCompilationPlatform( + CompilationPipeline.GetAssemblyDefinitionPlatforms() + .First(t => t.BuildTarget == EditorUserBuildSettings.activeBuildTarget)); + } UnityProjectName = Application.productName; @@ -104,10 +118,12 @@ public UnityProjectInfo(Dictionary supportedBuildTargets, M UnityProjectName = "UnityProject"; } - RefreshPlugins(); - RefreshProjects(config); + RefreshPlugins(performCompleteParse); - CurrentPlayerPlatform = AvailablePlatforms.First(t => t.BuildTarget == EditorUserBuildSettings.activeBuildTarget); + if (performCompleteParse) + { + RefreshProjects(config); + } } public void Dispose() @@ -115,21 +131,46 @@ public void Dispose() // This will be used soon } - public void RefreshPlugins() + public void RefreshPlugins(bool performCompleteParse) { - ScanForReferences(out List plugins, out List winmds); - Plugins = new ReadOnlyCollection(plugins); + List plugins = new List(); + List winmds = new List(); + List existingCSProjectFiles = new List(); + + Dictionary> scanMap = new Dictionary>(); + + if (performCompleteParse) + { + scanMap.Add(".dll", (path, guid) => plugins.Add(new PluginAssemblyInfo(this, guid, path, Utilities.IsManagedAssembly(path) ? PluginType.Managed : PluginType.Native))); + scanMap.Add(".winmd", (path, guid) => winmds.Add(new WinMDInfo(this, guid, path))); + } - foreach (PluginAssemblyInfo plugin in Plugins) + scanMap.Add(".csproj", (path, guid) => { - if (plugin.Type == PluginType.Native) + if (!path.EndsWith(".msb4u.csproj")) { - // Logging will be re-enabled with robust update holistically across MSB4U: https://github.com/microsoft/MSBuildForUnity/issues/75 - // Debug.Log($"Native plugin {plugin.ReferencePath.AbsolutePath} not yet supported for MSBuild project."); + existingCSProjectFiles.Add(path); + } + }); + + ScanAndProcessKnownFolders(scanMap); + + if (performCompleteParse) + { + Plugins = new ReadOnlyCollection(plugins); + WinMDs = new ReadOnlyCollection(winmds); + + foreach (PluginAssemblyInfo plugin in Plugins) + { + if (plugin.Type == PluginType.Native) + { + // Logging will be re-enabled with robust update holistically across MSB4U: https://github.com/microsoft/MSBuildForUnity/issues/75 + // Debug.Log($"Native plugin {plugin.ReferencePath.AbsolutePath} not yet supported for MSBuild project."); + } } } - WinMDs = new ReadOnlyCollection(winmds); + ExistingCSProjects = new ReadOnlyCollection(existingCSProjectFiles); } public void RefreshProjects(MSBuildToolsConfig config) @@ -395,67 +436,40 @@ private CSProjectInfo GetProjectInfo(Dictionary projectsM return toReturn; } - private void ScanForReferences(out List plugins, out List winmds) + private IEnumerable> ScanForFiles(string folder, IEnumerable extensions) { - plugins = new List(); - winmds = new List(); - - IEnumerable assetReferences = Directory.EnumerateFiles(Utilities.AssetPath, "*.*", SearchOption.AllDirectories) - .Where(file => file.ToLower().EndsWith(".dll") || file.ToLower().EndsWith(".winmd")); - foreach (string assetPath in assetReferences) + HashSet extensionSet = new HashSet(extensions.Select(t => t.ToLower())); + foreach (string file in Directory.EnumerateFiles(folder, "*.*", SearchOption.AllDirectories)) { - string assetRelativePath = Utilities.GetAssetsRelativePathFrom(assetPath); - PluginImporter importer = (PluginImporter)AssetImporter.GetAtPath(assetRelativePath); - if (importer == null) - { - Debug.LogWarning($"Didn't get an importer for '{assetRelativePath}', most likely due to it being in a Unity hidden folder (prefixed by a .)"); - continue; - } - - if (assetRelativePath.EndsWith(".dll")) + string extension = Path.GetExtension(file); + if (extensionSet.Contains(extension)) { - PluginAssemblyInfo toAdd = new PluginAssemblyInfo(this, Guid.Parse(AssetDatabase.AssetPathToGUID(assetRelativePath)), assetPath, importer.isNativePlugin ? PluginType.Native : PluginType.Managed); - plugins.Add(toAdd); - } - else if (assetRelativePath.EndsWith(".winmd")) - { - WinMDInfo toAdd = new WinMDInfo(this, Guid.Parse(AssetDatabase.AssetPathToGUID(assetRelativePath)), assetPath); - winmds.Add(toAdd); + yield return new KeyValuePair(extension, file); } } + } - IEnumerable packageReferences = Directory.EnumerateFiles(Utilities.PackageLibraryCachePath, "*.*", SearchOption.AllDirectories) - .Where(file => file.ToLower().EndsWith(".dll") || file.ToLower().EndsWith(".winmd")); - foreach (string packagePath in packageReferences) - { - string metaPath = packagePath + ".meta"; + private void ScanAndProcessKnownFolders(Dictionary> extensionCallbacks) + { + ScanAndProcessFiles(Utilities.AssetPath, extensionCallbacks); + ScanAndProcessFiles(Utilities.PackageLibraryCachePath, extensionCallbacks); + } - if (!File.Exists(metaPath)) - { - Debug.LogWarning($"Skipping a packages reference that didn't have an associated meta: '{packagePath}'"); - continue; - } - Guid guid; - using (StreamReader reader = new StreamReader(metaPath)) + private void ScanAndProcessFiles(string folder, Dictionary> extensionCallbacks) + { + foreach (KeyValuePair pair in ScanForFiles(folder, extensionCallbacks.Keys)) + { + if (!Utilities.IsVisibleToUnity(pair.Value)) { - string guidLine = reader.ReadUntil("guid"); - if (!Guid.TryParse(guidLine.Split(':')[1].Trim(), out guid)) - { - Debug.LogWarning($"Skipping a packages reference that didn't have a valid guid in the .meta file: '{packagePath}'"); - continue; - } + Debug.LogWarning($"Skipping processing asset '{pair.Value}' as it's not visible to Unity."); } - - if (packagePath.EndsWith(".dll")) + else if (!Utilities.TryGetGuidForAsset(new FileInfo(pair.Value), out Guid guid)) { - bool isManaged = Utilities.IsManagedAssembly(packagePath); - PluginAssemblyInfo toAdd = new PluginAssemblyInfo(this, guid, packagePath, isManaged ? PluginType.Managed : PluginType.Native); - plugins.Add(toAdd); + Debug.LogWarning($"Skipping processing asset '{pair.Value}' as no meta file was found, or guid parsed."); } - else if (packagePath.EndsWith(".winmd")) + else { - WinMDInfo toAdd = new WinMDInfo(this, guid, packagePath); - winmds.Add(toAdd); + extensionCallbacks[pair.Key](pair.Value, guid); } } } diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Utilities.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Utilities.cs index ed05053..81de19a 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Utilities.cs +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Utilities.cs @@ -110,6 +110,49 @@ public static string GetFullPathFromPackagesRelative(string path) throw new InvalidOperationException("Not a path known to be relative to project's Package folder."); } + /// + /// Gets whether the given path is visible to Unity. + /// + public static bool IsVisibleToUnity(string path) + { + return GetAssetImporter(path) != null; + } + + private static AssetImporter GetAssetImporter(string path) + { + path = Path.GetFullPath(path); + + string relativePath; + + if (path.StartsWith(AssetPath)) + { + relativePath = path.Replace(AssetPath, AssetsFolderName); + } + else if (path.StartsWith(PackageLibraryCachePath)) + { + relativePath = path.Replace(PackageLibraryCachePath, PackagesFolderName); + // Relative path will contain packages with their version "@x.y.z", so we need to strip that + // Method is to split on '@' into 'Packages\com.company.package' and 'x.y.z\' and then substring to first '\' + if (relativePath.Contains('@')) + { + string[] parts = relativePath.Split('@'); + relativePath = parts[0] + parts[1].Substring(parts[1].IndexOf('\\')); + } + } + else if (path.Contains(PackagesPath)) + { + relativePath = path.Replace(PackagesPath, PackagesFolderName); + } + else + { + return null; + } + + return string.IsNullOrEmpty(relativePath) + ? null + : AssetImporter.GetAtPath(relativePath); + } + /// /// Parses a .meta file to extract a guid for the asset. /// @@ -268,6 +311,17 @@ public static void AddRange(this ICollection collection, IEnumerable it /// True if a managed assembly. public static bool IsManagedAssembly(string assemblyPath) { + assemblyPath = Path.GetFullPath(assemblyPath); + + if (GetAssetImporter(assemblyPath) is PluginImporter importer) + { + return !importer.isNativePlugin; + } + else + { + + } + using (Stream fileStream = new FileStream(assemblyPath, FileMode.Open, FileAccess.Read)) using (BinaryReader binaryReader = new BinaryReader(fileStream)) { From 6a675c7cfc09c62dc1e9d2bb6ef8bf5ec395e16a Mon Sep 17 00:00:00 2001 From: Andrei Borodin Date: Tue, 21 Jan 2020 16:57:55 -0800 Subject: [PATCH 2/7] Fixed typo. --- .../Editor/ProjectGenerator/Scripts/Utilities.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Utilities.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Utilities.cs index 81de19a..53e1255 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Utilities.cs +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Utilities.cs @@ -317,10 +317,6 @@ public static bool IsManagedAssembly(string assemblyPath) { return !importer.isNativePlugin; } - else - { - - } using (Stream fileStream = new FileStream(assemblyPath, FileMode.Open, FileAccess.Read)) using (BinaryReader binaryReader = new BinaryReader(fileStream)) From 4ef4edb5d1667a92d210a90a9c30ba79e8360381 Mon Sep 17 00:00:00 2001 From: Andrei Borodin Date: Wed, 22 Jan 2020 11:25:31 -0800 Subject: [PATCH 3/7] Responding to Chris' comments. --- .../ITopLevelDependenciesProjectExporter.cs | 2 ++ .../ProjectGenerator/Scripts/MSBuildTools.cs | 4 ++-- .../Scripts/UnityProjectInfo.cs | 23 ++++++++----------- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/ITopLevelDependenciesProjectExporter.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/ITopLevelDependenciesProjectExporter.cs index 27d3315..0ade24d 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/ITopLevelDependenciesProjectExporter.cs +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/ITopLevelDependenciesProjectExporter.cs @@ -21,11 +21,13 @@ public struct ProjectReference /// public string Condition { get; set; } + /// public override int GetHashCode() { return ReferencePath?.GetHashCode() ?? 0; } + /// public override bool Equals(object obj) { return obj is ProjectReference other && Equals(ReferencePath, other.ReferencePath); diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/MSBuildTools.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/MSBuildTools.cs index 6f4d097..5cc2e9d 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/MSBuildTools.cs +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/MSBuildTools.cs @@ -233,7 +233,7 @@ public static void GenerateSDKProjects() public static void RegenerateSDKProjects() { - RegenerateEverything(unityProjectInfo = new UnityProjectInfo(SupportedBuildTargets, Config, true)); + RegenerateEverything(unityProjectInfo = new UnityProjectInfo(SupportedBuildTargets, Config, performCompleteParse: true)); Debug.Log($"{nameof(RegenerateSDKProjects)} Completed Succesfully."); } @@ -370,7 +370,7 @@ private static void RegenerateEverything(UnityProjectInfo unityProjectInfo) solutionExportStart = stopwatch.ElapsedMilliseconds; Exporter.ExportSolution(unityProjectInfo, Config); - MSBuildUnityProjectExporter.ExportTopLevelDependenciesProject(Exporter, new DirectoryInfo(Utilities.MSBuildProjectFolder), unityProjectInfo); + MSBuildUnityProjectExporter.ExportTopLevelDependenciesProject(Exporter, Config, new DirectoryInfo(Utilities.MSBuildProjectFolder), unityProjectInfo); solutionExportEnd = stopwatch.ElapsedMilliseconds; foreach (string otherFile in TemplateFiles.Instance.OtherFiles) diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/UnityProjectInfo.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/UnityProjectInfo.cs index 8c6f53a..fe0406a 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/UnityProjectInfo.cs +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/UnityProjectInfo.cs @@ -16,7 +16,7 @@ namespace Microsoft.Build.Unity.ProjectGeneration /// /// A helper class to parse the state of the current Unity project. /// - public class UnityProjectInfo : IDisposable + public class UnityProjectInfo { /// /// These package references aren't actual packages it appears, manually labeling them for exclusion. @@ -126,11 +126,6 @@ public UnityProjectInfo(Dictionary supportedBuildTargets, M } } - public void Dispose() - { - // This will be used soon - } - public void RefreshPlugins(bool performCompleteParse) { List plugins = new List(); @@ -160,14 +155,14 @@ public void RefreshPlugins(bool performCompleteParse) Plugins = new ReadOnlyCollection(plugins); WinMDs = new ReadOnlyCollection(winmds); - foreach (PluginAssemblyInfo plugin in Plugins) - { - if (plugin.Type == PluginType.Native) - { - // Logging will be re-enabled with robust update holistically across MSB4U: https://github.com/microsoft/MSBuildForUnity/issues/75 - // Debug.Log($"Native plugin {plugin.ReferencePath.AbsolutePath} not yet supported for MSBuild project."); - } - } + // Logging will be re-enabled with robust update holistically across MSB4U: https://github.com/microsoft/MSBuildForUnity/issues/75 + //foreach (PluginAssemblyInfo plugin in Plugins) + //{ + // if (plugin.Type == PluginType.Native) + // { + // Debug.Log($"Native plugin {plugin.ReferencePath.AbsolutePath} not yet supported for MSBuild project."); + // } + //} } ExistingCSProjects = new ReadOnlyCollection(existingCSProjectFiles); From 3f866b6c68871a3b088353a063fcd20e94ad7ada Mon Sep 17 00:00:00 2001 From: Andrei Borodin Date: Wed, 22 Jan 2020 14:26:09 -0800 Subject: [PATCH 4/7] Defaulting package/project references to include contentFiles;build to propogate to top level project --- .../SDKProjectTemplate.g.targets.template | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/MSBuildTemplates/SDKProjectTemplate.g.targets.template b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/MSBuildTemplates/SDKProjectTemplate.g.targets.template index e894440..83e230d 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/MSBuildTemplates/SDKProjectTemplate.g.targets.template +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/MSBuildTemplates/SDKProjectTemplate.g.targets.template @@ -8,6 +8,16 @@ + + + + analyzers + + + none + + + <_GenerateRestoreGraphProjectEntryInputProperties>UnityConfiguration=$(UnityConfiguration);UnityPlatform=$(UnityPlatform);$(_MSB4UPropagateProperties);$(_GenerateRestoreGraphProjectEntryInputProperties) From 1a8dc82619e874c90c1fd4d759ccc405a29b9413 Mon Sep 17 00:00:00 2001 From: Andrei Borodin Date: Wed, 22 Jan 2020 14:53:57 -0800 Subject: [PATCH 5/7] updated how private assets is set --- ...pendenciesProjectTemplate.g.props.template | 2 +- .../ITopLevelDependenciesProjectExporter.cs | 5 +++++ ...atedTopLevelDependenciesProjectExporter.cs | 8 +++++++ .../Scripts/MSBuildUnityProjectExporter.cs | 21 +++++++++---------- 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/MSBuildTemplates/DependenciesProjectTemplate.g.props.template b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/MSBuildTemplates/DependenciesProjectTemplate.g.props.template index 39a289c..86e5238 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/MSBuildTemplates/DependenciesProjectTemplate.g.props.template +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/MSBuildTemplates/DependenciesProjectTemplate.g.props.template @@ -38,7 +38,7 @@ - false + false diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/ITopLevelDependenciesProjectExporter.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/ITopLevelDependenciesProjectExporter.cs index 0ade24d..a259b01 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/ITopLevelDependenciesProjectExporter.cs +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/ITopLevelDependenciesProjectExporter.cs @@ -21,6 +21,11 @@ public struct ProjectReference /// public string Condition { get; set; } + /// + /// Whether this is an MSBuildForUnity reference or not. + /// + public bool IsGenerated { get; set; } + /// public override int GetHashCode() { diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedTopLevelDependenciesProjectExporter.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedTopLevelDependenciesProjectExporter.cs index b8dd815..11cc437 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedTopLevelDependenciesProjectExporter.cs +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedTopLevelDependenciesProjectExporter.cs @@ -20,6 +20,8 @@ internal class TemplatedTopLevelDependenciesProjectExporter : ITopLevelDependenc private const string ProjectReferenceTemplate_ReferenceToken = "REFERENCE"; private const string ProjectReferenceTemplate_ConditionToken = "CONDITION"; + private const string PrivateReferenceTemplate = "PRIVATE_REFERENCE"; + private readonly FileTemplate primaryTemplateFile; private readonly FileTemplate propsTemplateFile; private readonly FileTemplate targetsTemplateFile; @@ -55,6 +57,12 @@ public void Write() TemplatedWriter referenceWriter = propsWriter.CreateWriterFor(ProjectReferenceTemplate); referenceWriter.Write(ProjectReferenceTemplate_ReferenceToken, projectReference.ReferencePath.LocalPath); referenceWriter.Write(ProjectReferenceTemplate_ConditionToken, projectReference.Condition ?? string.Empty); + + if (projectReference.IsGenerated) + { + // Creating this is sufficient for the template to be included in the output + referenceWriter.CreateWriterFor(PrivateReferenceTemplate); + } } propsWriter.Export(propsExportPath); diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/MSBuildUnityProjectExporter.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/MSBuildUnityProjectExporter.cs index 1cc4aa1..f06e1c8 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/MSBuildUnityProjectExporter.cs +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/MSBuildUnityProjectExporter.cs @@ -85,25 +85,24 @@ public static void ExportTopLevelDependenciesProject(IUnityProjectExporter expor projectExporter.Guid = config.DependenciesProjectGuid; - if (unityProjectInfo != null) + Dictionary allPlatforms = unityProjectInfo.AvailablePlatforms.ToDictionary(t => t.BuildTarget, t => t); + foreach (CSProjectInfo projectInfo in unityProjectInfo.CSProjects.Values) { - Dictionary allPlatforms = unityProjectInfo.AvailablePlatforms.ToDictionary(t => t.BuildTarget, t => t); - foreach (CSProjectInfo projectInfo in unityProjectInfo.CSProjects.Values) + List platformConditions = GetPlatformConditions(allPlatforms, projectInfo.InEditorPlatforms.Keys); + projectExporter.References.Add(new ProjectReference() { - List platformConditions = GetPlatformConditions(allPlatforms, projectInfo.InEditorPlatforms.Keys); - projectExporter.References.Add(new ProjectReference() - { - ReferencePath = new Uri(GetProjectPath(projectInfo, generatedProjectFolder).FullName), - Condition = platformConditions.Count == 0 ? "false" : string.Join(" OR ", platformConditions) - }); - } + ReferencePath = new Uri(GetProjectPath(projectInfo, generatedProjectFolder).FullName), + Condition = platformConditions.Count == 0 ? "false" : string.Join(" OR ", platformConditions), + IsGenerated = true + }); } foreach (string otherProjectFile in unityProjectInfo.ExistingCSProjects) { projectExporter.References.Add(new ProjectReference() { - ReferencePath = new Uri(otherProjectFile) + ReferencePath = new Uri(otherProjectFile), + IsGenerated = false }); } From 3847ca4b37c26327273a3e06b00fe4c27c71cd38 Mon Sep 17 00:00:00 2001 From: Andrei Borodin Date: Wed, 22 Jan 2020 15:20:11 -0800 Subject: [PATCH 6/7] Fixing overwriting of Dependencies project. --- .../CrossUnityDependencies.Unity.msb4u.sln | 48 +++++++++---------- .../Assets/Dependencies.msb4u.csproj | 6 +-- ...atedTopLevelDependenciesProjectExporter.cs | 6 ++- 3 files changed, 32 insertions(+), 28 deletions(-) diff --git a/Samples/CrossUnityDependencies.Unity/Assets/CrossUnityDependencies.Unity.msb4u.sln b/Samples/CrossUnityDependencies.Unity/Assets/CrossUnityDependencies.Unity.msb4u.sln index da0d025..80a876f 100644 --- a/Samples/CrossUnityDependencies.Unity/Assets/CrossUnityDependencies.Unity.msb4u.sln +++ b/Samples/CrossUnityDependencies.Unity/Assets/CrossUnityDependencies.Unity.msb4u.sln @@ -118,12 +118,12 @@ Global {15A615C7-33AA-2409-09FE-0B28B0D5143C}.InEditor|WindowsStandalone64.Build.0 = InEditor|WindowsStandalone64 {15A615C7-33AA-2409-09FE-0B28B0D5143C}.InEditor|WSA.ActiveCfg = InEditor|WSA {15A615C7-33AA-2409-09FE-0B28B0D5143C}.InEditor|WSA.Build.0 = InEditor|WSA - {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|Android.ActiveCfg = InEditor|Android - {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|Any CPU.ActiveCfg = InEditor|Android - {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|iOS.ActiveCfg = InEditor|Android - {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|WindowsStandalone32.ActiveCfg = InEditor|Android - {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|WindowsStandalone64.ActiveCfg = InEditor|Android - {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|WSA.ActiveCfg = InEditor|Android + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|Android.ActiveCfg = Player|Android + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|Any CPU.ActiveCfg = Player|Android + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|iOS.ActiveCfg = Player|iOS + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|WindowsStandalone32.ActiveCfg = Player|WindowsStandalone32 + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|WindowsStandalone64.ActiveCfg = Player|WindowsStandalone64 + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|WSA.ActiveCfg = Player|WSA {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Release|Android.ActiveCfg = InEditor|Android {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Release|Any CPU.ActiveCfg = InEditor|Android {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Release|iOS.ActiveCfg = InEditor|Android @@ -147,12 +147,12 @@ Global {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.InEditor|WindowsStandalone64.Build.0 = InEditor|WindowsStandalone64 {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.InEditor|WSA.ActiveCfg = InEditor|WSA {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.InEditor|WSA.Build.0 = InEditor|WSA - {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|Android.ActiveCfg = InEditor|Android - {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|Any CPU.ActiveCfg = InEditor|Android - {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|iOS.ActiveCfg = InEditor|Android - {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|WindowsStandalone32.ActiveCfg = InEditor|Android - {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|WindowsStandalone64.ActiveCfg = InEditor|Android - {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|WSA.ActiveCfg = InEditor|Android + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|Android.ActiveCfg = Player|Android + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|Any CPU.ActiveCfg = Player|Android + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|iOS.ActiveCfg = Player|iOS + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|WindowsStandalone32.ActiveCfg = Player|WindowsStandalone32 + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|WindowsStandalone64.ActiveCfg = Player|WindowsStandalone64 + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|WSA.ActiveCfg = Player|WSA {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Release|Android.ActiveCfg = InEditor|Android {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Release|Any CPU.ActiveCfg = InEditor|Android {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Release|iOS.ActiveCfg = InEditor|Android @@ -176,12 +176,12 @@ Global {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.InEditor|WindowsStandalone64.Build.0 = InEditor|WindowsStandalone64 {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.InEditor|WSA.ActiveCfg = InEditor|WSA {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.InEditor|WSA.Build.0 = InEditor|WSA - {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|Android.ActiveCfg = InEditor|Android - {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|Any CPU.ActiveCfg = InEditor|Android - {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|iOS.ActiveCfg = InEditor|Android - {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|WindowsStandalone32.ActiveCfg = InEditor|Android - {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|WindowsStandalone64.ActiveCfg = InEditor|Android - {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|WSA.ActiveCfg = InEditor|Android + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|Android.ActiveCfg = Player|Android + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|Any CPU.ActiveCfg = Player|Android + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|iOS.ActiveCfg = Player|iOS + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|WindowsStandalone32.ActiveCfg = Player|WindowsStandalone32 + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|WindowsStandalone64.ActiveCfg = Player|WindowsStandalone64 + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|WSA.ActiveCfg = Player|WSA {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Release|Android.ActiveCfg = InEditor|Android {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Release|Any CPU.ActiveCfg = InEditor|Android {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Release|iOS.ActiveCfg = InEditor|Android @@ -239,12 +239,12 @@ Global {6546D776-5B41-65B4-0850-B3667F981C26}.InEditor|WindowsStandalone64.Build.0 = InEditor|WindowsStandalone64 {6546D776-5B41-65B4-0850-B3667F981C26}.InEditor|WSA.ActiveCfg = InEditor|WSA {6546D776-5B41-65B4-0850-B3667F981C26}.InEditor|WSA.Build.0 = InEditor|WSA - {6546D776-5B41-65B4-0850-B3667F981C26}.Player|Android.ActiveCfg = InEditor|Android - {6546D776-5B41-65B4-0850-B3667F981C26}.Player|Any CPU.ActiveCfg = InEditor|Android - {6546D776-5B41-65B4-0850-B3667F981C26}.Player|iOS.ActiveCfg = InEditor|Android - {6546D776-5B41-65B4-0850-B3667F981C26}.Player|WindowsStandalone32.ActiveCfg = InEditor|Android - {6546D776-5B41-65B4-0850-B3667F981C26}.Player|WindowsStandalone64.ActiveCfg = InEditor|Android - {6546D776-5B41-65B4-0850-B3667F981C26}.Player|WSA.ActiveCfg = InEditor|Android + {6546D776-5B41-65B4-0850-B3667F981C26}.Player|Android.ActiveCfg = Player|Android + {6546D776-5B41-65B4-0850-B3667F981C26}.Player|Any CPU.ActiveCfg = Player|Android + {6546D776-5B41-65B4-0850-B3667F981C26}.Player|iOS.ActiveCfg = Player|iOS + {6546D776-5B41-65B4-0850-B3667F981C26}.Player|WindowsStandalone32.ActiveCfg = Player|WindowsStandalone32 + {6546D776-5B41-65B4-0850-B3667F981C26}.Player|WindowsStandalone64.ActiveCfg = Player|WindowsStandalone64 + {6546D776-5B41-65B4-0850-B3667F981C26}.Player|WSA.ActiveCfg = Player|WSA {6546D776-5B41-65B4-0850-B3667F981C26}.Release|Android.ActiveCfg = InEditor|Android {6546D776-5B41-65B4-0850-B3667F981C26}.Release|Any CPU.ActiveCfg = InEditor|Android {6546D776-5B41-65B4-0850-B3667F981C26}.Release|iOS.ActiveCfg = InEditor|Android diff --git a/Samples/CrossUnityDependencies.Unity/Assets/Dependencies.msb4u.csproj b/Samples/CrossUnityDependencies.Unity/Assets/Dependencies.msb4u.csproj index 9e39426..052c97e 100644 --- a/Samples/CrossUnityDependencies.Unity/Assets/Dependencies.msb4u.csproj +++ b/Samples/CrossUnityDependencies.Unity/Assets/Dependencies.msb4u.csproj @@ -1,4 +1,4 @@ - + + diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedTopLevelDependenciesProjectExporter.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedTopLevelDependenciesProjectExporter.cs index 11cc437..d7e66eb 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedTopLevelDependenciesProjectExporter.cs +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedExporter/TemplatedTopLevelDependenciesProjectExporter.cs @@ -67,7 +67,11 @@ public void Write() propsWriter.Export(propsExportPath); - new TemplatedWriter(primaryTemplateFile).Export(primaryExportPath); + // Don't overwrite primary export path, as that is the file that is allowed to be edited + if (!File.Exists(primaryExportPath.FullName)) + { + new TemplatedWriter(primaryTemplateFile).Export(primaryExportPath); + } new TemplatedWriter(targetsTemplateFile).Export(targetsExportPath); } } From 40d6d1a54257d8eaa0e6500247c55deb61accc15 Mon Sep 17 00:00:00 2001 From: Andrei Borodin Date: Wed, 22 Jan 2020 16:20:49 -0800 Subject: [PATCH 7/7] Fixes and updates for the top-level project changes. --- .../CrossUnityDependencies.Unity/.gitignore | 3 +- .../Assets/Assembly-CSharp.msb4u.csproj | 2 +- ...endencies.Unity.Dependencies.msb4u.csproj} | 2 +- ...ncies.Unity.Dependencies.msb4u.csproj.meta | 12 +++++ .../IntegratedDependencies.Unity/.gitignore | 3 +- ...> Project.Unity.Dependencies.msb4u.csproj} | 0 ...ject.Unity.Dependencies.msb4u.csproj.meta} | 4 +- .../SimpleNuGetDependency.Unity/.gitignore | 2 + .../Assets/NewtonsoftDependency/.gitignore | 1 + .../NewtonsoftDependency.csproj | 22 ++++----- .../Project.Unity.Dependencies.msb4u.csproj | 42 +++++++++++++++++ ...ject.Unity.Dependencies.msb4u.csproj.meta} | 4 +- Samples/SimpleNuGetDependency.Unity/README.md | 46 +++++++++++++++---- .../ProjectBuilder/MSBuildProjectReference.cs | 2 +- ...pendenciesProjectTemplate.g.props.template | 2 +- ...ndenciesProjectTemplate.g.targets.template | 2 +- .../MSBuildForUnity.Common.props.template | 6 +++ .../SDKProjectTemplate.g.targets.template | 10 ---- .../ProjectGenerator/Scripts/MSBuildTools.cs | 41 ++++++++++------- .../Scripts/MSBuildUnityProjectExporter.cs | 21 +++++---- 20 files changed, 160 insertions(+), 67 deletions(-) rename Samples/CrossUnityDependencies.Unity/Assets/{Dependencies.msb4u.csproj => CrossUnityDependencies.Unity.Dependencies.msb4u.csproj} (96%) create mode 100644 Samples/CrossUnityDependencies.Unity/Assets/CrossUnityDependencies.Unity.Dependencies.msb4u.csproj.meta rename Samples/IntegratedDependencies.Unity/Assets/{Dependencies.msb4u.csproj => Project.Unity.Dependencies.msb4u.csproj} (100%) rename Samples/{CrossUnityDependencies.Unity/Assets/Dependencies.msb4u.csproj.meta => IntegratedDependencies.Unity/Assets/Project.Unity.Dependencies.msb4u.csproj.meta} (74%) create mode 100644 Samples/SimpleNuGetDependency.Unity/Assets/Project.Unity.Dependencies.msb4u.csproj rename Samples/{IntegratedDependencies.Unity/Assets/Dependencies.msb4u.csproj.meta => SimpleNuGetDependency.Unity/Assets/Project.Unity.Dependencies.msb4u.csproj.meta} (74%) diff --git a/Samples/CrossUnityDependencies.Unity/.gitignore b/Samples/CrossUnityDependencies.Unity/.gitignore index 7ca5aee..aa9f20a 100644 --- a/Samples/CrossUnityDependencies.Unity/.gitignore +++ b/Samples/CrossUnityDependencies.Unity/.gitignore @@ -67,4 +67,5 @@ crashlytics-build.properties /MSBuildForUnity.Common.props !/Assets/**/*.msb4u.* !/Packages/**/*.msb4u.* -/Assets/Dependencies \ No newline at end of file +/Assets/Dependencies +/Assets/Dependencies.meta \ No newline at end of file diff --git a/Samples/CrossUnityDependencies.Unity/Assets/Assembly-CSharp.msb4u.csproj b/Samples/CrossUnityDependencies.Unity/Assets/Assembly-CSharp.msb4u.csproj index 9fa48c4..77734b9 100644 --- a/Samples/CrossUnityDependencies.Unity/Assets/Assembly-CSharp.msb4u.csproj +++ b/Samples/CrossUnityDependencies.Unity/Assets/Assembly-CSharp.msb4u.csproj @@ -30,7 +30,7 @@ - + diff --git a/Samples/CrossUnityDependencies.Unity/Assets/Dependencies.msb4u.csproj b/Samples/CrossUnityDependencies.Unity/Assets/CrossUnityDependencies.Unity.Dependencies.msb4u.csproj similarity index 96% rename from Samples/CrossUnityDependencies.Unity/Assets/Dependencies.msb4u.csproj rename to Samples/CrossUnityDependencies.Unity/Assets/CrossUnityDependencies.Unity.Dependencies.msb4u.csproj index 052c97e..a26e7c4 100644 --- a/Samples/CrossUnityDependencies.Unity/Assets/Dependencies.msb4u.csproj +++ b/Samples/CrossUnityDependencies.Unity/Assets/CrossUnityDependencies.Unity.Dependencies.msb4u.csproj @@ -35,7 +35,7 @@ - + diff --git a/Samples/CrossUnityDependencies.Unity/Assets/CrossUnityDependencies.Unity.Dependencies.msb4u.csproj.meta b/Samples/CrossUnityDependencies.Unity/Assets/CrossUnityDependencies.Unity.Dependencies.msb4u.csproj.meta new file mode 100644 index 0000000..3b39a8a --- /dev/null +++ b/Samples/CrossUnityDependencies.Unity/Assets/CrossUnityDependencies.Unity.Dependencies.msb4u.csproj.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 2f317b2181ec2ab4fb3a763de00d052e +ScriptedImporter: + fileIDToRecycleName: + 11400000: CrossUnityDependencies.Unity.Dependencies.msb4u + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 11500000, guid: 0e4dca1acba66fd478b3854f09a32ec7, type: 3} + buildEngine: 0 + profiles: [] diff --git a/Samples/IntegratedDependencies.Unity/.gitignore b/Samples/IntegratedDependencies.Unity/.gitignore index 7ca5aee..aa9f20a 100644 --- a/Samples/IntegratedDependencies.Unity/.gitignore +++ b/Samples/IntegratedDependencies.Unity/.gitignore @@ -67,4 +67,5 @@ crashlytics-build.properties /MSBuildForUnity.Common.props !/Assets/**/*.msb4u.* !/Packages/**/*.msb4u.* -/Assets/Dependencies \ No newline at end of file +/Assets/Dependencies +/Assets/Dependencies.meta \ No newline at end of file diff --git a/Samples/IntegratedDependencies.Unity/Assets/Dependencies.msb4u.csproj b/Samples/IntegratedDependencies.Unity/Assets/Project.Unity.Dependencies.msb4u.csproj similarity index 100% rename from Samples/IntegratedDependencies.Unity/Assets/Dependencies.msb4u.csproj rename to Samples/IntegratedDependencies.Unity/Assets/Project.Unity.Dependencies.msb4u.csproj diff --git a/Samples/CrossUnityDependencies.Unity/Assets/Dependencies.msb4u.csproj.meta b/Samples/IntegratedDependencies.Unity/Assets/Project.Unity.Dependencies.msb4u.csproj.meta similarity index 74% rename from Samples/CrossUnityDependencies.Unity/Assets/Dependencies.msb4u.csproj.meta rename to Samples/IntegratedDependencies.Unity/Assets/Project.Unity.Dependencies.msb4u.csproj.meta index 6a0e770..29f96ed 100644 --- a/Samples/CrossUnityDependencies.Unity/Assets/Dependencies.msb4u.csproj.meta +++ b/Samples/IntegratedDependencies.Unity/Assets/Project.Unity.Dependencies.msb4u.csproj.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 -guid: 780daffcc77b35645849186e155316d4 +guid: 4c19391e4150d0e4b924554825807164 ScriptedImporter: fileIDToRecycleName: - 11400000: Dependencies.msb4u + 11400000: Project.Unity.Dependencies.msb4u externalObjects: {} userData: assetBundleName: diff --git a/Samples/SimpleNuGetDependency.Unity/.gitignore b/Samples/SimpleNuGetDependency.Unity/.gitignore index 58cf90c..aa9f20a 100644 --- a/Samples/SimpleNuGetDependency.Unity/.gitignore +++ b/Samples/SimpleNuGetDependency.Unity/.gitignore @@ -65,5 +65,7 @@ crashlytics-build.properties /MSBuild/Publish/**/*.dll /MSBuild/Publish/**/*.pdb /MSBuildForUnity.Common.props +!/Assets/**/*.msb4u.* +!/Packages/**/*.msb4u.* /Assets/Dependencies /Assets/Dependencies.meta \ No newline at end of file diff --git a/Samples/SimpleNuGetDependency.Unity/Assets/NewtonsoftDependency/.gitignore b/Samples/SimpleNuGetDependency.Unity/Assets/NewtonsoftDependency/.gitignore index 15ecc70..fe01375 100644 --- a/Samples/SimpleNuGetDependency.Unity/Assets/NewtonsoftDependency/.gitignore +++ b/Samples/SimpleNuGetDependency.Unity/Assets/NewtonsoftDependency/.gitignore @@ -1,4 +1,5 @@ Plugins/ .obj/ +.bin/ Plugins.meta !*.csproj \ No newline at end of file diff --git a/Samples/SimpleNuGetDependency.Unity/Assets/NewtonsoftDependency/NewtonsoftDependency.csproj b/Samples/SimpleNuGetDependency.Unity/Assets/NewtonsoftDependency/NewtonsoftDependency.csproj index 2583c70..cd1c6c2 100644 --- a/Samples/SimpleNuGetDependency.Unity/Assets/NewtonsoftDependency/NewtonsoftDependency.csproj +++ b/Samples/SimpleNuGetDependency.Unity/Assets/NewtonsoftDependency/NewtonsoftDependency.csproj @@ -10,25 +10,21 @@ - - .obj - Plugins - $(MSBuildForUnityDefaultOutputPath) + + .obj\ + .bin\ - - - all - runtime; build; native; contentfiles; analyzers - - - - + + + + + - + \ No newline at end of file diff --git a/Samples/SimpleNuGetDependency.Unity/Assets/Project.Unity.Dependencies.msb4u.csproj b/Samples/SimpleNuGetDependency.Unity/Assets/Project.Unity.Dependencies.msb4u.csproj new file mode 100644 index 0000000..ffc3e86 --- /dev/null +++ b/Samples/SimpleNuGetDependency.Unity/Assets/Project.Unity.Dependencies.msb4u.csproj @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Samples/IntegratedDependencies.Unity/Assets/Dependencies.msb4u.csproj.meta b/Samples/SimpleNuGetDependency.Unity/Assets/Project.Unity.Dependencies.msb4u.csproj.meta similarity index 74% rename from Samples/IntegratedDependencies.Unity/Assets/Dependencies.msb4u.csproj.meta rename to Samples/SimpleNuGetDependency.Unity/Assets/Project.Unity.Dependencies.msb4u.csproj.meta index aa4eca0..79091ce 100644 --- a/Samples/IntegratedDependencies.Unity/Assets/Dependencies.msb4u.csproj.meta +++ b/Samples/SimpleNuGetDependency.Unity/Assets/Project.Unity.Dependencies.msb4u.csproj.meta @@ -1,8 +1,8 @@ fileFormatVersion: 2 -guid: 3cfffcf6ca567fd44a9d881a77e8b97f +guid: 894e2005d6d3c1c49a49099c3215aca4 ScriptedImporter: fileIDToRecycleName: - 11400000: Dependencies.msb4u + 11400000: Project.Unity.Dependencies.msb4u externalObjects: {} userData: assetBundleName: diff --git a/Samples/SimpleNuGetDependency.Unity/README.md b/Samples/SimpleNuGetDependency.Unity/README.md index 5509c2b..68766ef 100644 --- a/Samples/SimpleNuGetDependency.Unity/README.md +++ b/Samples/SimpleNuGetDependency.Unity/README.md @@ -21,20 +21,50 @@ The project file structure has several required parts to it: - This file contains some core properties that we require. - Conditional declaration of `TargetFramework` that depends on whether `UnityCurrentTargetFramework` property is available from above import. - The target framework is what determines which DLL of a NuGet package is pulled in. MSBuildForUnity keeps the property up to date in `MSBuildForUnity.Common.props`. -- Setting the `BaseIntermediateOutputPath` (object directory) to be invisible by Unity, by prefixing it with a '.' -- Naming the `OutputPath` that will be seen by Unity, this is where the NuGet output will be dumped into. -- Package reference to `MSBuildForUnity` NuGet package that enables the correct resolution of dependencies. -- `Sdk.props` and `Sdk.targets` import that doesn't produce a dll (`Microsoft.Build.NoTargets`). - -The `Assets/NewtonSoftDependency/NewtonSoftDependency.csproj` contains all of this, plus the NuGet reference to "NewtonSoft.Json" and is a total of 33 lines long. - -![C# Project File Contents](docs/CSProjectContents.png) +- Setting the `BaseIntermediateOutputPath` (object directory) and `OutputPath` to be invisible by Unity, by prefixing it with a '.' +- `Sdk.props` and `Sdk.targets` import that doesn't produce a dll (`Microsoft.Build.NoTargets`), must be version `1.0.85`. + +The `Assets/NewtonSoftDependency/NewtonSoftDependency.csproj` contains all of this, plus the NuGet reference to "NewtonSoft.Json" and is a total of 30 lines long. + +```xml + + + + + netstandard2.0 + + + + $(UnityCurrentTargetFramework) + + + + + .obj\ + .bin\ + + + + + + + + + + + + + + + +``` ## The Process When MSBuildForUnity is brought into the project, the following happens: 1. Generates the small `MSBuildForUnity.Common.props` file. +2. Generates a top-level `{ProjectName}.Dependencies.msb4u.csproj` file. 2. Auto-processes all of the .csproj files in the repository, and builds them. ## Question & Answer diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectBuilder/MSBuildProjectReference.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectBuilder/MSBuildProjectReference.cs index b059f76..5d1b847 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectBuilder/MSBuildProjectReference.cs +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectBuilder/MSBuildProjectReference.cs @@ -58,7 +58,7 @@ public static MSBuildProjectReference FromMSBuildProject(string assetRelativePat { msBuildProjectReference.profiles = profiles.ToArray(); } - else if (Path.GetFileNameWithoutExtension(assetRelativePath).EndsWith(".msb4u") && !Path.GetFileName(assetRelativePath).Equals("Dependencies.msb4u.csproj")) + else if (Path.GetFileNameWithoutExtension(assetRelativePath).EndsWith(".msb4u") && !Path.GetFileName(assetRelativePath).EndsWith("Dependencies.msb4u.csproj")) { msBuildProjectReference.profiles = null; } diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/MSBuildTemplates/DependenciesProjectTemplate.g.props.template b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/MSBuildTemplates/DependenciesProjectTemplate.g.props.template index 86e5238..4b18e40 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/MSBuildTemplates/DependenciesProjectTemplate.g.props.template +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/MSBuildTemplates/DependenciesProjectTemplate.g.props.template @@ -30,7 +30,7 @@ - + diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/MSBuildTemplates/DependenciesProjectTemplate.g.targets.template b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/MSBuildTemplates/DependenciesProjectTemplate.g.targets.template index a4702fc..5f00e72 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/MSBuildTemplates/DependenciesProjectTemplate.g.targets.template +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/MSBuildTemplates/DependenciesProjectTemplate.g.targets.template @@ -1,5 +1,5 @@ - + <_GenerateRestoreGraphProjectEntryInputProperties>UnityConfiguration=$(UnityConfiguration);UnityPlatform=$(UnityPlatform);$(_MSB4UPropagateProperties);$(_GenerateRestoreGraphProjectEntryInputProperties) diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/MSBuildTemplates/MSBuildForUnity.Common.props.template b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/MSBuildTemplates/MSBuildForUnity.Common.props.template index 459c48a..ed3f067 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/MSBuildTemplates/MSBuildForUnity.Common.props.template +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/MSBuildTemplates/MSBuildForUnity.Common.props.template @@ -37,7 +37,13 @@ UnityConfiguration=$(UnityConfiguration);UnityPlatform=$(UnityPlatform);$(_MSB4UPropagateProperties);$(AdditionalProperties) + + analyzers + + + analyzers + diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/MSBuildTemplates/SDKProjectTemplate.g.targets.template b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/MSBuildTemplates/SDKProjectTemplate.g.targets.template index 83e230d..e894440 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/MSBuildTemplates/SDKProjectTemplate.g.targets.template +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/MSBuildTemplates/SDKProjectTemplate.g.targets.template @@ -8,16 +8,6 @@ - - - - analyzers - - - none - - - <_GenerateRestoreGraphProjectEntryInputProperties>UnityConfiguration=$(UnityConfiguration);UnityPlatform=$(UnityPlatform);$(_MSB4UPropagateProperties);$(_GenerateRestoreGraphProjectEntryInputProperties) diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/MSBuildTools.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/MSBuildTools.cs index 5cc2e9d..e18f1ca 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/MSBuildTools.cs +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/MSBuildTools.cs @@ -156,7 +156,7 @@ public void OnActiveBuildTargetChanged(BuildTarget previousTarget, BuildTarget n { if (EditorAnalyticsSessionInfo.elapsedTime > 0) { - RefreshGeneratedOutput(forceGenerateEverything: Config.AutoGenerateEnabled); + RefreshGeneratedOutput(forceGenerateEverything: true, forceCompleteGeneration: false); } } } @@ -205,7 +205,7 @@ public static void ToggleAutoGenerate() Config.AutoGenerateEnabled = !Config.AutoGenerateEnabled; Menu.SetChecked(AutoGenerate, Config.AutoGenerateEnabled); // If we just toggled on, regenerate everything - RefreshGeneratedOutput(forceGenerateEverything: Config.AutoGenerateEnabled); + RefreshGeneratedOutput(forceGenerateEverything: true, forceCompleteGeneration: false); } [MenuItem(AutoGenerate, true, priority = 101)] @@ -221,7 +221,7 @@ public static void GenerateSDKProjects() { try { - RefreshGeneratedOutput(forceGenerateEverything: true); + RefreshGeneratedOutput(forceGenerateEverything: true, forceCompleteGeneration: false); Debug.Log($"{nameof(GenerateSDKProjects)} Completed Succesfully."); } catch @@ -233,7 +233,7 @@ public static void GenerateSDKProjects() public static void RegenerateSDKProjects() { - RegenerateEverything(unityProjectInfo = new UnityProjectInfo(SupportedBuildTargets, Config, performCompleteParse: true)); + RegenerateEverything(unityProjectInfo = new UnityProjectInfo(SupportedBuildTargets, Config, performCompleteParse: true), completeGeneration: true); Debug.Log($"{nameof(RegenerateSDKProjects)} Completed Succesfully."); } @@ -255,16 +255,16 @@ static MSBuildTools() void OnUpdate() { EditorApplication.update -= OnUpdate; - RefreshGeneratedOutput(forceGenerateEverything: false); + RefreshGeneratedOutput(forceGenerateEverything: false, forceCompleteGeneration: false); } } else { - RefreshGeneratedOutput(forceGenerateEverything: false); + RefreshGeneratedOutput(forceGenerateEverything: false, forceCompleteGeneration: false); } } - private static void RefreshGeneratedOutput(bool forceGenerateEverything) + private static void RefreshGeneratedOutput(bool forceGenerateEverything, bool forceCompleteGeneration) { // In this method, the following must happen // - Clean up builds if necessary @@ -295,7 +295,7 @@ private static void RefreshGeneratedOutput(bool forceGenerateEverything) if (regenerateEverything || unityProjectInfo == null) { // Create the project info only if it's null or we need to regenerate - unityProjectInfo = new UnityProjectInfo(SupportedBuildTargets, Config, regenerateEverything); + unityProjectInfo = new UnityProjectInfo(SupportedBuildTargets, Config, Config.AutoGenerateEnabled || forceCompleteGeneration); } // We regenerate the common "directory" props file under the following conditions: @@ -308,7 +308,7 @@ private static void RefreshGeneratedOutput(bool forceGenerateEverything) if (regenerateEverything) { - RegenerateEverything(unityProjectInfo); + RegenerateEverything(unityProjectInfo, Config.AutoGenerateEnabled || forceCompleteGeneration); } if (!doesTokenFileExist) @@ -340,7 +340,7 @@ private static void ExportCoreUnityPropFiles(UnityProjectInfo unityProjectInfo) } - private static void RegenerateEverything(UnityProjectInfo unityProjectInfo) + private static void RegenerateEverything(UnityProjectInfo unityProjectInfo, bool completeGeneration) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); @@ -365,12 +365,18 @@ private static void RegenerateEverything(UnityProjectInfo unityProjectInfo) propsFileGenerationStart = stopwatch.ElapsedMilliseconds; MSBuildUnityProjectExporter.ExportCommonPropsFile(Exporter, unityProjectInfo.CurrentPlayerPlatform); - ExportCoreUnityPropFiles(unityProjectInfo); + if (completeGeneration) + { + ExportCoreUnityPropFiles(unityProjectInfo); + } propsFileGenerationEnd = stopwatch.ElapsedMilliseconds; solutionExportStart = stopwatch.ElapsedMilliseconds; - Exporter.ExportSolution(unityProjectInfo, Config); - MSBuildUnityProjectExporter.ExportTopLevelDependenciesProject(Exporter, Config, new DirectoryInfo(Utilities.MSBuildProjectFolder), unityProjectInfo); + if (completeGeneration) + { + Exporter.ExportSolution(unityProjectInfo, Config); + } + MSBuildUnityProjectExporter.ExportTopLevelDependenciesProject(Exporter, Config, new DirectoryInfo(Utilities.MSBuildProjectFolder), unityProjectInfo); solutionExportEnd = stopwatch.ElapsedMilliseconds; foreach (string otherFile in TemplateFiles.Instance.OtherFiles) @@ -378,10 +384,13 @@ private static void RegenerateEverything(UnityProjectInfo unityProjectInfo) File.Copy(otherFile, Path.Combine(Utilities.MSBuildProjectFolder, Path.GetFileName(otherFile))); } - string buildProjectsFile = "BuildProjects.proj"; - if (!File.Exists(Path.Combine(Utilities.MSBuildOutputFolder, buildProjectsFile))) + if (completeGeneration) { - GenerateBuildProjectsFile(buildProjectsFile, Exporter.GetSolutionFilePath(unityProjectInfo), unityProjectInfo.AvailablePlatforms); + string buildProjectsFile = "BuildProjects.proj"; + if (!File.Exists(Path.Combine(Utilities.MSBuildOutputFolder, buildProjectsFile))) + { + GenerateBuildProjectsFile(buildProjectsFile, Exporter.GetSolutionFilePath(unityProjectInfo), unityProjectInfo.AvailablePlatforms); + } } } finally diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/MSBuildUnityProjectExporter.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/MSBuildUnityProjectExporter.cs index f06e1c8..db6f0f3 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/MSBuildUnityProjectExporter.cs +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/MSBuildUnityProjectExporter.cs @@ -80,21 +80,24 @@ public static void ExportCommonPropsFile(IUnityProjectExporter exporter, Compila public static void ExportTopLevelDependenciesProject(IUnityProjectExporter exporter, MSBuildToolsConfig config, DirectoryInfo generatedProjectFolder, UnityProjectInfo unityProjectInfo) { - string projectPath = GetProjectFilePath(Utilities.AssetPath, "Dependencies"); + string projectPath = GetProjectFilePath(Utilities.AssetPath, $"{unityProjectInfo.UnityProjectName}.Dependencies"); ITopLevelDependenciesProjectExporter projectExporter = exporter.CreateTopLevelDependenciesProjectExporter(new FileInfo(projectPath), generatedProjectFolder); projectExporter.Guid = config.DependenciesProjectGuid; - Dictionary allPlatforms = unityProjectInfo.AvailablePlatforms.ToDictionary(t => t.BuildTarget, t => t); - foreach (CSProjectInfo projectInfo in unityProjectInfo.CSProjects.Values) + if (unityProjectInfo.AvailablePlatforms != null) { - List platformConditions = GetPlatformConditions(allPlatforms, projectInfo.InEditorPlatforms.Keys); - projectExporter.References.Add(new ProjectReference() + Dictionary allPlatforms = unityProjectInfo.AvailablePlatforms.ToDictionary(t => t.BuildTarget, t => t); + foreach (CSProjectInfo projectInfo in unityProjectInfo.CSProjects.Values) { - ReferencePath = new Uri(GetProjectPath(projectInfo, generatedProjectFolder).FullName), - Condition = platformConditions.Count == 0 ? "false" : string.Join(" OR ", platformConditions), - IsGenerated = true - }); + List platformConditions = GetPlatformConditions(allPlatforms, projectInfo.InEditorPlatforms.Keys); + projectExporter.References.Add(new ProjectReference() + { + ReferencePath = new Uri(GetProjectPath(projectInfo, generatedProjectFolder).FullName), + Condition = platformConditions.Count == 0 ? "false" : string.Join(" OR ", platformConditions), + IsGenerated = true + }); + } } foreach (string otherProjectFile in unityProjectInfo.ExistingCSProjects)