/// <summary> /// Parses an asmdef file creating a new instance of <see cref="AssemblyDefinitionInfo"/>. /// </summary> /// <param name="file">The file representing asmdef.</param> /// <param name="unityProjectInfo">Instance of <see cref="UnityProjectInfo"/>,</param> /// <param name="assembly">The Unity assembly reference.</param> /// <param name="isBuiltInPackage">True whether this asmdef lives in the editor installation folder.</param> /// <returns></returns> public static AssemblyDefinitionInfo Parse(FileInfo file, UnityProjectInfo unityProjectInfo, Assembly assembly, bool isBuiltInPackage = false) { if (file.Extension != ".asmdef") { throw new ArgumentException($"Given file '{file.FullName}' is not an assembly definition file."); } else if (!file.Exists) { throw new ArgumentException($"Given file '{file.FullName}' does not exist."); } AssemblyDefinitionInfo toReturn = JsonUtility.FromJson <AssemblyDefinitionInfo>(File.ReadAllText(file.FullName)); if (!Utilities.TryGetGuidForAsset(file, out Guid guid)) { Debug.LogError($"Failed to parse AsmDef meta for asm def: '{file.FullName}', didn't find guid."); } toReturn.assembly = assembly; toReturn.Directory = file.Directory; toReturn.AssetLocation = Utilities.GetAssetLocation(file); toReturn.file = file; toReturn.Guid = guid; toReturn.BuiltInPackage = isBuiltInPackage; toReturn.Validate(unityProjectInfo.AvailablePlatforms); toReturn.PrecompiledAssemblyReferences = new HashSet <string>(toReturn.precompiledReferences?.Select(t => t.Replace(".dll", string.Empty)) ?? Array.Empty <string>()); return(toReturn); }
/// <summary> /// Creates a new instance. /// </summary> /// <param name="unityProjectInfo">Instance of parsed unity project info.</param> /// <param name="guid">The unique Guid of this reference item.</param> /// <param name="referencePath">The output path to the reference item.</param> /// <param name="name">The name of the reference.</param> protected ReferenceItemInfo(UnityProjectInfo unityProjectInfo, Guid guid, Uri referencePath, string name) { UnityProjectInfo = unityProjectInfo; Guid = guid; ReferencePath = referencePath; Name = name; }
private static void RunGenerateSDKProjects() { // Create a copy of the packages as they might change after we create the MSBuild project string generatedProjectPath = Path.Combine(Utilities.MSBuildOutputFolder, "Projects"); try { Utilities.EnsureCleanDirectory(generatedProjectPath); } catch (IOException ex) { if (ex.Message.Contains(@"db.lock")) { Debug.LogError("Generated project appears to be still open with Visual Studio."); throw new InvalidDataException("Generated project appears to be still open with Visual Studio.", ex); } else { throw; } } Utilities.EnsureCleanDirectory(Path.Combine(Utilities.MSBuildOutputFolder, "Output")); MakePackagesCopy(Utilities.MSBuildOutputFolder); List <CompilationPlatformInfo> platforms = CompilationPipeline.GetAssemblyDefinitionPlatforms() .Where(t => supportedBuildTargets.Contains(t.BuildTarget)) .Select(CompilationPlatformInfo.GetCompilationPlatform) .OrderBy(t => t.Name) .ToList(); CompilationPlatformInfo editorPlatform = CompilationPlatformInfo.GetEditorPlatform(); CreateCommonPropsFile(platforms, editorPlatform, generatedProjectPath); UnityProjectInfo unityProjectInfo = new UnityProjectInfo(platforms, generatedProjectPath); // Read the solution template string solutionTemplateText = File.ReadAllText(TemplateFiles.Instance.MSBuildSolutionTemplatePath); // Read the project template string projectTemplateText = File.ReadAllText(TemplateFiles.Instance.SDKProjectFileTemplatePath); unityProjectInfo.ExportSolution(solutionTemplateText, projectTemplateText, generatedProjectPath); foreach (string otherFile in TemplateFiles.Instance.OtherFiles) { File.Copy(otherFile, Path.Combine(generatedProjectPath, Path.GetFileName(otherFile))); } string buildProjectsFile = "BuildProjects.proj"; if (!File.Exists(Path.Combine(Utilities.MSBuildOutputFolder, buildProjectsFile))) { GenerateBuildProjectsFile(buildProjectsFile, unityProjectInfo.UnityProjectName, platforms); } }
/// <summary> /// Creates a new instance of the <see cref="PluginAssemblyInfo"/>. /// </summary> public PluginAssemblyInfo(UnityProjectInfo unityProjectInfo, Guid guid, string fullPath, PluginType type) : base(unityProjectInfo, guid, new Uri(fullPath), Path.GetFileNameWithoutExtension(fullPath)) { Type = type; if (Type == PluginType.Managed) { ParseYAMLFile(); } }
private static void ExportCoreUnityPropFiles(UnityProjectInfo unityProjectInfo) { 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, unityProjectInfo.EditorPlatform, true); }
/// <summary> /// Creates a new instance of the CSProject info. /// </summary> /// <param name="unityProjectInfo">Instance of parsed unity project info.</param> /// <param name="guid">The unique Guid of this reference item.</param> /// <param name="assemblyDefinitionInfo">The associated Assembly-Definition info.</param> /// <param name="assembly">The Unity assembly object associated with this csproj.</param> /// <param name="baseOutputPath">The output path where everything will be outputted.</param> internal CSProjectInfo(UnityProjectInfo unityProjectInfo, AssemblyDefinitionInfo assemblyDefinitionInfo, string baseOutputPath) : base(unityProjectInfo, assemblyDefinitionInfo.Guid, new Uri(Path.Combine(baseOutputPath, $"{assemblyDefinitionInfo.Name}.csproj")), assemblyDefinitionInfo.Name) { AssemblyDefinitionInfo = assemblyDefinitionInfo; ProjectType = GetProjectType(assemblyDefinitionInfo); InEditorPlatforms = GetCompilationPlatforms(true); PlayerPlatforms = GetCompilationPlatforms(false); if (InEditorPlatforms.Count == 0 && PlayerPlatforms.Count == 0) { Debug.LogError($"The assembly project '{Name}' doesn't contain any supported in-editor or player platform targets."); } ProjectDependencies = new ReadOnlyCollection <CSProjectDependency <CSProjectInfo> >(csProjectDependencies); }
/// <summary> /// Creates a new instance of the CSProject info. /// </summary> /// <param name="unityProjectInfo">Instance of parsed unity project info.</param> /// <param name="guid">The unique Guid of this reference item.</param> /// <param name="assemblyDefinitionInfo">The associated Assembly-Definition info.</param> /// <param name="assembly">The Unity assembly object associated with this csproj.</param> internal CSProjectInfo(UnityProjectInfo unityProjectInfo, AssemblyDefinitionInfo assemblyDefinitionInfo) : base(unityProjectInfo, assemblyDefinitionInfo.Guid, assemblyDefinitionInfo.Name) { AssemblyDefinitionInfo = assemblyDefinitionInfo; ProjectType = GetProjectType(assemblyDefinitionInfo); InEditorPlatforms = GetCompilationPlatforms(true); PlayerPlatforms = GetCompilationPlatforms(false); if (InEditorPlatforms.Count == 0 && PlayerPlatforms.Count == 0) { Debug.LogError($"The assembly project '{Name}' doesn't contain any supported in-editor or player platform targets."); } ProjectDependencies = new ReadOnlyCollection <CSProjectDependency <CSProjectInfo> >(csProjectDependencies); PluginDependencies = new ReadOnlyCollection <CSProjectDependency <PluginAssemblyInfo> >(pluginAssemblyDependencies); WinMDDependencies = new ReadOnlyCollection <CSProjectDependency <WinMDInfo> >(winmdDependencies); }
private static void RegenerateEverything(UnityProjectInfo unityProjectInfo, bool completeGeneration) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); long postCleanupAndCopyStamp = 0, solutionExportStart = 0, solutionExportEnd = 0, exporterStart = 0, exporterEnd = 0, propsFileGenerationStart = 0, propsFileGenerationEnd = 0; try { if (Directory.Exists(Utilities.MSBuildProjectFolder)) { // Create a copy of the packages as they might change after we create the MSBuild project foreach (string file in Directory.EnumerateFiles(Utilities.MSBuildProjectFolder, "*", SearchOption.TopDirectoryOnly)) { File.SetAttributes(file, FileAttributes.Normal); File.Delete(file); } } else { Directory.CreateDirectory(Utilities.MSBuildProjectFolder); } postCleanupAndCopyStamp = stopwatch.ElapsedMilliseconds; propsFileGenerationStart = stopwatch.ElapsedMilliseconds; MSBuildUnityProjectExporter.ExportCommonPropsFile(Exporter, MSBuildForUnityVersion, unityProjectInfo.CurrentPlayerPlatform); if (completeGeneration) { ExportCoreUnityPropFiles(unityProjectInfo); } propsFileGenerationEnd = stopwatch.ElapsedMilliseconds; solutionExportStart = stopwatch.ElapsedMilliseconds; if (completeGeneration) { DirectoryInfo directoryInfo = new DirectoryInfo(Utilities.MSBuildProjectFolder); unityProjectInfo.ExportSolution(Exporter, new FileInfo(Exporter.GetSolutionFilePath(unityProjectInfo)), directoryInfo); unityProjectInfo.ExportProjects(Exporter, directoryInfo); } MSBuildUnityProjectExporter.ExportTopLevelDependenciesProject(Exporter, MSBuildForUnityVersion, Config, new DirectoryInfo(Utilities.MSBuildProjectFolder), unityProjectInfo); solutionExportEnd = stopwatch.ElapsedMilliseconds; string nuGetConfigPath = Path.Combine(Utilities.AssetPath, Path.GetFileName(TemplateFiles.Instance.NuGetConfigPath)); // Copy the NuGet.config file if it does not exist if (!File.Exists(nuGetConfigPath)) { File.Copy(TemplateFiles.Instance.NuGetConfigPath, nuGetConfigPath); } foreach (string otherFile in TemplateFiles.Instance.OtherFiles) { File.Copy(otherFile, Path.Combine(Utilities.MSBuildProjectFolder, Path.GetFileName(otherFile))); } if (completeGeneration) { string buildProjectsFile = "BuildProjects.proj"; if (!File.Exists(Path.Combine(Utilities.MSBuildOutputFolder, buildProjectsFile))) { GenerateBuildProjectsFile(buildProjectsFile, Exporter.GetSolutionFilePath(unityProjectInfo), unityProjectInfo.AvailablePlatforms); } } } finally { stopwatch.Stop(); Debug.Log($"Whole Generate Projects process took {stopwatch.ElapsedMilliseconds} ms; actual generation took {stopwatch.ElapsedMilliseconds - postCleanupAndCopyStamp}; solution export: {solutionExportEnd - solutionExportStart}; exporter creation: {exporterEnd - exporterStart}; props file generation: {propsFileGenerationEnd - propsFileGenerationStart}"); } }
private static void RefreshGeneratedOutput(bool forceGenerateEverything, bool forceCompleteGeneration) { // In this method, the following must happen // - Clean up builds if necessary // - Generate the common props file if necessary // - Regenerate everything else if necessary // - Build if the clean was done BuildTarget currentBuildTarget = EditorUserBuildSettings.activeBuildTarget; ApiCompatibilityLevel targetFramework = PlayerSettings.GetApiCompatibilityLevel(EditorUserBuildSettings.selectedBuildTargetGroup); bool buildTargetOrFrameworkChanged = EditorPrefs.GetInt($"{nameof(MSBuildTools)}.{nameof(currentBuildTarget)}") != (int)currentBuildTarget || EditorPrefs.GetInt($"{nameof(MSBuildTools)}.{nameof(targetFramework)}") != (int)targetFramework || forceGenerateEverything; if (buildTargetOrFrameworkChanged || CSProjectAssetRemoved) { // We clean up previous build if the EditorPrefs currentBuildTarget or targetFramework is different from current ones. // Or a CS Project file has been removed and we need to clean up MSBuildProjectBuilder.TryBuildAllProjects(MSBuildProjectBuilder.CleanProfileName); } // Get the token file in the Unity Temp directory, if it exists. Version tokenVerison = GetCurrentTokenVersion(); // We regenerate, if the token file exists, and it's current version. bool doesCurrentVersionTokenFileExist = tokenVerison != null && tokenVerison == MSBuildForUnityVersion; // We perform the regeneration of complete or partial pass in the following cases: // - forceGenerateEverything is true (we are told to) // - buildTargetOrFrameworkChanged is true (target framework changed) // - doesCurrentVersionTokenFileExist is false (version changed, or editor just opened) // - CSProjectAssetChanged is true (a csproj file has been added) // - AssemblyDefinitionAssetChanged is true and Config.FullGenerationEnabled is true (asmdef change and full regen is enabled that will gen based off asmdefs) // - AutoGenerateEnabled and token file doesn't exist or shouldClean is true bool performRegeneration = forceGenerateEverything || buildTargetOrFrameworkChanged || !doesCurrentVersionTokenFileExist || CSProjectAssetChanged || (AssemblyDefinitionAssetChanged && Config.FullGenerationEnabled); // Reset the values after using them CSProjectAssetChanged = false; AssemblyDefinitionAssetChanged = false; CSProjectAssetRemoved = false; if (performRegeneration || unityProjectInfo == null) { // Create the project info only if it's null or we need to regenerate unityProjectInfo = new UnityProjectInfo(Debug.unityLogger, SupportedBuildTargets, Config, Config.FullGenerationEnabled || forceCompleteGeneration); } if (performRegeneration) { // If we are forced complete, then we regenerate, otherwise perform the one that is selected RegenerateEverything(unityProjectInfo, Config.FullGenerationEnabled || forceCompleteGeneration); } if (!doesCurrentVersionTokenFileExist) { foreach (string tokenFile in Directory.GetFiles(Path.Combine(Utilities.ProjectPath, "Temp"), "*_token.msb4u", SearchOption.TopDirectoryOnly)) { File.Delete(tokenFile); } File.Create(Path.Combine(Utilities.ProjectPath, "Temp", $"{MSBuildForUnityVersion.ToString(3)}_token.msb4u")) .Dispose(); } // Write the current targetframework and build target EditorPrefs.SetInt($"{nameof(MSBuildTools)}.{nameof(currentBuildTarget)}", (int)currentBuildTarget); EditorPrefs.SetInt($"{nameof(MSBuildTools)}.{nameof(targetFramework)}", (int)targetFramework); // If we cleaned, now build, or if we regenerated if (buildTargetOrFrameworkChanged || performRegeneration) { MSBuildProjectBuilder.TryBuildAllProjects(MSBuildProjectBuilder.BuildProfileName); } }
public static void RegenerateSDKProjects() { RegenerateEverything(unityProjectInfo = new UnityProjectInfo(Debug.unityLogger, SupportedBuildTargets, Config, performCompleteParse: true), completeGeneration: true); Debug.Log($"{nameof(RegenerateSDKProjects)} Completed Succesfully."); }
/// <summary> /// Creates a new instance of the <see cref="PluginAssemblyInfo"/>. /// </summary> public WinMDInfo(UnityProjectInfo unityProjectInfo, Guid guid, string fullPath) : base(unityProjectInfo, guid, Path.GetFileNameWithoutExtension(fullPath)) { ReferencePath = new Uri(fullPath); ParseYAMLFile(); }
/// <summary> /// Creates a new instance. /// </summary> /// <param name="unityProjectInfo">Instance of parsed unity project info.</param> /// <param name="guid">The unique Guid of this reference item.</param> /// <param name="referencePath">The output path to the reference item.</param> /// <param name="name">The name of the reference.</param> protected ReferenceItemInfo(UnityProjectInfo unityProjectInfo, Guid guid, string name) { UnityProjectInfo = unityProjectInfo; Guid = guid; Name = name; }
public static void ExportTopLevelDependenciesProject(IUnityProjectExporter exporter, Version msb4uVerison, MSBuildToolsConfig config, DirectoryInfo generatedProjectFolder, UnityProjectInfo unityProjectInfo) { string projectPath = GetProjectFilePath(Utilities.AssetPath, $"{unityProjectInfo.UnityProjectName}.Dependencies"); ITopLevelDependenciesProjectExporter projectExporter = exporter.CreateTopLevelDependenciesProjectExporter(new FileInfo(projectPath), generatedProjectFolder); projectExporter.MSBuildForUnityVersion = msb4uVerison; projectExporter.Guid = config.DependenciesProjectGuid; if (unityProjectInfo.AvailablePlatforms != null) { 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); 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) { projectExporter.References.Add(new ProjectReference() { ReferencePath = new Uri(otherProjectFile), IsGenerated = false }); } projectExporter.Write(); }