private void GenerateTopLevelDependenciesProject(UnityProjectInfo unityProjectInfo) { 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(); // We use this to emulate the platform support for all Dictionary <BuildTarget, CompilationPlatformInfo> allPlatforms = unityProjectInfo.AvailablePlatforms.ToDictionary(t => t.BuildTarget, t => t); foreach (CSProjectInfo projectInfo in unityProjectInfo.CSProjects.Values) { List <string> platformConditions = GetPlatformConditions(allPlatforms, projectInfo.InEditorPlatforms.Keys); ProcessProjectDependency(replacementSet, projectReferenceTemplate, projectInfo, platformConditions); } dependenciesPropsTemplate.Write(propsPath, replacementSet); ITemplatePart targetsFileTemplate = dependenciesTargetsTemplate.Root; dependenciesTargetsTemplate.Write(targetsPath, propsFileTemplate.CreateReplacementSet()); if (!File.Exists(projectPath)) { dependenciesProjectTemplate.Write(projectPath, dependenciesProjectTemplate.Root.CreateReplacementSet()); } }
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); }
///<inherit-doc/> public void ExportProject(UnityProjectInfo unityProjectInfo, CSProjectInfo projectInfo) { string projectPath = GetProjectPath(projectInfo).FullName; bool generatedProject; switch (projectInfo.AssemblyDefinitionInfo.AssetLocation) { case AssetLocation.BuiltInPackage: case AssetLocation.External: case AssetLocation.PackageLibraryCache: generatedProject = true; break; case AssetLocation.Project: case AssetLocation.Package: generatedProject = false; break; default: throw new InvalidOperationException("The project's assembly definition file is in an unknown location."); } if (!TryExportPropsFile(unityProjectInfo, projectInfo)) { Debug.LogError($"Error exporting the generated props file for {projectInfo.Name}"); return; } if (!TryExportTargetsFile(unityProjectInfo, projectInfo)) { Debug.LogError($"Error exporting the generated targets file for {projectInfo.Name}"); return; } if (generatedProject) { generatedProjectFileTemplate.Write(projectPath, generatedProjectFileTemplate.Root.CreateReplacementSet()); File.SetAttributes(projectPath, FileAttributes.ReadOnly); } else if (!File.Exists(projectPath)) { projectFileTemplate.Write(projectPath, projectFileTemplate.Root.CreateReplacementSet()); } }
private bool TryExportTargetsFile(UnityProjectInfo unityProjectInfo, CSProjectInfo projectInfo) { string projectPath = GetProjectFilePath(generatedOutputFolder, projectInfo); ITemplatePart rootTemplatePart = targetsFileTemplate.Root; TemplateReplacementSet rootReplacementSet = rootTemplatePart.CreateReplacementSet(); ITemplatePart supportedPlatformBuildTemplate = rootTemplatePart.Templates["SUPPORTED_PLATFORM_BUILD_CONDITION"]; PopulateSupportedPlatformBuildConditions(supportedPlatformBuildTemplate, rootReplacementSet, "InEditor", projectInfo.InEditorPlatforms); PopulateSupportedPlatformBuildConditions(supportedPlatformBuildTemplate, rootReplacementSet, "Player", projectInfo.PlayerPlatforms); string targetsFilePath = projectPath.Replace("csproj", "g.targets"); targetsFileTemplate.Write(targetsFilePath, rootReplacementSet); File.SetAttributes(targetsFilePath, FileAttributes.ReadOnly); return(true); }
public void GenerateDirectoryPropsFile(UnityProjectInfo unityProjectInfo) { string outputPath = Path.Combine(Utilities.ProjectPath, "MSBuildForUnity.Common.props"); ITemplatePart rootTemplate = msbuildForUnityCommonTemplate.Root; TemplateReplacementSet rootReplacementSet = rootTemplate.CreateReplacementSet(null); rootTemplate.Tokens["GENERATED_OUTPUT_DIRECTORY"].AssignValue(rootReplacementSet, generatedOutputFolder.FullName); rootTemplate.Tokens["UNITY_PROJECT_ASSETS_PATH"].AssignValue(rootReplacementSet, Path.GetFullPath(Application.dataPath)); rootTemplate.Tokens["CURRENT_UNITY_PLATFORM"].AssignValue(rootReplacementSet, unityProjectInfo.CurrentPlayerPlatform.Name); rootTemplate.Tokens["CURRENT_TARGET_FRAMEWORK"].AssignValue(rootReplacementSet, unityProjectInfo.CurrentPlayerPlatform.TargetFramework.AsMSBuildString()); string[] versionParts = Application.unityVersion.Split('.'); rootTemplate.Tokens["UNITY_MAJOR_VERSION"].AssignValue(rootReplacementSet, versionParts[0]); rootTemplate.Tokens["UNITY_MINOR_VERSION"].AssignValue(rootReplacementSet, versionParts[1]); msbuildForUnityCommonTemplate.Write(outputPath, rootReplacementSet); }
private bool TryExportPropsFile(UnityProjectInfo unityProjectInfo, CSProjectInfo projectInfo) { ITemplatePart rootTemplatePart = propsFileTemplate.Root; TemplateReplacementSet rootReplacementSet = rootTemplatePart.CreateReplacementSet(); ITemplatePart projectReferenceSetTemplatePart = rootTemplatePart.Templates["PROJECT_REFERENCE_SET"]; ITemplatePart sourceExcludeTemplatePart = rootTemplatePart.Templates["SOURCE_EXCLUDE"]; string projectPath = GetProjectFilePath(generatedOutputFolder, projectInfo); foreach (AssemblyDefinitionInfo nestedAsmdef in projectInfo.AssemblyDefinitionInfo.NestedAssemblyDefinitionFiles) { TemplateReplacementSet replacementSet = sourceExcludeTemplatePart.CreateReplacementSet(rootReplacementSet); sourceExcludeTemplatePart.Tokens["EXCLUDE_DIRECTORY_PATH"].AssignValue(replacementSet, nestedAsmdef.Directory.FullName); } HashSet <string> inEditorSearchPaths = new HashSet <string>(), playerSearchPaths = new HashSet <string>(); CreateProjectReferencesSet(projectInfo, projectReferenceSetTemplatePart, rootReplacementSet, inEditorSearchPaths, true); CreateProjectReferencesSet(projectInfo, projectReferenceSetTemplatePart, rootReplacementSet, playerSearchPaths, false); rootTemplatePart.Tokens["PROJECT_GUID"].AssignValue(rootReplacementSet, projectInfo.Guid.ToString()); rootTemplatePart.Tokens["ALLOW_UNSAFE"].AssignValue(rootReplacementSet, projectInfo.AssemblyDefinitionInfo.allowUnsafeCode.ToString()); rootTemplatePart.Tokens["LANGUAGE_VERSION"].AssignValue(rootReplacementSet, MSBuildTools.CSharpVersion); rootTemplatePart.Tokens["DEVELOPMENT_BUILD"].AssignValue(rootReplacementSet, "false"); rootTemplatePart.Tokens["IS_EDITOR_ONLY_TARGET"].AssignValue(rootReplacementSet, (projectInfo.ProjectType == ProjectType.EditorAsmDef || projectInfo.ProjectType == ProjectType.PredefinedEditorAssembly).ToString()); rootTemplatePart.Tokens["UNITY_EDITOR_INSTALL_FOLDER"].AssignValue(rootReplacementSet, Path.GetDirectoryName(EditorApplication.applicationPath) + "\\"); rootTemplatePart.Tokens["PROJECT_NAME"].AssignValue(rootReplacementSet, projectInfo.Name); rootTemplatePart.Tokens["DEFAULT_PLATFORM"].AssignValue(rootReplacementSet, unityProjectInfo.AvailablePlatforms.First(t => t.BuildTarget == BuildTarget.StandaloneWindows).Name); rootTemplatePart.Tokens["SUPPORTED_PLATFORMS"].AssignValue(rootReplacementSet, new DelimitedStringSet(";", unityProjectInfo.AvailablePlatforms.Select(t => t.Name))); rootTemplatePart.Tokens["INEDITOR_ASSEMBLY_SEARCH_PATHS"].AssignValue(rootReplacementSet, new DelimitedStringSet(";", inEditorSearchPaths)); rootTemplatePart.Tokens["PLAYER_ASSEMBLY_SEARCH_PATHS"].AssignValue(rootReplacementSet, new DelimitedStringSet(";", playerSearchPaths)); rootTemplatePart.Tokens["PLATFORM_PROPS_FOLDER_PATH"].AssignValue(rootReplacementSet, generatedOutputFolder.FullName); rootTemplatePart.Tokens["PROJECT_DIRECTORY_PATH"].AssignValue(rootReplacementSet, projectInfo.AssemblyDefinitionInfo.Directory.FullName); string propsFilePath = projectPath.Replace("csproj", "g.props"); propsFileTemplate.Write(propsFilePath, rootReplacementSet); File.SetAttributes(propsFilePath, FileAttributes.ReadOnly); return(true); }
///<inherit-doc/> public void ExportSolution(UnityProjectInfo unityProjectInfo) { string solutionFilePath = GetSolutionFilePath(unityProjectInfo); if (File.Exists(solutionFilePath)) { File.Delete(solutionFilePath); } ITemplatePart rootTemplatePart = solutionFileTemplate.Root; TemplateReplacementSet rootReplacementSet = rootTemplatePart.CreateReplacementSet(); ITemplatePart projectTemplate = rootTemplatePart.Templates["PROJECT"]; ITemplatePart folderTemplate = rootTemplatePart.Templates["FOLDER"]; ITemplatePart configPlatformTemplate = rootTemplatePart.Templates["CONFIGURATION_PLATFORM"]; ITemplatePart configPlatformMappingTemplate = rootTemplatePart.Templates["CONFIGURATION_PLATFORM_MAPPING"]; ITemplatePart configPlatformEnabledTemplate = rootTemplatePart.Templates["CONFIGURATION_PLATFORM_ENABLED"]; ITemplatePart folderNestedProjectsTemplate = rootTemplatePart.Templates["FOLDER_NESTED_PROJECTS"]; CSProjectInfo[] unorderedProjects = unityProjectInfo.CSProjects.Select(t => t.Value).ToArray(); List <CSProjectInfo> orderedProjects = new List <CSProjectInfo>(); while (orderedProjects.Count < unorderedProjects.Length) { bool oneRemoved = false; for (int i = 0; i < unorderedProjects.Length; i++) { if (unorderedProjects[i] == null) { continue; } if (unorderedProjects[i].ProjectDependencies.Count == 0 || unorderedProjects[i].ProjectDependencies.All(t => orderedProjects.Contains(t.Dependency))) { orderedProjects.Add(unorderedProjects[i]); unorderedProjects[i] = null; oneRemoved = true; } } if (!oneRemoved) { Debug.LogError($"Possible circular dependency."); break; } } List <CSProjectInfo> builtinPackages = new List <CSProjectInfo>(); List <CSProjectInfo> importedPacakges = new List <CSProjectInfo>(); List <CSProjectInfo> externalPackages = new List <CSProjectInfo>(); foreach (CSProjectInfo project in orderedProjects) { TemplateReplacementSet replacementSet = projectTemplate.CreateReplacementSet(rootReplacementSet); ProcessProjectEntry(project.Name, GetProjectPath(project).FullName, project.Guid, project.ProjectDependencies, projectTemplate, replacementSet); switch (project.AssemblyDefinitionInfo.AssetLocation) { case AssetLocation.BuiltInPackage: builtinPackages.Add(project); break; case AssetLocation.PackageLibraryCache: importedPacakges.Add(project); break; case AssetLocation.External: externalPackages.Add(project); break; default: break; } } // Add the "Dependencies" project ProcessProjectEntry("Dependencies", GetProjectFilePath(Utilities.AssetPath, "Dependencies"), Guid.NewGuid(), null, projectTemplate, projectTemplate.CreateReplacementSet(rootReplacementSet)); PopulateFolder(folderTemplate, folderNestedProjectsTemplate, rootReplacementSet, "Built In Packages", builtinPackages); PopulateFolder(folderTemplate, folderNestedProjectsTemplate, rootReplacementSet, "Imported Packages", importedPacakges); PopulateFolder(folderTemplate, folderNestedProjectsTemplate, rootReplacementSet, "External Packages", externalPackages); ITemplateToken configPlatform_ConfigurationToken = configPlatformTemplate.Tokens["CONFIGURATION"]; ITemplateToken configPlatform_PlatformToken = configPlatformTemplate.Tokens["PLATFORM"]; foreach (CompilationPlatformInfo platform in unityProjectInfo.AvailablePlatforms) { TemplateReplacementSet replacementSet = configPlatformTemplate.CreateReplacementSet(rootReplacementSet); configPlatform_ConfigurationToken.AssignValue(replacementSet, "InEditor"); configPlatform_PlatformToken.AssignValue(replacementSet, platform.Name); replacementSet = configPlatformTemplate.CreateReplacementSet(rootReplacementSet); configPlatform_ConfigurationToken.AssignValue(replacementSet, "Player"); configPlatform_PlatformToken.AssignValue(replacementSet, platform.Name); } List <string> disabled = new List <string>(); foreach (CSProjectInfo project in orderedProjects.Select(t => t)) { void ConfigurationTemplateReplace(ITemplatePart templatePart, TemplateReplacementSet replacementSet, string guid, string configuration, string platform) { templatePart.Tokens["PROJECT_GUID"].AssignValue(replacementSet, guid.ToString().ToUpper()); templatePart.Tokens["PROJECT_CONFIGURATION"].AssignValue(replacementSet, configuration); templatePart.Tokens["PROJECT_PLATFORM"].AssignValue(replacementSet, platform); templatePart.Tokens["SOLUTION_CONFIGURATION"].AssignValue(replacementSet, configuration); templatePart.Tokens["SOLUTION_PLATFORM"].AssignValue(replacementSet, platform); } void ProcessMappings(Guid guid, string configuration, IReadOnlyDictionary <BuildTarget, CompilationPlatformInfo> platforms) { foreach (CompilationPlatformInfo platform in unityProjectInfo.AvailablePlatforms) { TemplateReplacementSet replacemetSet = configPlatformMappingTemplate.CreateReplacementSet(rootReplacementSet); ConfigurationTemplateReplace(configPlatformMappingTemplate, replacemetSet, guid.ToString(), configuration, platform.Name); if (platforms.ContainsKey(platform.BuildTarget)) { replacemetSet = configPlatformEnabledTemplate.CreateReplacementSet(rootReplacementSet); ConfigurationTemplateReplace(configPlatformEnabledTemplate, replacemetSet, guid.ToString(), configuration, platform.Name); } } } ProcessMappings(project.Guid, "InEditor", project.InEditorPlatforms); ProcessMappings(project.Guid, "Player", project.PlayerPlatforms); } foreach (CSProjectInfo project in unityProjectInfo.CSProjects.Values) { ExportProject(unityProjectInfo, project); } GenerateTopLevelDependenciesProject(unityProjectInfo); solutionFileTemplate.Write(solutionFilePath, rootReplacementSet); }