예제 #1
0
        /// <summary>
        /// Compiles all script modules.
        /// </summary>
        /// <param name="Modules">Module project filenames.</param>
        private static void CompileModules(List <string> Modules)
        {
            string DependencyFile = Path.Combine(CommandUtils.CmdEnv.EngineSavedFolder, "UATModuleHashes.xml");

            if (AreDependenciesUpToDate(Modules, DependencyFile) && !GlobalCommandLine.IgnoreDependencies)
            {
                Log.TraceInformation("Dependencies are up to date. Skipping compile.");
                return;
            }

            Log.TraceInformation("Dependencies are out of date. Compiling scripts....");

            // clean old assemblies
            CleanupScriptsAssemblies();

            DateTime StartTime = DateTime.Now;

            string BuildTool = CommandUtils.CmdEnv.MsBuildExe;

            // msbuild (standard on windows, in mono >=5.0 is preferred due to speed and parallel compilation)
            bool UseParallelMsBuild = Path.GetFileNameWithoutExtension(BuildTool).ToLower() == "msbuild";

            if (UseParallelMsBuild)
            {
                string ModulesList = string.Join(";", Modules);

                // Mono has an issue where arugments with semicolons or commas can't be passed through to
                // as arguments so we need to manually construct a temp file with the list of modules
                // see (https://github.com/Microsoft/msbuild/issues/471)
                var UATProjTemplate = CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, @"Engine\Source\Programs\AutomationTool\Scripts\UAT.proj");
                var UATProjFile     = Path.Combine(CommandUtils.CmdEnv.EngineSavedFolder, "UATTempProj.proj");

                string ProjContents = File.ReadAllText(UATProjTemplate);
                ProjContents = ProjContents.Replace("$(Modules)", ModulesList);

                Directory.CreateDirectory(Path.GetDirectoryName(UATProjFile));
                File.WriteAllText(UATProjFile, ProjContents);

                string MsBuildVerbosity = Log.OutputLevel >= LogEventType.Verbose ? "minimal" : "quiet";

                var CmdLine = String.Format("\"{0}\" /p:Configuration={1} /verbosity:{2} /nologo", UATProjFile, BuildConfig, MsBuildVerbosity);
                // suppress the run command because it can be long and intimidating, making the logs around this code harder to read.
                var Result = CommandUtils.Run(BuildTool, CmdLine, Options: CommandUtils.ERunOptions.Default | CommandUtils.ERunOptions.NoLoggingOfRunCommand | CommandUtils.ERunOptions.LoggingOfRunDuration);
                if (Result.ExitCode != 0)
                {
                    throw new AutomationException(String.Format("Failed to build \"{0}\":{1}{2}", UATProjFile, Environment.NewLine, Result.Output));
                }
            }
            else
            {
                // Make sure DefaultScriptsDLLName is compiled first
                var DefaultScriptsProjName = Path.ChangeExtension(DefaultScriptsDLLName, "csproj");

                // Primary modules must be built first
                List <string> PrimaryModules = Modules.Where(M => M.IndexOf(DefaultScriptsProjName, StringComparison.InvariantCultureIgnoreCase) >= 0).ToList();

                foreach (var ModuleName in PrimaryModules)
                {
                    Log.TraceInformation("Building script module: {0}", ModuleName);
                    try
                    {
                        CompileScriptModule(ModuleName);
                    }
                    catch (Exception Ex)
                    {
                        CommandUtils.LogError(LogUtils.FormatException(Ex));
                        throw new AutomationException("Failed to compile module {0}", ModuleName);
                    }
                    break;
                }

                // Second pass, compile everything else
                List <string> SecondaryModules = Modules.Where(M => !PrimaryModules.Contains(M)).ToList();

                // Non-parallel method
                foreach (var ModuleName in SecondaryModules)
                {
                    Log.TraceInformation("Building script module: {0}", ModuleName);
                    try
                    {
                        CompileScriptModule(ModuleName);
                    }
                    catch (Exception Ex)
                    {
                        CommandUtils.LogError(LogUtils.FormatException(Ex));
                        throw new AutomationException("Failed to compile module {0}", ModuleName);
                    }
                }
            }

            TimeSpan Duration = DateTime.Now - StartTime;

            Log.TraceInformation("Compiled {0} modules in {1} secs", Modules.Count, Duration.TotalSeconds);

            HashCollection NewHashes = HashModules(Modules);

            if (NewHashes == null)
            {
                Log.TraceWarning("Failed to save dependency info!");
            }
            else
            {
                NewHashes.SaveToFile(DependencyFile);
                Log.TraceVerbose("Wrote depencencies to {0}", DependencyFile);
            }
        }