diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/AssemblyDefinitionInfo.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/AssemblyDefinitionInfo.cs index 1b831a4..529165c 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/AssemblyDefinitionInfo.cs +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/AssemblyDefinitionInfo.cs @@ -70,6 +70,7 @@ public static AssemblyDefinitionInfo Parse(FileInfo file, UnityProjectInfo unity toReturn.BuiltInPackage = isBuiltInPackage; toReturn.Validate(unityProjectInfo.AvailablePlatforms); toReturn.PrecompiledAssemblyReferences = new HashSet(toReturn.precompiledReferences?.Select(t => t.Replace(".dll", string.Empty)) ?? Array.Empty()); + toReturn.DefineConstraints = new HashSet(toReturn.defineConstraints ?? (toReturn.defineConstraints = new string[0])); return toReturn; } @@ -90,7 +91,9 @@ public static AssemblyDefinitionInfo Parse(FileInfo file, UnityProjectInfo unity [SerializeField] private string[] precompiledReferences = null; public bool autoReferenced; - public string[] defineConstraints; + + [SerializeField] + private string[] defineConstraints = null; /// /// Gets or sets the parsed Guid of the AssemblyDefinition asset. @@ -147,8 +150,16 @@ public static AssemblyDefinitionInfo Parse(FileInfo file, UnityProjectInfo unity /// public HashSet PrecompiledAssemblyReferences { get; private set; } + /// + /// Gets assembly defintions that are nested (in terms of folder hierarchy) in respect to this assembly defintion. + /// public HashSet NestedAssemblyDefinitionFiles { get; } = new HashSet(); + /// + /// Gets the define constraints for this assembly defintion. + /// + public HashSet DefineConstraints { get; private set; } + /// /// After it's parsed from JSON, this method should be invoked to validate some of the values and set additional properties. /// diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/CSProjectInfo.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/CSProjectInfo.cs index b7c4689..2fa267d 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/CSProjectInfo.cs +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/CSProjectInfo.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; -using System.IO; using System.Linq; using UnityEditor; using UnityEngine; @@ -138,12 +137,29 @@ private ReadOnlyDictionary GetCompilationP } // We only are an asmdef at this point, as above we handle all PredfinedAssemblies, then EditorAsmDef and PredefinedEditorAssembly for inEditor and not inEditor cases above - Func predicate = AssemblyDefinitionInfo.includePlatforms.Length > 0 - ? predicate = (t) => AssemblyDefinitionInfo.includePlatforms.Contains(t.Name) - : predicate = (t) => !AssemblyDefinitionInfo.excludePlatforms.Contains(t.Name); + bool IsPlatformSupported(CompilationPlatformInfo platform) + { + HashSet additionalSet = inEditor ? platform.AdditionalInEditorDefines : platform.AdditionalPlayerDefines; + + // Check for defines to ensure they are included in the platform (differentiate between editor/player) + foreach (string define in AssemblyDefinitionInfo.DefineConstraints) + { + if (!platform.CommonPlatformDefines.Contains(define) && !additionalSet.Contains(define)) + { + return false; + } + } + + if (AssemblyDefinitionInfo.includePlatforms.Length > 0) + { + return AssemblyDefinitionInfo.includePlatforms.Contains(platform.Name); + } + // else + return !AssemblyDefinitionInfo.excludePlatforms.Contains(platform.Name); + } return new ReadOnlyDictionary( - UnityProjectInfo.AvailablePlatforms.Where(predicate) + UnityProjectInfo.AvailablePlatforms.Where(IsPlatformSupported) .ToDictionary(t => t.BuildTarget, t => t)); } diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedProjectExporter.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedProjectExporter.cs index 21cbe21..a8e8a39 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedProjectExporter.cs +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedProjectExporter.cs @@ -413,6 +413,9 @@ void ProcessDefaultMappings(ProjectConfigurationMapping mapping, Dictionary availablePlatformNames = unityProjectInfo.AvailablePlatforms.Select(t => t.Name).ToList(); + Dictionary> defaultPlatformsMap = new Dictionary> { { "InEditor", availablePlatformNames }, { "Player", availablePlatformNames } }; + // Iterate over every project foreach (CSProjectInfo project in orderedProjects) { @@ -442,7 +445,7 @@ void ProcessProjectPlatforms(string configuration, IEnumerable platforms ProcessProjectPlatforms("Player", enabledPlayerPlatforms); // Add all other known solution mappings, map to itself or allowed mappings - ProcessDefaultMappings(mapping, new Dictionary> { { "InEditor", enabledInEditorPlatforms }, { "Player", enabledPlayerPlatforms } }); + ProcessDefaultMappings(mapping, defaultPlatformsMap); } // Process the Dependencies Project now 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 bf5e9f9..534a7a5 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 @@ -34,6 +34,16 @@ public class UnityProjectInfo : IDisposable { "Unity.ugui", "UnityEngine.UI" } }; + /// + /// Another patching technique to add defines to some assembly defintion files. TestRunner for example, is only referenced by projects with UNITY_INCLUDE_TESTS and references nunit that has UNITY_INCLUDE_TESTS; + /// However it doesn't have the define itself. This breaks Player build, and as it appears that Unity specially handles this case as well. + /// + private static readonly Dictionary> ImpliedDefinesForAsmDefs = new Dictionary>() + { + { "UnityEditor.TestRunner", new List(){ "UNITY_INCLUDE_TESTS" } }, + { "UnityEngine.TestRunner", new List(){ "UNITY_INCLUDE_TESTS" } }, + }; + /// /// Gets the name of this Unity Project. /// @@ -222,7 +232,7 @@ private Dictionary CreateUnityProjects(MSBuildToolsConfig } // Now we have all of the assembly definiton files, let's run a quick validation. - CorrectReferences(asmDefInfoMap); + ValidateAndPatchAssemblyDefinitions(asmDefInfoMap); int index = 0; ProcessSortedAsmDef(asmDefDirectoriesSorted.ToArray(), ref index, (uri) => true, (a) => { }); @@ -243,7 +253,7 @@ private Dictionary CreateUnityProjects(MSBuildToolsConfig /// /// This performs reference correction, for example this corrects "Unity.ugui" to be "UnityEngine.UI" (a known error of TextMeshPro). For correction map see . /// - private void CorrectReferences(Dictionary asmDefInfoMap) + private void ValidateAndPatchAssemblyDefinitions(Dictionary asmDefInfoMap) { foreach (KeyValuePair asmDefPair in asmDefInfoMap) { @@ -259,6 +269,14 @@ private void CorrectReferences(Dictionary asmDef } } } + + if (ImpliedDefinesForAsmDefs.TryGetValue(asmDefPair.Key, out List defines)) + { + foreach (string define in defines) + { + asmDefPair.Value.DefineConstraints.Add(define); + } + } } }