Example #1
0
        /// <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);
        }
Example #2
0
 /// <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;
 }
Example #3
0
        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);
            }
        }
Example #4
0
        /// <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.");
 }
Example #11
0
 /// <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();
        }