private string GetProjectEntry(CSProjectInfo projectInfo, string projectEntryTemplateBody) { StringBuilder toReturn = new StringBuilder(); toReturn.AppendLine(Utilities.ReplaceTokens(projectEntryTemplateBody, new Dictionary <string, string>() { { "<PROJECT_NAME>", projectInfo.Name }, { "<PROJECT_RELATIVE_PATH>", Path.GetFileName(projectInfo.ReferencePath.AbsolutePath) }, { "<PROJECT_GUID>", projectInfo.Guid.ToString().ToUpper() } })); if (projectInfo.ProjectDependencies.Count > 0) { string projectDependencyStartSection = " ProjectSection(ProjectDependencies) = postProject"; string projectDependencyGuid = " {<DependencyGuid>} = {<DependencyGuid>}"; string projectDependencyStopSection = " EndProjectSection"; toReturn.AppendLine(projectDependencyStartSection); foreach (CSProjectDependency <CSProjectInfo> project in projectInfo.ProjectDependencies) { toReturn.AppendLine(projectDependencyGuid.Replace("<DependencyGuid>", project.Dependency.Guid.ToString().ToUpper())); } toReturn.AppendLine(projectDependencyStopSection); } toReturn.Append("EndProject"); return(toReturn.ToString()); }
private CSProjectInfo GetProjectInfo(Dictionary <string, CSProjectInfo> projectsMap, Dictionary <string, AssemblyDefinitionInfo> asmDefInfoMap, HashSet <string> builtInPackagesWithoutSource, string projectKey, string projectOutputPath) { if (projectsMap.TryGetValue(projectKey, out CSProjectInfo value)) { return(value); } if (!asmDefInfoMap.TryGetValue(projectKey, out AssemblyDefinitionInfo assemblyDefinitionInfo)) { Debug.LogError($"Can't find an asmdef for project: {projectKey}, this project may need to be to added to the PackageReferencesUnity2019 or ExcludedPackageReferences exclusion list"); throw new InvalidOperationException($"Can't find an asmdef for project: {projectKey}"); } CSProjectInfo toReturn = new CSProjectInfo(this, assemblyDefinitionInfo, projectOutputPath); projectsMap.Add(projectKey, toReturn); if (!assemblyDefinitionInfo.BuiltInPackage) { foreach (PluginAssemblyInfo plugin in Plugins.Where(t => t.Type != PluginType.Native)) { if (plugin.AutoReferenced || assemblyDefinitionInfo.PrecompiledAssemblyReferences.Contains(plugin.Name)) { toReturn.AddDependency(plugin); } } } foreach (string reference in toReturn.AssemblyDefinitionInfo.References) { if (ExcludedPackageReferences.Contains(reference)) { Debug.LogWarning($"Skipping processing {reference} for {toReturn.Name}, as it's marked as excluded."); continue; } #if !UNITY_2019_3_OR_NEWER if (PackageReferencesUnity2019.Contains(reference)) { Debug.LogWarning($"Skipping processing {reference} for {toReturn.Name}, as it's for Unity 2019.3+."); continue; } #endif string packageCandidate = $"com.{reference.ToLower()}"; if (builtInPackagesWithoutSource.Any(t => packageCandidate.StartsWith(t))) { Debug.LogWarning($"Skipping processing {reference} for {toReturn.Name}, as it's a built-in package without source."); continue; } toReturn.AddDependency(GetProjectInfo(projectsMap, asmDefInfoMap, builtInPackagesWithoutSource, reference, projectOutputPath)); } return(toReturn); }
/// <summary> /// Adds a dependency to the project. /// </summary> /// <param name="csProjectInfo">The C# dependency.</param> internal void AddDependency(CSProjectInfo csProjectInfo) { AddDependency(csProjectDependencies, csProjectInfo); }
private CSProjectInfo GetProjectInfo(Dictionary <string, CSProjectInfo> projectsMap, Dictionary <string, AssemblyDefinitionInfo> asmDefInfoMap, HashSet <string> builtInPackagesWithoutSource, string projectKey, string projectOutputPath) { #if UNITY_2019_3_OR_NEWER if (SpecialPluginNameMappingUnity2019.TryGetValue(projectKey, out string pluginName)) { projectKey = pluginName; } #endif if (projectsMap.TryGetValue(projectKey, out CSProjectInfo value)) { return(value); } if (!asmDefInfoMap.TryGetValue(projectKey, out AssemblyDefinitionInfo assemblyDefinitionInfo)) { Debug.LogError($"Can't find an asmdef for project: {projectKey}, this project may need to be to added to the PackageReferencesUnity2019 or ExcludedPackageReferences exclusion list"); throw new InvalidOperationException($"Can't find an asmdef for project: {projectKey}"); } CSProjectInfo toReturn = new CSProjectInfo(this, assemblyDefinitionInfo, projectOutputPath); projectsMap.Add(projectKey, toReturn); if (!assemblyDefinitionInfo.BuiltInPackage) { foreach (PluginAssemblyInfo plugin in Plugins.Where(t => t.Type != PluginType.Native)) { if (plugin.AutoReferenced || assemblyDefinitionInfo.PrecompiledAssemblyReferences.Contains(plugin.Name)) { toReturn.AddDependency(plugin); } } } foreach (string reference in toReturn.AssemblyDefinitionInfo.References) { if (ExcludedPackageReferences.Contains(reference)) { Debug.LogWarning($"Skipping processing {reference} for {toReturn.Name}, as it's marked as excluded."); continue; } #if !UNITY_2019_3_OR_NEWER if (PackageReferencesUnity2019.Contains(reference)) { Debug.LogWarning($"Skipping processing {reference} for {toReturn.Name}, as it's for Unity 2019.3+."); continue; } #endif string packageCandidate = $"com.{reference.ToLower()}"; if (builtInPackagesWithoutSource.Any(t => packageCandidate.StartsWith(t))) { Debug.LogWarning($"Skipping processing {reference} for {toReturn.Name}, as it's a built-in package without source."); continue; } toReturn.AddDependency(GetProjectInfo(projectsMap, asmDefInfoMap, builtInPackagesWithoutSource, reference, projectOutputPath)); } // Manually add special plugin dependencies to the projects #if UNITY_2019_3_OR_NEWER #if UNITY_2020_2_OR_NEWER if (toReturn.Name.StartsWith("Microsoft.MixedReality.Toolkit") || toReturn.Name.StartsWith("Unity.TextMeshPro")) #else if (toReturn.Name.StartsWith("Microsoft.MixedReality.Toolkit")) #endif { string[] plugins = SpecialPluginNameMappingUnity2019.Values.OrderByDescending(p => p).ToArray(); foreach (var plugin in plugins) { if (projectsMap.TryGetValue(plugin, out CSProjectInfo projectInfo)) { toReturn.AddDependency(projectInfo); } #if UNITY_2020_2_OR_NEWER else { CSProjectInfo newProjInfo = new CSProjectInfo(this, asmDefInfoMap[plugin], projectOutputPath); if (plugin == plugins[1]) { newProjInfo.AddDependency(projectsMap[plugins[0]]); } projectsMap.Add(plugin, newProjInfo); toReturn.AddDependency(newProjInfo); } #endif } } #endif return(toReturn); }
public UnityProjectInfo(IEnumerable <CompilationPlatformInfo> availablePlatforms, string projectOutputPath) { this.availablePlatforms = availablePlatforms; Dictionary <string, Assembly> unityAssemblies = CompilationPipeline.GetAssemblies().ToDictionary(t => t.name); Dictionary <string, CSProjectInfo> csProjects = new Dictionary <string, CSProjectInfo>(); CSProjects = new ReadOnlyDictionary <string, CSProjectInfo>(csProjects); foreach (KeyValuePair <string, Assembly> pair in unityAssemblies) { CSProjectInfo toAdd; string asmDefPath = CompilationPipeline.GetAssemblyDefinitionFilePathFromAssemblyName(pair.Key); if (string.IsNullOrEmpty(asmDefPath)) { if (!pair.Key.StartsWith("Assembly-CSharp")) { Debug.LogError($"Failed to retrieve AsmDef for script assembly: {pair.Key}"); } toAdd = new CSProjectInfo(availablePlatforms, Guid.NewGuid(), null, pair.Value, projectOutputPath); } else { string guid = AssetDatabase.AssetPathToGUID(asmDefPath); if (!Guid.TryParse(guid, out Guid guidResult)) { Debug.LogError($"Failed to get GUID of the AsmDef at '{asmDefPath}' for assembly: {pair.Key}"); } else { guidResult = Guid.NewGuid(); } AssemblyDefinitionAsset assemblyDefinitionAsset = AssetDatabase.LoadAssetAtPath <AssemblyDefinitionAsset>(asmDefPath); AssemblyDefinitionInfo assemblyDefinitionInfo = assemblyDefinitionAsset == null ? null : JsonUtility.FromJson <AssemblyDefinitionInfo>(assemblyDefinitionAsset.text); assemblyDefinitionInfo?.Validate(availablePlatforms); toAdd = new CSProjectInfo(availablePlatforms, guidResult, assemblyDefinitionInfo, pair.Value, projectOutputPath); } csProjects.Add(pair.Key, toAdd); } Plugins = new ReadOnlyCollection <PluginAssemblyInfo>(ScanForPluginDLLs()); foreach (PluginAssemblyInfo plugin in Plugins) { if (plugin.Type == PluginType.Native) { Debug.LogWarning($"Native plugin {plugin.ReferencePath.AbsolutePath} not yet supported for MSBuild project."); } } foreach (CSProjectInfo project in CSProjects.Values) { // Get the assembly references first from AssemblyDefinitionInfo if available (it's actually more correct), otherwise fallback to Assemby IEnumerable <string> references = project.AssemblyDefinitionInfo == null ? project.Assembly.assemblyReferences.Select(t => t.name) : (project.AssemblyDefinitionInfo.references ?? Array.Empty <string>()); foreach (string reference in references) { if (CSProjects.TryGetValue(reference, out CSProjectInfo dependency)) { project.AddDependency(dependency); } else { Debug.LogError($"Failed to get dependency '{reference}' for project '{project.Name}'."); } } foreach (PluginAssemblyInfo plugin in Plugins) { if (plugin.AutoReferenced && plugin.Type != PluginType.Native) { project.AddDependency(plugin); } } } }