Esempio n. 1
0
        /// <summary>
        /// Creates a hash collection that represents the state of all modules in this list. If
        /// a module has no current output or is missing files then a null collection will be returned
        /// </summary>
        /// <param name="Modules"></param>
        /// <returns></returns>
        private static HashCollection HashModules(IEnumerable <string> Modules, bool WarnOnFailure = true)
        {
            HashCollection Hashes = new HashCollection();

            foreach (string Module in Modules)
            {
                // this project is built by the AutomationTool project that the RunUAT script builds so
                // it will always be newer than was last built
                if (Module.Contains("AutomationUtils.Automation"))
                {
                    continue;
                }

                CsProjectInfo Proj;

                Dictionary <string, string> Properties = new Dictionary <string, string>();
                Properties.Add("Platform", "AnyCPU");
                Properties.Add("Configuration", "Development");

                FileReference ModuleFile = new FileReference(Module);

                if (!CsProjectInfo.TryRead(ModuleFile, Properties, out Proj))
                {
                    if (WarnOnFailure)
                    {
                        Log.TraceWarning("Failed to read file {0}", ModuleFile);
                    }
                    return(null);
                }

                if (!Hashes.AddCsProjectInfo(Proj, HashCollection.HashType.MetaData))
                {
                    if (WarnOnFailure)
                    {
                        Log.TraceWarning("Failed to hash file {0}", ModuleFile);
                    }
                    return(null);
                }
            }

            return(Hashes);
        }
        /// <summary>
        /// Finds and/or compiles all script files and assemblies.
        /// </summary>
        /// <param name="ScriptsForProjectFileName">Path to the current project. May be null, in which case we compile scripts for all projects.</param>
        /// <param name="AdditionalScriptsFolders">Additional script fodlers to look for source files in.</param>
        public static void FindAndCompileAllScripts(string ScriptsForProjectFileName, List <string> AdditionalScriptsFolders)
        {
            // Find all the project files
            Stopwatch            SearchTimer  = Stopwatch.StartNew();
            List <FileReference> ProjectFiles = FindAutomationProjects(ScriptsForProjectFileName, AdditionalScriptsFolders);

            Log.TraceLog("Found {0} project files in {1:0.000}s", ProjectFiles.Count, SearchTimer.Elapsed.TotalSeconds);

            // Get the default properties for compiling the projects
            Dictionary <string, string> MsBuildProperties = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);

            MsBuildProperties.Add("Platform", "AnyCPU");
            MsBuildProperties.Add("Configuration", BuildConfig);
            MsBuildProperties.Add("EngineDir", CommandUtils.EngineDirectory.FullName);

            // Read all the projects
            Stopwatch ParsingTimer = Stopwatch.StartNew();

            CsProjectInfo[] Projects = new CsProjectInfo[ProjectFiles.Count];
            Parallel.For(0, ProjectFiles.Count, Idx => Projects[Idx] = CsProjectInfo.Read(ProjectFiles[Idx], MsBuildProperties));
            Log.TraceLog("Parsed project files in {0:0.000}s", ParsingTimer.Elapsed.TotalSeconds);

            // Compile only if not disallowed.
            if (GlobalCommandLine.Compile && !String.IsNullOrEmpty(CommandUtils.CmdEnv.MsBuildExe))
            {
                List <CsProjectInfo> CompileProjects = new List <CsProjectInfo>(Projects);
                if (CommandUtils.IsEngineInstalled())
                {
                    CompileProjects.RemoveAll(x => x.ProjectPath.IsUnderDirectory(CommandUtils.EngineDirectory));
                }
                CompileAutomationProjects(CompileProjects, MsBuildProperties);
            }

            // Get all the build artifacts
            BuildProducts = new HashSet <FileReference>();

            HashSet <DirectoryReference> OutputDirs = new HashSet <DirectoryReference>();

            OutputDirs.Add(DirectoryReference.Combine(CommandUtils.EngineDirectory, "Binaries", "DotNET"));             // Don't want any artifacts from this directory (just AutomationTool.exe and AutomationScripts.dll)

            foreach (CsProjectInfo Project in Projects)
            {
                DirectoryReference OutputDir;
                if (!Project.TryGetOutputDir(out OutputDir))
                {
                    throw new AutomationException("Unable to get output directory for {0}", Project.ProjectPath);
                }

                if (OutputDirs.Add(OutputDir))
                {
                    BuildProducts.UnionWith(DirectoryReference.EnumerateFiles(OutputDir));
                }
            }

            // Load everything
            Stopwatch       LoadTimer  = Stopwatch.StartNew();
            List <Assembly> Assemblies = LoadAutomationAssemblies(Projects);

            Log.TraceLog("Loaded assemblies in {0:0.000}s", LoadTimer.Elapsed.TotalSeconds);

            // Setup platforms
            Platform.InitializePlatforms(Assemblies.ToArray());

            // Instantiate all the automation classes for interrogation
            Log.TraceVerbose("Creating commands.");
            ScriptCommands = new Dictionary <string, Type>(StringComparer.InvariantCultureIgnoreCase);
            foreach (Assembly CompiledScripts in Assemblies)
            {
                try
                {
                    foreach (Type ClassType in CompiledScripts.GetTypes())
                    {
                        if (ClassType.IsSubclassOf(typeof(BuildCommand)) && ClassType.IsAbstract == false)
                        {
                            if (ScriptCommands.ContainsKey(ClassType.Name) == false)
                            {
                                ScriptCommands.Add(ClassType.Name, ClassType);
                            }
                            else
                            {
                                bool IsSame = string.Equals(ClassType.AssemblyQualifiedName, ScriptCommands[ClassType.Name].AssemblyQualifiedName);

                                if (IsSame == false)
                                {
                                    Log.TraceWarning("Unable to add command {0} twice. Previous: {1}, Current: {2}", ClassType.Name,
                                                     ClassType.AssemblyQualifiedName, ScriptCommands[ClassType.Name].AssemblyQualifiedName);
                                }
                            }
                        }
                    }
                }
                catch (ReflectionTypeLoadException LoadEx)
                {
                    foreach (Exception SubEx in LoadEx.LoaderExceptions)
                    {
                        Log.TraceWarning("Got type loader exception: {0}", SubEx.ToString());
                    }
                    throw new AutomationException("Failed to add commands from {0}. {1}", CompiledScripts, LoadEx);
                }
                catch (Exception Ex)
                {
                    throw new AutomationException("Failed to add commands from {0}. {1}", CompiledScripts, Ex);
                }
            }
        }