Example #1
0
        /// <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 void FindAndCompileAllScripts(string ScriptsForProjectFileName, List <string> AdditionalScriptsFolders)
        {
            bool DoCompile = false;

            if (GlobalCommandLine.Compile)
            {
                DoCompile = true;
            }

            // Change to Engine\Source (if exists) to properly discover all UBT classes
            var OldCWD             = Environment.CurrentDirectory;
            var UnrealBuildToolCWD = CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, "Engine", "Source");

            if (Directory.Exists(UnrealBuildToolCWD))
            {
                Environment.CurrentDirectory = UnrealBuildToolCWD;
            }
            // Register all the classes inside UBT
            Log.TraceVerbose("Registering UBT Classes.");
            UnrealBuildTool.UnrealBuildTool.RegisterAllUBTClasses();
            Environment.CurrentDirectory = OldCWD;

            // Compile only if not disallowed.
            if (DoCompile && !String.IsNullOrEmpty(CommandUtils.CmdEnv.MsBuildExe))
            {
                CleanupScriptsAssemblies();
                FindAndCompileScriptModules(ScriptsForProjectFileName, AdditionalScriptsFolders);
            }

            var ScriptAssemblies = new List <Assembly>();

            LoadPreCompiledScriptAssemblies(ScriptAssemblies);

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

            // Instantiate all the automation classes for interrogation
            Log.TraceVerbose("Creating commands.");
            ScriptCommands = new CaselessDictionary <Type>();
            foreach (var CompiledScripts in ScriptAssemblies)
            {
                foreach (var ClassType in CompiledScripts.GetTypes())
                {
                    if (ClassType.IsSubclassOf(typeof(BuildCommand)) && ClassType.IsAbstract == false)
                    {
                        if (ScriptCommands.ContainsKey(ClassType.Name) == false)
                        {
                            ScriptCommands.Add(ClassType.Name, ClassType);
                        }
                        else
                        {
                            Log.TraceWarning("Unable to add command {0} twice. Previous: {1}, Current: {2}", ClassType.Name,
                                             ClassType.AssemblyQualifiedName, ScriptCommands[ClassType.Name].AssemblyQualifiedName);
                        }
                    }
                }
            }
        }
        /// <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 void FindAndCompileAllScripts(string ScriptsForProjectFileName, List <string> AdditionalScriptsFolders)
        {
            bool DoCompile = false;

            if (GlobalCommandLine.Compile)
            {
                DoCompile = true;
            }

            // Compile only if not disallowed.
            if (DoCompile && !String.IsNullOrEmpty(CommandUtils.CmdEnv.MsBuildExe))
            {
                CleanupScriptsAssemblies();
                FindAndCompileScriptModules(ScriptsForProjectFileName, AdditionalScriptsFolders);
            }

            var ScriptAssemblies = new List <Assembly>();

            LoadPreCompiledScriptAssemblies(ScriptAssemblies);

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

            // Instantiate all the automation classes for interrogation
            Log.TraceVerbose("Creating commands.");
            ScriptCommands = new Dictionary <string, Type>(StringComparer.InvariantCultureIgnoreCase);
            foreach (var CompiledScripts in ScriptAssemblies)
            {
                try
                {
                    foreach (var 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 (Exception Ex)
                {
                    throw new AutomationException("Failed to add commands from {0}. {1}", CompiledScripts, Ex);
                }
            }
        }
        /// <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);
                }
            }
        }