/// <summary>
		/// Gets a parameter from the command line if it hasn't been specified in the constructor. 
		/// If the command line is not available, default value will be used.
		/// </summary>
		/// <param name="Command">Command to parse the command line for. Can be null.</param>
		/// <param name="SpecifiedValue">Value specified in the constructor (or not)</param>
		/// <param name="Default">Default value.</param>
		/// <param name="ParamNames">Command line parameter names to parse.</param>
		/// <returns>Parameter value.</returns>
		bool GetParamValueIfNotSpecified(CommandUtils Command, bool? SpecifiedValue, bool Default, params string[] ParamNames)
		{
			if (SpecifiedValue.HasValue)
			{
				return SpecifiedValue.Value;
			}
			else if (Command != null)
			{
				foreach (var Param in ParamNames)
				{
					if (Command.ParseParam(Param))
					{
						return true;
					}
				}
			}
			return Default;
		}
		public override void SetupOptionsForRun(ref string AppName, ref CommandUtils.ERunOptions Options, ref string CommandLine)
		{
			if (AppName == "sh" || AppName == "xbuild" || AppName == "codesign")
			{
				Options &= ~CommandUtils.ERunOptions.AppMustExist;
			}
			if (AppName == "xbuild")
			{
				AppName = "xbuild";
				CommandLine = (String.IsNullOrEmpty(CommandLine) ? "" : CommandLine) + " /verbosity:quiet /nologo";
				// For some reason AutomationScripts.Automation.csproj has ToolsVersion set
				// to 11.0, which is no available on linux, so force ToolsVersion to 4.0
				CommandLine += " /tv:4.0";
				// Pass #define MONO to all the automation scripts (see XboxOne)
				CommandLine += " /p:DefineConstants=MONO";
				// Some projects have TargetFrameworkProfile=Client which causes warnings on Linux
				// so force it to empty.
				CommandLine += " /p:TargetFrameworkProfile=";
			}
			if (AppName.EndsWith(".exe") || ((AppName.Contains("/Binaries/Win64/") || AppName.Contains("/Binaries/Linux/")) && string.IsNullOrEmpty(Path.GetExtension(AppName))))
			{
				if (AppName.Contains("/Binaries/Win64/") || AppName.Contains("/Binaries/Linux/"))
				{
					AppName = AppName.Replace("/Binaries/Win64/", "/Binaries/Linux/");
					AppName = AppName.Replace("-cmd.exe", "");
					AppName = AppName.Replace("-Cmd.exe", "");
					AppName = AppName.Replace(".exe", "");
				}
				else
				{
					// It's a C# app, so run it with Mono
					CommandLine = "\"" + AppName + "\" " + (String.IsNullOrEmpty(CommandLine) ? "" : CommandLine);
					AppName = "mono";
					Options &= ~CommandUtils.ERunOptions.AppMustExist;
				}
			}
		}
		/// <summary>
		/// Gets optional parameter from the command line if it hasn't been specified in the constructor. 
		/// If the command line is not available or the command has not been specified in the command line, default value will be used.
		/// </summary>
		/// <param name="Command">Command to parse the command line for. Can be null.</param>
		/// <param name="SpecifiedValue">Value specified in the constructor (or not)</param>
		/// <param name="Default">Default value.</param>
		/// <param name="TrueParam">Name of a parameter that sets the value to 'true', for example: -clean</param>
		/// <param name="FalseParam">Name of a parameter that sets the value to 'false', for example: -noclean</param>
		/// <returns>Parameter value or default value if the paramater has not been specified</returns>
		bool? GetOptionalParamValueIfNotSpecified(CommandUtils Command, bool? SpecifiedValue, bool? Default, string TrueParam, string FalseParam)
		{
			if (SpecifiedValue.HasValue)
			{
				return SpecifiedValue.Value;
			}
			else if (Command != null)
			{
				bool? Value = null;
				if (!String.IsNullOrEmpty(TrueParam) && Command.ParseParam(TrueParam))
				{
					Value = true;
				}
				else if (!String.IsNullOrEmpty(FalseParam) && Command.ParseParam(FalseParam))
				{
					Value = false;
				}
				if (Value.HasValue)
				{
					return Value;
				}
			}
			return Default;
		}
        /// <summary>
        /// Runs a commandlet using Engine/Binaries/Win64/UE4Editor-Cmd.exe.
        /// </summary>
        /// <param name="ProjectFile">Project name.</param>
        /// <param name="UE4Exe">The name of the UE4 Editor executable to use.</param>
        /// <param name="Commandlet">Commandlet name.</param>
        /// <param name="Parameters">Command line parameters (without -run=)</param>
        public static void RunCommandlet(FileReference ProjectName, string UE4Exe, string Commandlet, string Parameters = null)
        {
            Log("Running UE4Editor {0} for project {1}", Commandlet, ProjectName);

            var CWD = Path.GetDirectoryName(UE4Exe);

            string EditorExe = UE4Exe;

            if (String.IsNullOrEmpty(CWD))
            {
                EditorExe = HostPlatform.Current.GetUE4ExePath(UE4Exe);
                CWD       = CombinePaths(CmdEnv.LocalRoot, HostPlatform.Current.RelativeBinariesFolder);
            }

            PushDir(CWD);

            DateTime StartTime = DateTime.UtcNow;

            string LocalLogFile = LogUtils.GetUniqueLogName(CombinePaths(CmdEnv.EngineSavedFolder, Commandlet));

            Log("Commandlet log file is {0}", LocalLogFile);
            string Args = String.Format(
                "{0} -run={1} {2} -abslog={3} -stdout -CrashForUAT -unattended {5}{4}",
                (ProjectName == null) ? "" : CommandUtils.MakePathSafeToUseWithCommandLine(ProjectName.FullName),
                Commandlet,
                String.IsNullOrEmpty(Parameters) ? "" : Parameters,
                CommandUtils.MakePathSafeToUseWithCommandLine(LocalLogFile),
                IsBuildMachine ? "-buildmachine" : "",
                (GlobalCommandLine.Verbose || GlobalCommandLine.AllowStdOutLogVerbosity) ? "-AllowStdOutLogVerbosity " : ""
                );
            ERunOptions Opts = ERunOptions.Default;

            if (GlobalCommandLine.UTF8Output)
            {
                Args += " -UTF8Output";
                Opts |= ERunOptions.UTF8Output;
            }
            var RunResult = Run(EditorExe, Args, Options: Opts);

            PopDir();

            // Draw attention to signal exit codes on Posix systems, rather than just printing the exit code
            if (RunResult.ExitCode > 128 && RunResult.ExitCode < 128 + 32)
            {
                if (RunResult.ExitCode == 139)
                {
                    CommandUtils.LogError("Editor terminated abnormally due to a segmentation fault");
                }
                else
                {
                    CommandUtils.LogError("Editor terminated abnormally with signal {0}", RunResult.ExitCode - 128);
                }
            }

            // If we're running on a Mac, dump all the *.crash files that were generated while the editor was running.
            if (HostPlatform.Current.HostEditorPlatform == UnrealTargetPlatform.Mac)
            {
                // If the exit code indicates the main process crashed, introduce a small delay because the crash report is written asynchronously.
                // If we exited normally, still check without waiting in case SCW or some other child process crashed.
                if (RunResult.ExitCode > 128)
                {
                    CommandUtils.Log("Pausing before checking for crash logs...");
                    Thread.Sleep(10 * 1000);
                }

                // Create a list of directories containing crash logs, and add the system log folder
                List <string> CrashDirs = new List <string>();
                CrashDirs.Add("/Library/Logs/DiagnosticReports");

                // Add the user's log directory too
                string HomeDir = Environment.GetEnvironmentVariable("HOME");
                if (!String.IsNullOrEmpty(HomeDir))
                {
                    CrashDirs.Add(Path.Combine(HomeDir, "Library/Logs/DiagnosticReports"));
                }

                // Check each directory for crash logs
                List <FileInfo> CrashFileInfos = new List <FileInfo>();
                foreach (string CrashDir in CrashDirs)
                {
                    try
                    {
                        DirectoryInfo CrashDirInfo = new DirectoryInfo(CrashDir);
                        if (CrashDirInfo.Exists)
                        {
                            CrashFileInfos.AddRange(CrashDirInfo.EnumerateFiles("*.crash", SearchOption.TopDirectoryOnly).Where(x => x.LastWriteTimeUtc >= StartTime));
                        }
                    }
                    catch (UnauthorizedAccessException)
                    {
                        // Not all account types can access /Library/Logs/DiagnosticReports
                    }
                }

                // Dump them all to the log
                foreach (FileInfo CrashFileInfo in CrashFileInfos)
                {
                    // snmpd seems to often crash (suspect due to it being starved of CPU cycles during cooks)
                    if (!CrashFileInfo.Name.StartsWith("snmpd_"))
                    {
                        CommandUtils.Log("Found crash log - {0}", CrashFileInfo.FullName);
                        try
                        {
                            string[] Lines = File.ReadAllLines(CrashFileInfo.FullName);
                            foreach (string Line in Lines)
                            {
                                CommandUtils.Log("Crash: {0}", Line);
                            }
                        }
                        catch (Exception Ex)
                        {
                            CommandUtils.LogWarning("Failed to read file ({0})", Ex.Message);
                        }
                    }
                }
            }

            // Copy the local commandlet log to the destination folder.
            string DestLogFile = LogUtils.GetUniqueLogName(CombinePaths(CmdEnv.LogFolder, Commandlet));

            if (!CommandUtils.CopyFile_NoExceptions(LocalLogFile, DestLogFile))
            {
                CommandUtils.LogWarning("Commandlet {0} failed to copy the local log file from {1} to {2}. The log file will be lost.", Commandlet, LocalLogFile, DestLogFile);
            }
            string ProjectStatsDirectory = CombinePaths((ProjectName == null)? CombinePaths(CmdEnv.LocalRoot, "Engine") : Path.GetDirectoryName(ProjectName.FullName), "Saved", "Stats");

            if (Directory.Exists(ProjectStatsDirectory))
            {
                string DestCookerStats = CmdEnv.LogFolder;
                foreach (var StatsFile in Directory.EnumerateFiles(ProjectStatsDirectory, "*.csv"))
                {
                    if (!CommandUtils.CopyFile_NoExceptions(StatsFile, CombinePaths(DestCookerStats, Path.GetFileName(StatsFile))))
                    {
                        CommandUtils.LogWarning("Commandlet {0} failed to copy the local log file from {1} to {2}. The log file will be lost.", Commandlet, StatsFile, CombinePaths(DestCookerStats, Path.GetFileName(StatsFile)));
                    }
                }
            }
//			else
//			{
//				CommandUtils.LogWarning("Failed to find directory {0} will not save stats", ProjectStatsDirectory);
//			}

            // Whether it was copied correctly or not, delete the local log as it was only a temporary file.
            CommandUtils.DeleteFile_NoExceptions(LocalLogFile);

            if (RunResult.ExitCode != 0)
            {
                throw new CommandletException(DestLogFile, RunResult.ExitCode, "BUILD FAILED: Failed while running {0} for {1}; see log {2}", Commandlet, ProjectName, DestLogFile);
            }
        }
Exemple #5
0
 public virtual bool PublishSymbols(DirectoryReference SymbolStoreDirectory, List <FileReference> Files, string Product, string BuildVersion = null)
 {
     CommandUtils.LogWarning("PublishSymbols() has not been implemented for {0}", PlatformType.ToString());
     return(false);
 }
Exemple #6
0
        /// <summary>
        /// Attempts to autodetect project properties.
        /// </summary>
        /// <param name="RawProjectPath">Full project path.</param>
        /// <returns>Project properties.</returns>
        private static ProjectProperties DetectProjectProperties(FileReference RawProjectPath, List <UnrealTargetPlatform> ClientTargetPlatforms, bool AssetNativizationRequested)
        {
            var Properties = new ProjectProperties();

            Properties.RawProjectPath = RawProjectPath;

            // detect if the project is content only, but has non-default build settings
            List <string> ExtraSearchPaths = null;

            if (RawProjectPath != null)
            {
                if (RequiresTempTarget(RawProjectPath, ClientTargetPlatforms, AssetNativizationRequested))
                {
                    GenerateTempTarget(RawProjectPath);
                    Properties.bWasGenerated = true;
                    ExtraSearchPaths         = new List <string>();

                    string TempTargetDir = CommandUtils.CombinePaths(Path.GetDirectoryName(RawProjectPath.FullName), "Intermediate", "Source");
                    ExtraSearchPaths.Add(TempTargetDir);

                    // in case the RulesCompiler (what we use to find all the
                    // Target.cs files) has already cached the contents of this
                    // directory, then we need to invalidate that cache (so
                    // it'll find/use the new Target.cs file)
                    RulesCompiler.InvalidateRulesFileCache(TempTargetDir);
                }
                else if (File.Exists(Path.Combine(Path.GetDirectoryName(RawProjectPath.FullName), "Intermediate", "Source", Path.GetFileNameWithoutExtension(RawProjectPath.FullName) + ".Target.cs")))
                {
                    File.Delete(Path.Combine(Path.GetDirectoryName(RawProjectPath.FullName), "Intermediate", "Source", Path.GetFileNameWithoutExtension(RawProjectPath.FullName) + ".Target.cs"));
                }
            }

            if (CommandUtils.CmdEnv.HasCapabilityToCompile)
            {
                DetectTargetsForProject(Properties, ExtraSearchPaths);
                Properties.bIsCodeBasedProject = !CommandUtils.IsNullOrEmpty(Properties.Targets) || !CommandUtils.IsNullOrEmpty(Properties.Programs);
            }
            else
            {
                // should never ask for engine targets if we can't compile
                if (RawProjectPath == null)
                {
                    throw new AutomationException("Cannot determine engine targets if we can't compile.");
                }

                Properties.bIsCodeBasedProject = Properties.bWasGenerated;
                // if there's a Source directory with source code in it, then mark us as having source code
                string SourceDir = CommandUtils.CombinePaths(Path.GetDirectoryName(RawProjectPath.FullName), "Source");
                if (Directory.Exists(SourceDir))
                {
                    string[] CppFiles = Directory.GetFiles(SourceDir, "*.cpp", SearchOption.AllDirectories);
                    string[] HFiles   = Directory.GetFiles(SourceDir, "*.h", SearchOption.AllDirectories);
                    Properties.bIsCodeBasedProject |= (CppFiles.Length > 0 || HFiles.Length > 0);
                }
            }

            // check to see if the uproject loads modules, only if we haven't already determined it is a code based project
            if (!Properties.bIsCodeBasedProject && RawProjectPath != null)
            {
                string uprojectStr = File.ReadAllText(RawProjectPath.FullName);
                Properties.bIsCodeBasedProject = uprojectStr.Contains("\"Modules\"");
            }

            // Get all ini files
            if (RawProjectPath != null)
            {
                CommandUtils.LogVerbose("Loading ini files for {0}", RawProjectPath);

                var EngineDirectory = CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, "Engine");
                foreach (UnrealTargetPlatform TargetPlatformType in Enum.GetValues(typeof(UnrealTargetPlatform)))
                {
                    if (TargetPlatformType != UnrealTargetPlatform.Unknown)
                    {
                        var Config = ConfigCacheIni.CreateConfigCacheIni(TargetPlatformType, "Engine", RawProjectPath.Directory, new DirectoryReference(EngineDirectory));
                        Properties.EngineConfigs.Add(TargetPlatformType, Config);
                    }
                }

                foreach (UnrealTargetPlatform TargetPlatformType in Enum.GetValues(typeof(UnrealTargetPlatform)))
                {
                    if (TargetPlatformType != UnrealTargetPlatform.Unknown)
                    {
                        var Config = ConfigCacheIni.CreateConfigCacheIni(TargetPlatformType, "Game", RawProjectPath.Directory);
                        Properties.GameConfigs.Add(TargetPlatformType, Config);
                    }
                }
            }

            return(Properties);
        }
        private void SetLocalRootPath()
        {
            var LocalRootPath = CommandUtils.ConvertSeparators(PathSeparator.Slash, RootFromUATLocation(UATExe));

            CommandUtils.ConditionallySetEnvVar(EnvVarNames.LocalRoot, LocalRootPath);
        }
        /// <summary>
        /// Constructor. Be sure to use this.ParamName to set the actual property name as parameter names and property names
        /// overlap here.
        /// If a parameter value is not set, it will be parsed from the command line if the command is null, the default value will be used.
        /// </summary>
        public ProjectParams(			
			string RawProjectPath,

			CommandUtils Command = null,
			string Device = null,			
			string MapToRun = null,			
			string Port = null,
			string RunCommandline = null,						
			string StageCommandline = null,
            string BundleName = null,
			string StageDirectoryParam = null,
			string UE4Exe = null,
			string SignPak = null,
			List<UnrealTargetConfiguration> ClientConfigsToBuild = null,
			List<UnrealTargetConfiguration> ServerConfigsToBuild = null,
			ParamList<string> MapsToCook = null,
			ParamList<string> DirectoriesToCook = null,
			ParamList<string> ClientCookedTargets = null,
			ParamList<string> EditorTargets = null,
			ParamList<string> ServerCookedTargets = null,
			List<UnrealTargetPlatform> ClientTargetPlatforms = null,
			List<UnrealTargetPlatform> ServerTargetPlatforms = null,	
			bool? Build = null,
			bool? Cook = null,
			string CookFlavor = null,
			bool? Run = null,
			bool? SkipServer = null,
			bool? Clean = null,
            bool? Compressed = null,
            bool? UseDebugParamForEditorExe = null,
            bool? IterativeCooking = null,
			bool? CookOnTheFly = null,
			bool? CrashReporter = null,
			bool? DedicatedServer = null,
			bool? Client = null,
			bool? Deploy = null,
			bool? FileServer = null,
			bool? Foreign = null,
			bool? ForeignCode = null,
			bool? LogWindow = null,
			bool? NoCleanStage = null,
			bool? NoClient = null,
			bool? NoDebugInfo = null,
			bool? NoXGE = null,
			bool? Package = null,
			bool? Pak = null,
			bool? SignedPak = null,
            bool? NullRHI = null,
            bool? FakeClient = null,
            bool? EditorTest = null,
            bool? RunAutomationTests = null,
            string RunAutomationTest = null,
            int? CrashIndex = null,
            bool? Rocket = null,
			bool? SkipCook = null,
			bool? SkipCookOnTheFly = null,
			bool? SkipPak = null,
			bool? SkipStage = null,
			bool? Stage = null,
			bool? Manifests = null,
			bool? Unattended = null,
			int? NumClients = null,
			bool? Archive = null,
			string ArchiveDirectoryParam = null,
			ParamList<string> ProgramTargets = null,
			bool? Distribution = null
			)
        {
            //
            //// Use this.Name with properties and fields!
            //

            this.RawProjectPath = RawProjectPath;
            if (MapsToCook != null)
            {
                this.MapsToCook = MapsToCook;
            }
            if (DirectoriesToCook != null)
            {
                this.DirectoriesToCook = DirectoriesToCook;
            }
            if (ClientCookedTargets != null)
            {
                this.ClientCookedTargets = ClientCookedTargets;
            }
            if (ServerCookedTargets != null)
            {
                this.ServerCookedTargets = ServerCookedTargets;
            }
            if (EditorTargets != null)
            {
                this.EditorTargets = EditorTargets;
            }
            if (ProgramTargets != null)
            {
                this.ProgramTargets = ProgramTargets;
            }

            // Parse command line params for client platforms "-TargetPlatform=", "-Platform=" and also "-Win64", "-Mac" etc.
            this.ClientTargetPlatforms = SetupTargetPlatforms(Command, ClientTargetPlatforms, new ParamList<UnrealTargetPlatform>() {UnrealTargetPlatform.Win64}, true, "TargetPlatform", "Platform");

            // Parse command line params for server paltforms "-ServerTargetPlatform", "-ServerPlatform"; "-Win64" etc is not allowed here
            this.ServerTargetPlatforms = SetupTargetPlatforms(Command, ServerTargetPlatforms, this.ClientTargetPlatforms, false, "ServerTargetPlatform", "ServerPlatform");

            this.Build = GetParamValueIfNotSpecified(Command, Build, this.Build, "build");
            this.Run = GetParamValueIfNotSpecified(Command, Run, this.Run, "run");
            this.Cook = GetParamValueIfNotSpecified(Command, Cook, this.Cook, "cook");
            this.CookFlavor = ParseParamValueIfNotSpecified(Command, CookFlavor, "cookflavor", String.Empty);
            this.SkipCook = GetParamValueIfNotSpecified(Command, SkipCook, this.SkipCook, "skipcook");
            if (this.SkipCook)
            {
                this.Cook = true;
            }
            this.Clean = GetOptionalParamValueIfNotSpecified(Command, Clean, this.Clean, "clean", null);
            this.SignPak = ParseParamValueIfNotSpecified(Command, SignPak, "signpak", String.Empty);
            this.SignedPak = !String.IsNullOrEmpty(this.SignPak) || GetParamValueIfNotSpecified(Command, SignedPak, this.SignedPak, "signedpak");
            this.Pak = this.SignedPak || GetParamValueIfNotSpecified(Command, Pak, this.Pak, "pak");
            this.SkipPak = GetParamValueIfNotSpecified(Command, SkipPak, this.SkipPak, "skippak");
            if (this.SkipPak)
            {
                this.Pak = true;
            }
            this.NoXGE = GetParamValueIfNotSpecified(Command, NoXGE, this.NoXGE, "noxge");
            this.CookOnTheFly = GetParamValueIfNotSpecified(Command, CookOnTheFly, this.CookOnTheFly, "cookonthefly");
            this.Compressed = GetParamValueIfNotSpecified(Command, Compressed, this.Compressed, "compressed");
            this.UseDebugParamForEditorExe = GetParamValueIfNotSpecified(Command, UseDebugParamForEditorExe, this.UseDebugParamForEditorExe, "UseDebugParamForEditorExe");
            this.IterativeCooking = GetParamValueIfNotSpecified(Command, IterativeCooking, this.IterativeCooking, "iterativecooking", "iterate");
            this.SkipCookOnTheFly = GetParamValueIfNotSpecified(Command, SkipCookOnTheFly, this.SkipCookOnTheFly, "skipcookonthefly");
            this.FileServer = GetParamValueIfNotSpecified(Command, FileServer, this.FileServer, "fileserver");
            this.DedicatedServer = GetParamValueIfNotSpecified(Command, DedicatedServer, this.DedicatedServer, "dedicatedserver", "server");
            this.Client = GetParamValueIfNotSpecified(Command, Client, this.Client, "client");
            if( this.Client )
            {
                this.DedicatedServer = true;
            }
            this.NoClient = GetParamValueIfNotSpecified(Command, NoClient, this.NoClient, "noclient");
            this.LogWindow = GetParamValueIfNotSpecified(Command, LogWindow, this.LogWindow, "logwindow");
            this.Stage = GetParamValueIfNotSpecified(Command, Stage, this.Stage, "stage");
            this.SkipStage = GetParamValueIfNotSpecified(Command, SkipStage, this.SkipStage, "skipstage");
            if (this.SkipStage)
            {
                this.Stage = true;
            }
            this.StageDirectoryParam = ParseParamValueIfNotSpecified(Command, StageDirectoryParam, "stagingdirectory", String.Empty).Trim(new char[]{'\"'});
            this.Manifests = GetParamValueIfNotSpecified(Command, Manifests, this.Manifests, "manifests");
            this.Archive = GetParamValueIfNotSpecified(Command, Archive, this.Archive, "archive");
            this.ArchiveDirectoryParam = ParseParamValueIfNotSpecified(Command, ArchiveDirectoryParam, "archivedirectory", String.Empty);
            this.Distribution = GetParamValueIfNotSpecified(Command, Distribution, this.Distribution, "distribution");
            this.NoDebugInfo = GetParamValueIfNotSpecified(Command, NoDebugInfo, this.NoDebugInfo, "nodebuginfo");
            this.NoCleanStage = GetParamValueIfNotSpecified(Command, NoCleanStage, this.NoCleanStage, "nocleanstage");
            this.MapToRun = ParseParamValueIfNotSpecified(Command, MapToRun, "map", String.Empty);
            this.Foreign = GetParamValueIfNotSpecified(Command, Foreign, this.Foreign, "foreign");
            this.ForeignCode = GetParamValueIfNotSpecified(Command, ForeignCode, this.ForeignCode, "foreigncode");
            this.StageCommandline = ParseParamValueIfNotSpecified(Command, StageCommandline, "cmdline");
            this.BundleName = ParseParamValueIfNotSpecified(Command, BundleName, "bundlename");
            this.RunCommandline = ParseParamValueIfNotSpecified(Command, RunCommandline, "addcmdline");
            this.Package = GetParamValueIfNotSpecified(Command, Package, this.Package, "package");
            this.Deploy = GetParamValueIfNotSpecified(Command, Deploy, this.Deploy, "deploy");
            this.Device = ParseParamValueIfNotSpecified(Command, Device, "device", String.Empty).Trim(new char[]{'\"'});
            this.ServerDevice = ParseParamValueIfNotSpecified(Command, ServerDevice, "serverdevice", this.Device);
            this.Port = ParseParamValueIfNotSpecified(Command, Port, "port", String.Empty);
            this.NullRHI = GetParamValueIfNotSpecified(Command, NullRHI, this.NullRHI, "nullrhi");
            this.FakeClient = GetParamValueIfNotSpecified(Command, FakeClient, this.FakeClient, "fakeclient");
            this.EditorTest = GetParamValueIfNotSpecified(Command, EditorTest, this.EditorTest, "editortest");
            this.RunAutomationTest = ParseParamValueIfNotSpecified(Command, RunAutomationTest, "RunAutomationTest");
            this.RunAutomationTests = this.RunAutomationTest != "" || GetParamValueIfNotSpecified(Command, RunAutomationTests, this.RunAutomationTests, "RunAutomationTests");
            this.SkipServer = GetParamValueIfNotSpecified(Command, SkipServer, this.SkipServer, "skipserver");
            this.Rocket = GetParamValueIfNotSpecified(Command, Rocket, this.Rocket || GlobalCommandLine.Rocket, "rocket");
            this.UE4Exe = ParseParamValueIfNotSpecified(Command, UE4Exe, "ue4exe", "UE4Editor-Cmd.exe");
            this.Unattended = GetParamValueIfNotSpecified(Command, Unattended, this.Unattended, "unattended");
            this.DeviceUsername = ParseParamValueIfNotSpecified(Command, DeviceUsername, "deviceuser", String.Empty);
            this.DevicePassword = ParseParamValueIfNotSpecified(Command, DevicePassword, "devicepass", String.Empty);
            this.CrashReporter = GetParamValueIfNotSpecified(Command, CrashReporter, this.CrashReporter, "crashreporter");
            if (ClientConfigsToBuild == null)
            {
                if (Command != null)
                {
                    var ClientConfig = Command.ParseParamValue("clientconfig");
                    if (ClientConfig != null)
                    {
                        this.ClientConfigsToBuild = new List<UnrealTargetConfiguration>();
                        var Configs = new ParamList<string>(ClientConfig.Split('+'));
                        foreach (var ConfigName in Configs)
                        {
                            this.ClientConfigsToBuild.Add((UnrealTargetConfiguration)Enum.Parse(typeof(UnrealTargetConfiguration), ConfigName, true));
                        }
                    }
                }
            }
            else
            {
                this.ClientConfigsToBuild = ClientConfigsToBuild;
            }
            if (ServerConfigsToBuild == null)
            {
                if (Command != null)
                {
                    var ServerConfig = Command.ParseParamValue("serverconfig");
                    if (ServerConfig != null && ServerConfigsToBuild == null)
                    {
                        this.ServerConfigsToBuild = new List<UnrealTargetConfiguration>();
                        var Configs = new ParamList<string>(ServerConfig.Split('+'));
                        foreach (var ConfigName in Configs)
                        {
                            this.ServerConfigsToBuild.Add((UnrealTargetConfiguration)Enum.Parse(typeof(UnrealTargetConfiguration), ConfigName, true));
                        }
                    }
                }
            }
            else
            {
                this.ServerConfigsToBuild = ServerConfigsToBuild;
            }
            if (NumClients.HasValue)
            {
                this.NumClients = NumClients.Value;
            }
            else if (Command != null)
            {
                this.NumClients = Command.ParseParamInt("numclients");
            }
            if (CrashIndex.HasValue)
            {
                this.CrashIndex = CrashIndex.Value;
            }
            else if (Command != null)
            {
                this.CrashIndex = Command.ParseParamInt("CrashIndex");
            }

            AutodetectSettings(false);
            ValidateAndLog();
        }
Exemple #9
0
		public override void SetupOptionsForRun(ref string AppName, ref CommandUtils.ERunOptions Options, ref string CommandLine)
		{
			if (AppName == "sh" || AppName == "xbuild" || AppName == "codesign")
			{
				Options &= ~CommandUtils.ERunOptions.AppMustExist;
			}
			if (AppName == "xbuild")
			{
				AppName = "sh";
				CommandLine = "-c 'xbuild " + (String.IsNullOrEmpty(CommandLine) ? "" : CommandLine) + " /p:DefineConstants=MONO /verbosity:quiet /nologo |grep -i error; if [ $? -ne 1 ]; then exit 1; else exit 0; fi'";
			}
			if (AppName.EndsWith(".exe") || ((AppName.Contains("/Binaries/Win64/") || AppName.Contains("/Binaries/Mac/")) && string.IsNullOrEmpty(Path.GetExtension(AppName))))
			{
				if (AppName.Contains("/Binaries/Win64/") || AppName.Contains("/Binaries/Mac/"))
				{
					AppName = AppName.Replace("/Binaries/Win64/", "/Binaries/Mac/");
					AppName = AppName.Replace("-cmd.exe", "");
					AppName = AppName.Replace("-Cmd.exe", "");
					AppName = AppName.Replace(".exe", "");
					string AppFilename = Path.GetFileName(AppName);
					if (!CommandUtils.FileExists(AppName))
					{
						AppName = AppName + ".app/Contents/MacOS/" + AppFilename;
					}
				}
				else
				{
					// It's a C# app, so run it with Mono
					CommandLine = "\"" + AppName + "\" " + (String.IsNullOrEmpty(CommandLine) ? "" : CommandLine);
					AppName = "mono";
					Options &= ~CommandUtils.ERunOptions.AppMustExist;
				}
			}
		}
        public static int Main(string[] Arguments)
        {
            // Ensure UTF8Output flag is respected, since we are initializing logging early in the program.
            if (CommandUtils.ParseParam(Arguments, "-Utf8output"))
            {
                Console.OutputEncoding = new System.Text.UTF8Encoding(false, false);
            }

            // Parse the log level argument
            if (CommandUtils.ParseParam(Arguments, "-Verbose"))
            {
                Log.OutputLevel = LogEventType.Verbose;
            }
            if (CommandUtils.ParseParam(Arguments, "-VeryVerbose"))
            {
                Log.OutputLevel = LogEventType.VeryVerbose;
            }

            // Initialize the log system, buffering the output until we can create the log file
            StartupTraceListener StartupListener = new StartupTraceListener();

            Trace.Listeners.Add(StartupListener);

            // Configure log timestamps
            Log.IncludeTimestamps = CommandUtils.ParseParam(Arguments, "-Timestamps");

            // Enter the main program section
            ExitCode ReturnCode = ExitCode.Success;

            try
            {
                // Set the working directory to the UE4 root
                Environment.CurrentDirectory = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetOriginalLocation()), "..", "..", ".."));

                // Ensure we can resolve any external assemblies as necessary.
                string PathToBinariesDotNET = Path.GetDirectoryName(Assembly.GetEntryAssembly().GetOriginalLocation());
                AssemblyUtils.InstallAssemblyResolver(PathToBinariesDotNET);
                AssemblyUtils.InstallRecursiveAssemblyResolver(PathToBinariesDotNET);

                // Initialize the host platform layer
                HostPlatform.Initialize();

                // Log the operating environment. Since we usually compile to AnyCPU, we may be executed using different system paths under WOW64.
                Log.TraceVerbose("{2}: Running on {0} as a {1}-bit process.", HostPlatform.Current.GetType().Name, Environment.Is64BitProcess ? 64 : 32, DateTime.UtcNow.ToString("o"));

                // Log if we're running from the launcher
                string ExecutingAssemblyLocation = Assembly.GetExecutingAssembly().Location;
                if (string.Compare(ExecutingAssemblyLocation, Assembly.GetEntryAssembly().GetOriginalLocation(), StringComparison.OrdinalIgnoreCase) != 0)
                {
                    Log.TraceVerbose("Executed from AutomationToolLauncher ({0})", ExecutingAssemblyLocation);
                }
                Log.TraceVerbose("CWD={0}", Environment.CurrentDirectory);

                // Hook up exit callbacks
                AppDomain Domain = AppDomain.CurrentDomain;
                Domain.ProcessExit  += Domain_ProcessExit;
                Domain.DomainUnload += Domain_ProcessExit;
                HostPlatform.Current.SetConsoleCtrlHandler(CtrlHandlerDelegateInstance);

                // Log the application version
                FileVersionInfo Version = AssemblyUtils.ExecutableVersion;
                Log.TraceVerbose("{0} ver. {1}", Version.ProductName, Version.ProductVersion);

                // Don't allow simultaneous execution of AT (in the same branch)
                ReturnCode = InternalUtils.RunSingleInstance(() => MainProc(Arguments, StartupListener));
            }
            catch (AutomationException Ex)
            {
                // Output the message in the desired format
                if (Ex.OutputFormat == AutomationExceptionOutputFormat.Silent)
                {
                    Log.TraceLog("{0}", ExceptionUtils.FormatExceptionDetails(Ex));
                }
                else if (Ex.OutputFormat == AutomationExceptionOutputFormat.Minimal)
                {
                    Log.TraceInformation("{0}", Ex.ToString().Replace("\n", "\n  "));
                    Log.TraceLog("{0}", ExceptionUtils.FormatExceptionDetails(Ex));
                }
                else
                {
                    Log.WriteException(Ex, LogUtils.FinalLogFileName);
                }

                // Take the exit code from the exception
                ReturnCode = Ex.ErrorCode;
            }
            catch (Exception Ex)
            {
                // Use a default exit code
                Log.WriteException(Ex, LogUtils.FinalLogFileName);
                ReturnCode = ExitCode.Error_Unknown;
            }
            finally
            {
                // In all cases, do necessary shut down stuff, but don't let any additional exceptions leak out while trying to shut down.

                // Make sure there's no directories on the stack.
                NoThrow(() => CommandUtils.ClearDirStack(), "Clear Dir Stack");

                // Try to kill process before app domain exits to leave the other KillAll call to extreme edge cases
                NoThrow(() => { if (ShouldKillProcesses && !Utils.IsRunningOnMono)
                                {
                                    ProcessManager.KillAll();
                                }
                        }, "Kill All Processes");

                // Write the exit code
                Log.TraceInformation("AutomationTool exiting with ExitCode={0} ({1})", (int)ReturnCode, ReturnCode);

                // Can't use NoThrow here because the code logs exceptions. We're shutting down logging!
                Trace.Close();
            }
            return((int)ReturnCode);
        }
        /// <summary>
        /// Print the contents of the graph
        /// </summary>
        /// <param name="NodeToState">Mapping of node to its current state</param>
        /// <param name="Options">Options for how to print the graph</param>
        public void Print(HashSet <Node> CompletedNodes, GraphPrintOptions Options)
        {
            // Get a list of all the triggers, including the null global one
            List <ManualTrigger> AllTriggers = new List <ManualTrigger>();

            AllTriggers.Add(null);
            AllTriggers.AddRange(NameToTrigger.Values.OrderBy(x => x.QualifiedName));

            // Output all the triggers in order
            CommandUtils.Log("");
            CommandUtils.Log("Graph:");
            foreach (ManualTrigger Trigger in AllTriggers)
            {
                // Filter everything by this trigger
                Dictionary <AgentGroup, Node[]> FilteredGroupToNodes = new Dictionary <AgentGroup, Node[]>();
                foreach (AgentGroup Group in Groups)
                {
                    Node[] Nodes = Group.Nodes.Where(x => x.ControllingTrigger == Trigger).ToArray();
                    if (Nodes.Length > 0)
                    {
                        FilteredGroupToNodes[Group] = Nodes;
                    }
                }

                // Skip this trigger if there's nothing to display
                if (FilteredGroupToNodes.Count == 0)
                {
                    continue;
                }

                // Print the trigger name
                CommandUtils.Log("    Trigger: {0}", (Trigger == null)? "None" : Trigger.QualifiedName);
                if (Trigger != null && Options.HasFlag(GraphPrintOptions.ShowNotifications))
                {
                    foreach (string User in Trigger.NotifyUsers)
                    {
                        CommandUtils.Log("            notify> {0}", User);
                    }
                }

                // Output all the groups for this trigger
                foreach (AgentGroup Group in Groups)
                {
                    Node[] Nodes;
                    if (FilteredGroupToNodes.TryGetValue(Group, out Nodes))
                    {
                        CommandUtils.Log("        Group: {0} ({1})", Group.Name, String.Join(";", Group.PossibleTypes));
                        foreach (Node Node in Nodes)
                        {
                            CommandUtils.Log("            Node: {0}{1}", Node.Name, CompletedNodes.Contains(Node)? " (completed)" : "");
                            if (Options.HasFlag(GraphPrintOptions.ShowDependencies))
                            {
                                HashSet <Node> InputDependencies = new HashSet <Node>(Node.GetDirectInputDependencies());
                                foreach (Node InputDependency in InputDependencies)
                                {
                                    CommandUtils.Log("                input> {0}", InputDependency.Name);
                                }
                                HashSet <Node> OrderDependencies = new HashSet <Node>(Node.GetDirectOrderDependencies());
                                foreach (Node OrderDependency in OrderDependencies.Except(InputDependencies))
                                {
                                    CommandUtils.Log("                after> {0}", OrderDependency.Name);
                                }
                            }
                            if (Options.HasFlag(GraphPrintOptions.ShowNotifications))
                            {
                                string Label = Node.bNotifyOnWarnings? "warnings" : "errors";
                                foreach (string User in Node.NotifyUsers)
                                {
                                    CommandUtils.Log("                {0}> {1}", Label, User);
                                }
                                foreach (string Submitter in Node.NotifySubmitters)
                                {
                                    CommandUtils.Log("                {0}> submitters to {1}", Label, Submitter);
                                }
                            }
                        }
                    }
                }
            }
            CommandUtils.Log("");

            // Print out all the aggregates
            string[] AggregateNames = AggregateNameToNodes.Keys.OrderBy(x => x).ToArray();
            if (AggregateNames.Length > 0)
            {
                CommandUtils.Log("Aggregates:");
                foreach (string AggregateName in AggregateNames)
                {
                    CommandUtils.Log("    {0}", AggregateName);
                }
                CommandUtils.Log("");
            }
        }
Exemple #12
0
        /// <summary>
        /// Entry point for the commandlet
        /// </summary>
        public override void ExecuteBuild()
        {
            string OutputDir = ParseParamValue("OutputDir");
            string ContentOnlyPlatformsString = ParseParamValue("ContentOnlyPlatforms");
            IEnumerable <UnrealTargetPlatform> ContentOnlyPlatforms = Enumerable.Empty <UnrealTargetPlatform>();

            if (!String.IsNullOrWhiteSpace(ContentOnlyPlatformsString))
            {
                ContentOnlyPlatforms = ContentOnlyPlatformsString.Split(';').Where(x => !String.IsNullOrWhiteSpace(x)).Select(x => (UnrealTargetPlatform)Enum.Parse(typeof(UnrealTargetPlatform), x));
            }
            string AnalyticsTypeOverride = ParseParamValue("AnalyticsTypeOverride");

            // Write InstalledBuild.txt to indicate Engine is installed
            string InstalledBuildFile = CommandUtils.CombinePaths(OutputDir, "Engine/Build/InstalledBuild.txt");

            CommandUtils.CreateDirectory(CommandUtils.GetDirectoryName(InstalledBuildFile));
            CommandUtils.WriteAllText(InstalledBuildFile, "");

            string         OutputEnginePath     = Path.Combine(OutputDir, "Engine");
            string         OutputBaseEnginePath = Path.Combine(OutputEnginePath, "Config", "BaseEngine.ini");
            FileAttributes OutputAttributes     = FileAttributes.ReadOnly;
            List <String>  IniLines             = new List <String>();

            // Should always exist but if not, we don't need extra line
            if (File.Exists(OutputBaseEnginePath))
            {
                OutputAttributes = File.GetAttributes(OutputBaseEnginePath);
                IniLines.Add("");
            }
            else
            {
                CommandUtils.CreateDirectory(CommandUtils.GetDirectoryName(OutputBaseEnginePath));
                CommandUtils.WriteAllText(OutputBaseEnginePath, "");
                OutputAttributes = File.GetAttributes(OutputBaseEnginePath) | OutputAttributes;
            }

            // Create list of platform configurations installed in a Rocket build
            List <InstalledPlatformInfo.InstalledPlatformConfiguration> InstalledConfigs = new List <InstalledPlatformInfo.InstalledPlatformConfiguration>();

            foreach (UnrealTargetPlatform CodeTargetPlatform in Enum.GetValues(typeof(UnrealTargetPlatform)))
            {
                UEBuildPlatform BuildPlatform = UEBuildPlatform.GetBuildPlatform(CodeTargetPlatform, true);
                if (BuildPlatform != null)
                {
                    string Architecture = BuildPlatform.CreateContext(null).GetActiveArchitecture();

                    // Try to parse additional Architectures from the command line
                    string Architectures    = ParseParamValue(CodeTargetPlatform.ToString() + "Architectures");
                    string GPUArchitectures = ParseParamValue(CodeTargetPlatform.ToString() + "GPUArchitectures");

                    // Build a list of pre-compiled architecture combinations for this platform if any
                    List <string> AllArchNames;

                    if (!String.IsNullOrWhiteSpace(Architectures) && !String.IsNullOrWhiteSpace(GPUArchitectures))
                    {
                        AllArchNames = (from Arch in Architectures.Split('+')
                                        from GPUArch in GPUArchitectures.Split('+')
                                        select "-" + Arch + "-" + GPUArch).ToList();
                    }
                    else if (!String.IsNullOrWhiteSpace(Architectures))
                    {
                        AllArchNames = Architectures.Split('+').ToList();
                    }
                    else
                    {
                        AllArchNames = new List <string>();
                    }

                    // Check whether this platform should only be used for content based projects
                    EProjectType ProjectType = ContentOnlyPlatforms.Contains(CodeTargetPlatform) ? EProjectType.Content : EProjectType.Any;

                    // Allow Content only platforms to be shown as options in all projects
                    bool bCanBeDisplayed = ProjectType == EProjectType.Content;
                    foreach (UnrealTargetConfiguration CodeTargetConfiguration in Enum.GetValues(typeof(UnrealTargetConfiguration)))
                    {
                        // Need to check for development receipt as we use that for the Engine code in DebugGame
                        UnrealTargetConfiguration EngineConfiguration = (CodeTargetConfiguration == UnrealTargetConfiguration.DebugGame) ? UnrealTargetConfiguration.Development : CodeTargetConfiguration;
                        string ReceiptFileName = TargetReceipt.GetDefaultPath(OutputEnginePath, "UE4Game", CodeTargetPlatform, EngineConfiguration, Architecture);

                        if (File.Exists(ReceiptFileName))
                        {
                            // Strip the output folder so that this can be used on any machine
                            ReceiptFileName = new FileReference(ReceiptFileName).MakeRelativeTo(new DirectoryReference(OutputDir));

                            // If we have pre-compiled architectures for this platform then add an entry for each of these -
                            // there isn't a receipt for each architecture like some other platforms
                            if (AllArchNames.Count > 0)
                            {
                                foreach (string Arch in AllArchNames)
                                {
                                    InstalledConfigs.Add(new InstalledPlatformInfo.InstalledPlatformConfiguration(CodeTargetConfiguration, CodeTargetPlatform, TargetRules.TargetType.Game, Arch, ReceiptFileName, ProjectType, bCanBeDisplayed));
                                }
                            }
                            else
                            {
                                InstalledConfigs.Add(new InstalledPlatformInfo.InstalledPlatformConfiguration(CodeTargetConfiguration, CodeTargetPlatform, TargetRules.TargetType.Game, Architecture, ReceiptFileName, ProjectType, bCanBeDisplayed));
                            }
                        }
                    }
                }
            }

            UnrealBuildTool.InstalledPlatformInfo.WriteConfigFileEntries(InstalledConfigs, ref IniLines);

            if (!String.IsNullOrEmpty(AnalyticsTypeOverride))
            {
                // Write Custom Analytics type setting
                IniLines.Add("");
                IniLines.Add("[Analytics]");
                IniLines.Add(String.Format("UE4TypeOverride=\"{0}\"", AnalyticsTypeOverride));
            }

            // Make sure we can write to the the config file
            File.SetAttributes(OutputBaseEnginePath, OutputAttributes & ~FileAttributes.ReadOnly);
            File.AppendAllLines(OutputBaseEnginePath, IniLines);
            File.SetAttributes(OutputBaseEnginePath, OutputAttributes);
        }
Exemple #13
0
        public override void ExecuteBuild()
        {
            // Parse the target list
            string[] Targets = ParseParamValues("Target");
            if (Targets.Length == 0)
            {
                throw new AutomationException("No targets specified (eg. -Target=\"UE4Editor Win64 Development\")");
            }

            // Parse the archive path
            string ArchivePath = ParseParamValue("Archive");

            if (ArchivePath != null && (!ArchivePath.StartsWith("//") || ArchivePath.Sum(x => (x == '/')? 1 : 0) < 4))
            {
                throw new AutomationException("Archive path is not a valid depot filename");
            }

            // Prepare the build agenda
            UE4Build.BuildAgenda Agenda = new UE4Build.BuildAgenda();
            foreach (string Target in Targets)
            {
                string[] Tokens = Target.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

                UnrealTargetPlatform      Platform;
                UnrealTargetConfiguration Configuration;
                if (Tokens.Length < 3 || !Enum.TryParse(Tokens[1], true, out Platform) || !Enum.TryParse(Tokens[2], true, out Configuration))
                {
                    throw new AutomationException("Invalid target '{0}' - expected <TargetName> <Platform> <Configuration>");
                }

                Agenda.AddTarget(Tokens[0], Platform, Configuration, InAddArgs: String.Join(" ", Tokens.Skip(3)));
            }

            // Build everything
            UE4Build Builder = new UE4Build(this);

            Builder.Build(Agenda, InUpdateVersionFiles: ArchivePath != null);

            // Include the build products for UAT and UBT if required
            if (ParseParam("WithUAT"))
            {
                Builder.AddUATFilesToBuildProducts();
            }
            if (ParseParam("WithUBT"))
            {
                Builder.AddUBTFilesToBuildProducts();
            }

            // Archive the build products
            if (ArchivePath != null)
            {
                // Create an output folder
                string OutputFolder = Path.Combine(CommandUtils.CmdEnv.LocalRoot, "ArchiveForUGS");
                Directory.CreateDirectory(OutputFolder);

                // Create a temp folder for storing stripped PDB files
                string SymbolsFolder = Path.Combine(OutputFolder, "Symbols");
                Directory.CreateDirectory(SymbolsFolder);

                // Get the Windows toolchain
                Platform WindowsTargetPlatform = Platform.GetPlatform(UnrealTargetPlatform.Win64);

                // Figure out all the files for the archive
                string ZipFileName = Path.Combine(OutputFolder, "Archive.zip");
                using (Ionic.Zip.ZipFile Zip = new Ionic.Zip.ZipFile())
                {
                    Zip.UseZip64WhenSaving = Ionic.Zip.Zip64Option.Always;
                    foreach (string BuildProduct in Builder.BuildProductFiles)
                    {
                        if (!File.Exists(BuildProduct))
                        {
                            throw new AutomationException("Missing build product: {0}", BuildProduct);
                        }
                        if (BuildProduct.EndsWith(".pdb", StringComparison.InvariantCultureIgnoreCase))
                        {
                            string StrippedFileName = CommandUtils.MakeRerootedFilePath(BuildProduct, CommandUtils.CmdEnv.LocalRoot, SymbolsFolder);
                            Directory.CreateDirectory(Path.GetDirectoryName(StrippedFileName));
                            WindowsTargetPlatform.StripSymbols(new FileReference(BuildProduct), new FileReference(StrippedFileName));
                            Zip.AddFile(StrippedFileName, Path.GetDirectoryName(CommandUtils.StripBaseDirectory(StrippedFileName, SymbolsFolder)));
                        }
                        else
                        {
                            Zip.AddFile(BuildProduct, Path.GetDirectoryName(CommandUtils.StripBaseDirectory(BuildProduct, CommandUtils.CmdEnv.LocalRoot)));
                        }
                    }
                    // Create the zip file
                    Console.WriteLine("Writing {0}...", ZipFileName);
                    Zip.Save(ZipFileName);
                }

                // Submit it to Perforce if required
                if (CommandUtils.AllowSubmit)
                {
                    // Delete any existing clientspec for submitting
                    string ClientName = Environment.MachineName + "_BuildForUGS";

                    // Create a brand new one
                    P4ClientInfo Client = new P4ClientInfo();
                    Client.Owner    = CommandUtils.P4Env.User;
                    Client.Host     = Environment.MachineName;
                    Client.Stream   = ArchivePath.Substring(0, ArchivePath.IndexOf('/', ArchivePath.IndexOf('/', 2) + 1));
                    Client.RootPath = Path.Combine(OutputFolder, "Perforce");
                    Client.Name     = ClientName;
                    Client.Options  = P4ClientOption.NoAllWrite | P4ClientOption.NoClobber | P4ClientOption.NoCompress | P4ClientOption.Unlocked | P4ClientOption.NoModTime | P4ClientOption.RmDir;
                    Client.LineEnd  = P4LineEnd.Local;
                    P4.CreateClient(Client, AllowSpew: false);

                    // Create a new P4 connection for this workspace
                    P4Connection SubmitP4 = new P4Connection(Client.Owner, Client.Name, P4Env.P4Port);
                    SubmitP4.Revert("-k //...");

                    // Figure out where the zip file has to go in Perforce
                    P4WhereRecord WhereZipFile = SubmitP4.Where(ArchivePath, false).FirstOrDefault(x => !x.bUnmap && x.Path != null);
                    if (WhereZipFile == null)
                    {
                        throw new AutomationException("Couldn't locate {0} in this workspace");
                    }

                    // Get the latest version of it
                    int NewCL = SubmitP4.CreateChange(Description: String.Format("[CL {0}] Updated binaries", P4Env.Changelist));
                    SubmitP4.Sync(String.Format("-k \"{0}\"", ArchivePath), AllowSpew: false);
                    CommandUtils.CopyFile(ZipFileName, WhereZipFile.Path);
                    SubmitP4.Add(NewCL, String.Format("\"{0}\"", ArchivePath));
                    SubmitP4.Edit(NewCL, String.Format("\"{0}\"", ArchivePath));

                    // Submit it
                    int SubmittedCL;
                    SubmitP4.Submit(NewCL, out SubmittedCL);
                    if (SubmittedCL <= 0)
                    {
                        throw new AutomationException("Submit failed.");
                    }
                    Console.WriteLine("Submitted in changelist {0}", SubmittedCL);
                }
            }
        }
Exemple #14
0
        public override void ExecuteBuild()
        {
            string RootDirParam = ParseParamValue("RootDir", null);

            if (RootDirParam == null)
            {
                throw new AutomationException("Missing -BaseDir=... parameter");
            }

            string CreatedBy    = ParseParamValue("CreatedBy", null);
            string CreatedByUrl = ParseParamValue("CreatedByUrl", null);
            bool   bForce       = ParseParam("Force");

            foreach (FileReference PluginFile in DirectoryReference.EnumerateFiles(new DirectoryReference(RootDirParam), "*.uplugin", System.IO.SearchOption.AllDirectories))
            {
                LogInformation("Reading {0}", PluginFile);
                string InputText = File.ReadAllText(PluginFile.FullName);

                // Parse the descriptor
                PluginDescriptor Descriptor;
                try
                {
                    Descriptor = new PluginDescriptor(JsonObject.Parse(InputText));
                }
                catch (JsonParseException Ex)
                {
                    LogError("Unable to parse {0}: {1}", PluginFile, Ex.ToString());
                    continue;
                }

                // Update the fields
                if (CreatedBy != null && Descriptor.CreatedBy != CreatedBy)
                {
                    LogInformation("  Updating 'CreatedBy' field from '{0}' to '{1}'", Descriptor.CreatedBy ?? "<empty>", CreatedBy);
                    Descriptor.CreatedBy = CreatedBy;
                }
                if (CreatedByUrl != null)
                {
                    LogInformation("  Updating 'CreatedByURL' field from '{0}' to '{1}'", Descriptor.CreatedByURL ?? "<empty>", CreatedByUrl);
                    Descriptor.CreatedByURL = CreatedByUrl;
                }

                // Format the output text
                StringBuilder Output = new StringBuilder();
                using (JsonWriter Writer = new JsonWriter(new StringWriter(Output)))
                {
                    Writer.WriteObjectStart();
                    Descriptor.Write(Writer);
                    Writer.WriteObjectEnd();
                }

                // Compare the output and input; write it if it differs
                string OutputText = Output.ToString();
                if (InputText != OutputText)
                {
                    if (CommandUtils.IsReadOnly(PluginFile.FullName))
                    {
                        if (!bForce)
                        {
                            LogWarning("File is read only; skipping write.");
                            continue;
                        }
                        CommandUtils.SetFileAttributes(PluginFile.FullName, ReadOnly: false);
                    }
                    LogInformation("  Writing updated file.", PluginFile);
                    FileReference.WriteAllText(PluginFile, OutputText);
                }
            }
        }
        /// <summary>
        /// Kills all running processes.
        /// </summary>
        public static void KillAll()
        {
            List <IProcess> ProcessesToKill = new List <IProcess>();

            lock (SyncObject)
            {
                foreach (var ProcResult in ActiveProcesses)
                {
                    if (!ProcResult.HasExited)
                    {
                        ProcessesToKill.Add(ProcResult);
                    }
                }
                ActiveProcesses.Clear();
            }
            // Remove processes that can't be killed
            for (int ProcessIndex = ProcessesToKill.Count - 1; ProcessIndex >= 0; --ProcessIndex)
            {
                var ProcessName = ProcessesToKill[ProcessIndex].GetProcessName();
                if (!String.IsNullOrEmpty(ProcessName) && !CanBeKilled(ProcessName))
                {
                    CommandUtils.LogLog("Ignoring process \"{0}\" because it can't be killed.", ProcessName);
                    ProcessesToKill.RemoveAt(ProcessIndex);
                }
            }
            if (ProcessesToKill.Count > 0)
            {
                CommandUtils.LogLog("Trying to kill {0} spawned processes.", ProcessesToKill.Count);
                foreach (var Proc in ProcessesToKill)
                {
                    CommandUtils.LogLog("  {0}", Proc.GetProcessName());
                }
                if (CommandUtils.IsBuildMachine)
                {
                    for (int Cnt = 0; Cnt < 9; Cnt++)
                    {
                        bool AllDone = true;
                        foreach (var Proc in ProcessesToKill)
                        {
                            try
                            {
                                if (!Proc.HasExited)
                                {
                                    AllDone = false;
                                    CommandUtils.LogLog("Waiting for process: {0}", Proc.GetProcessName());
                                }
                            }
                            catch (Exception)
                            {
                                CommandUtils.LogWarning("Exception Waiting for process");
                                AllDone = false;
                            }
                        }
                        try
                        {
                            if (ProcessResult.HasAnyDescendants(Process.GetCurrentProcess()))
                            {
                                AllDone = false;
                                CommandUtils.LogInformation("Waiting for descendants of main process...");
                            }
                        }
                        catch (Exception Ex)
                        {
                            CommandUtils.LogWarning("Exception Waiting for descendants of main process. " + Ex);
                            AllDone = false;
                        }

                        if (AllDone)
                        {
                            break;
                        }
                        Thread.Sleep(10000);
                    }
                }
                foreach (var Proc in ProcessesToKill)
                {
                    var ProcName = Proc.GetProcessName();
                    try
                    {
                        if (!Proc.HasExited)
                        {
                            CommandUtils.LogLog("Killing process: {0}", ProcName);
                            Proc.StopProcess(false);
                        }
                    }
                    catch (Exception Ex)
                    {
                        CommandUtils.LogWarning("Exception while trying to kill process {0}:", ProcName);
                        CommandUtils.LogWarning(LogUtils.FormatException(Ex));
                    }
                }
                try
                {
                    if (CommandUtils.IsBuildMachine && ProcessResult.HasAnyDescendants(Process.GetCurrentProcess()))
                    {
                        CommandUtils.LogLog("current process still has descendants, trying to kill them...");
                        ProcessResult.KillAllDescendants(Process.GetCurrentProcess());
                    }
                }
                catch (Exception)
                {
                    CommandUtils.LogWarning("Exception killing descendants of main process");
                }
            }
        }
        /// <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)
            {
                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
                            {
                                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>
 /// Sets any additional options for running an executable.
 /// </summary>
 /// <param name="AppName"></param>
 /// <param name="Options"></param>
 /// <param name="CommandLine"></param>
 public abstract void SetupOptionsForRun(ref string AppName, ref CommandUtils.ERunOptions Options, ref string CommandLine);
        protected virtual void InitEnvironment(P4Connection Connection, CommandEnvironment CmdEnv)
        {
            //
            // P4 Environment
            //

            P4Port     = CommandUtils.GetEnvVar(EnvVarNames.P4Port);
            ClientRoot = CommandUtils.GetEnvVar(EnvVarNames.ClientRoot);
            User       = CommandUtils.GetEnvVar(EnvVarNames.User);
            ChangelistStringInternal = CommandUtils.GetEnvVar(EnvVarNames.Changelist, null);
            Client      = CommandUtils.GetEnvVar(EnvVarNames.Client);
            BuildRootP4 = CommandUtils.GetEnvVar(EnvVarNames.BuildRootP4);
            if (BuildRootP4.EndsWith("/", StringComparison.InvariantCultureIgnoreCase) || BuildRootP4.EndsWith("\\", StringComparison.InvariantCultureIgnoreCase))
            {
                // We expect the build root to not end with a path separator
                BuildRootP4 = BuildRootP4.Substring(0, BuildRootP4.Length - 1);
                CommandUtils.SetEnvVar(EnvVarNames.BuildRootP4, BuildRootP4);
            }
            BuildRootEscaped = CommandUtils.GetEnvVar(EnvVarNames.BuildRootEscaped);
            LabelToSync      = CommandUtils.GetEnvVar(EnvVarNames.LabelToSync);

            if (((CommandUtils.P4Enabled || CommandUtils.IsBuildMachine) && (ClientRoot == String.Empty || User == String.Empty ||
                                                                             (String.IsNullOrEmpty(ChangelistStringInternal) && CommandUtils.IsBuildMachine) || Client == String.Empty || BuildRootP4 == String.Empty)))
            {
                Log.TraceInformation("P4Enabled={0}", CommandUtils.P4Enabled);
                Log.TraceInformation("ClientRoot={0}", ClientRoot);
                Log.TraceInformation("User={0}", User);
                Log.TraceInformation("ChangelistString={0}", ChangelistStringInternal);
                Log.TraceInformation("Client={0}", Client);
                Log.TraceInformation("BuildRootP4={0}", BuildRootP4);

                throw new AutomationException("BUILD FAILED Perforce Environment is not set up correctly. Please check your environment variables.");
            }

            LabelPrefix = BuildRootP4 + "/";

            if (CommandUtils.P4Enabled)
            {
                if (CommandUtils.IsBuildMachine || ChangelistStringInternal != null)
                {
                    // We may not always need the changelist number if we're not a build machine.
                    // In local runs, changelist initialization can be really slow!
                    VerifyChangelistStringAndSetChangelistNumber();
                }

                // Setup branch name
                string DepotSuffix = "//depot/";
                if (BuildRootP4.StartsWith(DepotSuffix))
                {
                    BranchName = BuildRootP4.Substring(DepotSuffix.Length);
                }
                else
                {
                    throw new AutomationException("Needs update to work with a stream");
                }

                if (String.IsNullOrWhiteSpace(BranchName))
                {
                    throw new AutomationException("BUILD FAILED no branch name.");
                }
            }

            LogSettings();
        }
Exemple #19
0
		/// <summary>
		/// Constructor. Be sure to use this.ParamName to set the actual property name as parameter names and property names
		/// overlap here.
		/// If a parameter value is not set, it will be parsed from the command line if the command is null, the default value will be used.
		/// </summary>
		public ProjectParams(			
			string RawProjectPath,

			CommandUtils Command = null,
			string Device = null,			
			string MapToRun = null,	
			string AdditionalServerMapParams = null,
			ParamList<string> Port = null,
			string RunCommandline = null,						
			string StageCommandline = null,
            string BundleName = null,
            string StageDirectoryParam = null,
            bool? StageNonMonolithic = null,
			string UE4Exe = null,
			string SignPak = null,
			List<UnrealTargetConfiguration> ClientConfigsToBuild = null,
			List<UnrealTargetConfiguration> ServerConfigsToBuild = null,
			ParamList<string> MapsToCook = null,
			ParamList<string> DirectoriesToCook = null,
            string InternationalizationPreset = null,
            ParamList<string> CulturesToCook = null,
			ParamList<string> ClientCookedTargets = null,
			ParamList<string> EditorTargets = null,
			ParamList<string> ServerCookedTargets = null,
			List<UnrealTargetPlatform> ClientTargetPlatforms = null,
            Dictionary<UnrealTargetPlatform, UnrealTargetPlatform> ClientDependentPlatformMap = null,
			List<UnrealTargetPlatform> ServerTargetPlatforms = null,
            Dictionary<UnrealTargetPlatform, UnrealTargetPlatform> ServerDependentPlatformMap = null,
			bool? Build = null,
			bool? Cook = null,
			string CookFlavor = null,
			bool? Run = null,
			bool? SkipServer = null,
			bool? Clean = null,
            bool? Compressed = null,
            bool? UseDebugParamForEditorExe = null,
            bool? IterativeCooking = null,
            bool? CookAll = null,
            bool? CookMapsOnly = null,
            bool? CookOnTheFly = null,
            bool? CookOnTheFlyStreaming = null,
            bool? UnversionedCookedContent = null,
            string AdditionalCookerOptions = null,
            string BasedOnReleaseVersion = null,
            string CreateReleaseVersion = null,
            bool? GeneratePatch = null,
            string DLCName = null,
            bool? DLCIncludeEngineContent = null,
            bool? NewCook = null,
            bool? OldCook = null,
			bool? CrashReporter = null,
			bool? DedicatedServer = null,
			bool? Client = null,
			bool? Deploy = null,
			bool? FileServer = null,
			bool? Foreign = null,
			bool? ForeignCode = null,
			bool? LogWindow = null,
			bool? NoCleanStage = null,
			bool? NoClient = null,
			bool? NoDebugInfo = null,
			bool? NoXGE = null,
			bool? Package = null,
			bool? Pak = null,
			bool? Prereqs = null,
			bool? NoBootstrapExe = null,
            bool? SignedPak = null,
            bool? NullRHI = null,
            bool? FakeClient = null,
            bool? EditorTest = null,
            bool? RunAutomationTests = null,
            string RunAutomationTest = null,
            int? CrashIndex = null,
            bool? Rocket = null,
			bool? SkipCook = null,
			bool? SkipCookOnTheFly = null,
			bool? SkipPak = null,
			bool? SkipStage = null,
			bool? Stage = null,
			bool? Manifests = null,
            bool? CreateChunkInstall = null,
			bool? Unattended = null,
			int? NumClients = null,
			bool? Archive = null,
			string ArchiveDirectoryParam = null,
			bool? ArchiveMetaData = null,
			ParamList<string> ProgramTargets = null,
			bool? Distribution = null,
            bool? Prebuilt = null,
            int? RunTimeoutSeconds = null,
			string SpecifiedArchitecture = null,
            bool? IterativeDeploy = null,
			bool? FastCook = null,
			bool? IgnoreCookErrors = null
			)
		{
			//
			//// Use this.Name with properties and fields!
			//

			this.RawProjectPath = RawProjectPath;
			if (DirectoriesToCook != null)
			{
				this.DirectoriesToCook = DirectoriesToCook;
			}
            this.InternationalizationPreset = ParseParamValueIfNotSpecified(Command, InternationalizationPreset, "i18npreset");
            if (CulturesToCook != null)
			{
                this.CulturesToCook = CulturesToCook;
			}
			if (ClientCookedTargets != null)
			{
				this.ClientCookedTargets = ClientCookedTargets;
			}
			if (ServerCookedTargets != null)
			{
				this.ServerCookedTargets = ServerCookedTargets;
			}
			if (EditorTargets != null)
			{
				this.EditorTargets = EditorTargets;
			}
			if (ProgramTargets != null)
			{
				this.ProgramTargets = ProgramTargets;
			}

			// Parse command line params for client platforms "-TargetPlatform=Win64+Mac", "-Platform=Win64+Mac" and also "-Win64", "-Mac" etc.
            if (ClientDependentPlatformMap != null)
            {
                this.ClientDependentPlatformMap = ClientDependentPlatformMap;
            }

			this.ClientTargetPlatforms = SetupTargetPlatforms(ref this.ClientDependentPlatformMap, Command, ClientTargetPlatforms, new ParamList<UnrealTargetPlatform>() { HostPlatform.Current.HostEditorPlatform }, true, "TargetPlatform", "Platform");

            // Parse command line params for server platforms "-ServerTargetPlatform=Win64+Mac", "-ServerPlatform=Win64+Mac". "-Win64" etc is not allowed here
            if (ServerDependentPlatformMap != null)
            {
                this.ServerDependentPlatformMap = ServerDependentPlatformMap;
            }
            this.ServerTargetPlatforms = SetupTargetPlatforms(ref this.ServerDependentPlatformMap, Command, ServerTargetPlatforms, this.ClientTargetPlatforms, false, "ServerTargetPlatform", "ServerPlatform");

			this.Build = GetParamValueIfNotSpecified(Command, Build, this.Build, "build");
			this.Run = GetParamValueIfNotSpecified(Command, Run, this.Run, "run");
			this.Cook = GetParamValueIfNotSpecified(Command, Cook, this.Cook, "cook");
			this.CookFlavor = ParseParamValueIfNotSpecified(Command, CookFlavor, "cookflavor", String.Empty);
            this.NewCook = GetParamValueIfNotSpecified(Command, NewCook, this.NewCook, "NewCook");
            this.OldCook = GetParamValueIfNotSpecified(Command, OldCook, this.OldCook, "OldCook");
            this.CreateReleaseVersion = ParseParamValueIfNotSpecified(Command, CreateReleaseVersion, "createreleaseversion", String.Empty);
            this.BasedOnReleaseVersion = ParseParamValueIfNotSpecified(Command, BasedOnReleaseVersion, "basedonreleaseversion", String.Empty);
            this.GeneratePatch = GetParamValueIfNotSpecified(Command, GeneratePatch, this.GeneratePatch, "GeneratePatch");
            this.AdditionalCookerOptions = ParseParamValueIfNotSpecified(Command, AdditionalCookerOptions, "AdditionalCookerOptions", String.Empty);
            this.DLCName = ParseParamValueIfNotSpecified(Command, DLCName, "DLCName", String.Empty);
            this.DLCIncludeEngineContent = GetParamValueIfNotSpecified(Command, DLCIncludeEngineContent, this.DLCIncludeEngineContent, "DLCIncludeEngineContent");
			this.SkipCook = GetParamValueIfNotSpecified(Command, SkipCook, this.SkipCook, "skipcook");
			if (this.SkipCook)
			{
				this.Cook = true;
			}
			this.Clean = GetOptionalParamValueIfNotSpecified(Command, Clean, this.Clean, "clean", null);
			this.SignPak = ParseParamValueIfNotSpecified(Command, SignPak, "signpak", String.Empty);
			this.SignedPak = !String.IsNullOrEmpty(this.SignPak) || GetParamValueIfNotSpecified(Command, SignedPak, this.SignedPak, "signedpak");
			this.Pak = this.SignedPak || GetParamValueIfNotSpecified(Command, Pak, this.Pak, "pak");
			this.SkipPak = GetParamValueIfNotSpecified(Command, SkipPak, this.SkipPak, "skippak");
			if (this.SkipPak)
			{
				this.Pak = true;
			}
			this.NoXGE = GetParamValueIfNotSpecified(Command, NoXGE, this.NoXGE, "noxge");
			this.CookOnTheFly = GetParamValueIfNotSpecified(Command, CookOnTheFly, this.CookOnTheFly, "cookonthefly");
            if (this.CookOnTheFly && this.SkipCook)
            {
                this.Cook = false;
            }
            this.CookOnTheFlyStreaming = GetParamValueIfNotSpecified(Command, CookOnTheFlyStreaming, this.CookOnTheFlyStreaming, "cookontheflystreaming");
            this.UnversionedCookedContent = GetParamValueIfNotSpecified(Command, UnversionedCookedContent, this.UnversionedCookedContent, "UnversionedCookedContent");
            this.Compressed = GetParamValueIfNotSpecified(Command, Compressed, this.Compressed, "compressed");
            this.UseDebugParamForEditorExe = GetParamValueIfNotSpecified(Command, UseDebugParamForEditorExe, this.UseDebugParamForEditorExe, "UseDebugParamForEditorExe");
            this.IterativeCooking = GetParamValueIfNotSpecified(Command, IterativeCooking, this.IterativeCooking, new string[] { "iterativecooking", "iterate" } );
			this.SkipCookOnTheFly = GetParamValueIfNotSpecified(Command, SkipCookOnTheFly, this.SkipCookOnTheFly, "skipcookonthefly");
            this.CookAll = GetParamValueIfNotSpecified(Command, CookAll, this.CookAll, "CookAll");
            this.CookMapsOnly = GetParamValueIfNotSpecified(Command, CookMapsOnly, this.CookMapsOnly, "CookMapsOnly");
			this.FileServer = GetParamValueIfNotSpecified(Command, FileServer, this.FileServer, "fileserver");
			this.DedicatedServer = GetParamValueIfNotSpecified(Command, DedicatedServer, this.DedicatedServer, "dedicatedserver", "server");
			this.Client = GetParamValueIfNotSpecified(Command, Client, this.Client, "client");
			if( this.Client )
			{
				this.DedicatedServer = true;
			}
			this.NoClient = GetParamValueIfNotSpecified(Command, NoClient, this.NoClient, "noclient");
			this.LogWindow = GetParamValueIfNotSpecified(Command, LogWindow, this.LogWindow, "logwindow");
			this.Stage = GetParamValueIfNotSpecified(Command, Stage, this.Stage, "stage");
			this.SkipStage = GetParamValueIfNotSpecified(Command, SkipStage, this.SkipStage, "skipstage");
			if (this.SkipStage)
			{
				this.Stage = true;
			}
			this.StageDirectoryParam = ParseParamValueIfNotSpecified(Command, StageDirectoryParam, "stagingdirectory", String.Empty, true);
            this.StageNonMonolithic = GetParamValueIfNotSpecified(Command, StageNonMonolithic, this.StageNonMonolithic, "StageNonMonolithic");
			this.Manifests = GetParamValueIfNotSpecified(Command, Manifests, this.Manifests, "manifests");
            this.CreateChunkInstall = GetParamValueIfNotSpecified(Command, CreateChunkInstall, this.CreateChunkInstall, "createchunkinstall");
			this.ChunkInstallDirectory = ParseParamValueIfNotSpecified(Command, ChunkInstallDirectory, "chunkinstalldirectory", String.Empty, true);
			this.ChunkInstallVersionString = ParseParamValueIfNotSpecified(Command, ChunkInstallVersionString, "chunkinstallversion", String.Empty, true);
			this.Archive = GetParamValueIfNotSpecified(Command, Archive, this.Archive, "archive");
			this.ArchiveDirectoryParam = ParseParamValueIfNotSpecified(Command, ArchiveDirectoryParam, "archivedirectory", String.Empty, true);
			this.ArchiveMetaData = GetParamValueIfNotSpecified(Command, ArchiveMetaData, this.ArchiveMetaData, "archivemetadata");
			this.Distribution = GetParamValueIfNotSpecified(Command, Distribution, this.Distribution, "distribution");
			this.Prereqs = GetParamValueIfNotSpecified(Command, Prereqs, this.Prereqs, "prereqs");
			this.NoBootstrapExe = GetParamValueIfNotSpecified(Command, NoBootstrapExe, this.NoBootstrapExe, "nobootstrapexe");
            this.Prebuilt = GetParamValueIfNotSpecified(Command, Prebuilt, this.Prebuilt, "prebuilt");
            if (this.Prebuilt)
            {
                this.SkipCook = true;
                /*this.SkipPak = true;
                this.SkipStage = true;
                this.Pak = true;
                this.Stage = true;*/
                this.Cook = true;
                this.Archive = true;
                
                this.Deploy = true;
                this.Run = true;
                //this.StageDirectoryParam = this.PrebuiltDir;
            }
            this.NoDebugInfo = GetParamValueIfNotSpecified(Command, NoDebugInfo, this.NoDebugInfo, "nodebuginfo");
			this.NoCleanStage = GetParamValueIfNotSpecified(Command, NoCleanStage, this.NoCleanStage, "nocleanstage");
			this.MapToRun = ParseParamValueIfNotSpecified(Command, MapToRun, "map", String.Empty);
			this.AdditionalServerMapParams = ParseParamValueIfNotSpecified(Command, AdditionalServerMapParams, "AdditionalServerMapParams", String.Empty);
			this.Foreign = GetParamValueIfNotSpecified(Command, Foreign, this.Foreign, "foreign");
			this.ForeignCode = GetParamValueIfNotSpecified(Command, ForeignCode, this.ForeignCode, "foreigncode");
			this.StageCommandline = ParseParamValueIfNotSpecified(Command, StageCommandline, "cmdline");
			this.BundleName = ParseParamValueIfNotSpecified(Command, BundleName, "bundlename");
			this.RunCommandline = ParseParamValueIfNotSpecified(Command, RunCommandline, "addcmdline");
			this.Package = GetParamValueIfNotSpecified(Command, Package, this.Package, "package");
			this.Deploy = GetParamValueIfNotSpecified(Command, Deploy, this.Deploy, "deploy");
			this.IterativeDeploy = GetParamValueIfNotSpecified(Command, IterativeDeploy, this.IterativeDeploy, new string[] {"iterativedeploy", "iterate" } );
			this.FastCook = GetParamValueIfNotSpecified(Command, FastCook, this.FastCook, "FastCook");
			this.IgnoreCookErrors = GetParamValueIfNotSpecified(Command, IgnoreCookErrors, this.IgnoreCookErrors, "IgnoreCookErrors");
			this.Device = ParseParamValueIfNotSpecified(Command, Device, "device", String.Empty).Trim(new char[] { '\"' });

			// strip the platform prefix the specified device.
			if (this.Device.Contains("@"))
			{
				this.DeviceName = this.Device.Substring(this.Device.IndexOf("@") + 1);
			}
			else
			{
				this.DeviceName = this.Device;
			}

			this.ServerDevice = ParseParamValueIfNotSpecified(Command, ServerDevice, "serverdevice", this.Device);
			this.NullRHI = GetParamValueIfNotSpecified(Command, NullRHI, this.NullRHI, "nullrhi");
			this.FakeClient = GetParamValueIfNotSpecified(Command, FakeClient, this.FakeClient, "fakeclient");
			this.EditorTest = GetParamValueIfNotSpecified(Command, EditorTest, this.EditorTest, "editortest");
            this.RunAutomationTest = ParseParamValueIfNotSpecified(Command, RunAutomationTest, "RunAutomationTest");
            this.RunAutomationTests = this.RunAutomationTest != "" || GetParamValueIfNotSpecified(Command, RunAutomationTests, this.RunAutomationTests, "RunAutomationTests");
            this.SkipServer = GetParamValueIfNotSpecified(Command, SkipServer, this.SkipServer, "skipserver");
			this.Rocket = GetParamValueIfNotSpecified(Command, Rocket, this.Rocket || GlobalCommandLine.Rocket, "rocket");
			this.UE4Exe = ParseParamValueIfNotSpecified(Command, UE4Exe, "ue4exe", "UE4Editor-Cmd.exe");
			this.Unattended = GetParamValueIfNotSpecified(Command, Unattended, this.Unattended, "unattended");
			this.DeviceUsername = ParseParamValueIfNotSpecified(Command, DeviceUsername, "deviceuser", String.Empty);
			this.DevicePassword = ParseParamValueIfNotSpecified(Command, DevicePassword, "devicepass", String.Empty);
			this.CrashReporter = GetParamValueIfNotSpecified(Command, CrashReporter, this.CrashReporter, "crashreporter");
			this.SpecifiedArchitecture = ParseParamValueIfNotSpecified(Command, SpecifiedArchitecture, "specifiedarchitecture", String.Empty);
			if (ClientConfigsToBuild == null)
			{
				if (Command != null)
				{
					var ClientConfig = Command.ParseParamValue("clientconfig");
					if (ClientConfig != null)
					{
						this.ClientConfigsToBuild = new List<UnrealTargetConfiguration>();
						var Configs = new ParamList<string>(ClientConfig.Split('+'));
						foreach (var ConfigName in Configs)
						{
							this.ClientConfigsToBuild.Add((UnrealTargetConfiguration)Enum.Parse(typeof(UnrealTargetConfiguration), ConfigName, true));
						}
					}
				}
			}
			else
			{
				this.ClientConfigsToBuild = ClientConfigsToBuild;
			}

            if (Port == null)
            {
                if( Command != null )
                {
                    this.Port = new ParamList<string>();

                    var PortString = Command.ParseParamValue("port");
                    if (String.IsNullOrEmpty(PortString) == false)
                    {
                        var Ports = new ParamList<string>(PortString.Split('+'));
                        foreach (var P in Ports)
                        {
                            this.Port.Add(P);
                        }
                    }
                    
                }
            }
            else
            {
                this.Port = Port;
            }

            if (MapsToCook == null)
            {
                if (Command != null)
                {
                    this.MapsToCook = new ParamList<string>();

                    var MapsString = Command.ParseParamValue("MapsToCook");
                    if (String.IsNullOrEmpty(MapsString) == false)
                    {
                        var MapNames = new ParamList<string>(MapsString.Split('+'));
                        foreach ( var M in MapNames ) 
                        {
                            this.MapsToCook.Add( M );
                        }
                    }
                }
            }
            else
            {
                this.MapsToCook = MapsToCook;
            }

            if (String.IsNullOrEmpty(this.MapToRun) == false)
            {
                this.MapsToCook.Add(this.MapToRun);
            }
            
			if (ServerConfigsToBuild == null)
			{
				if (Command != null)
				{
					var ServerConfig = Command.ParseParamValue("serverconfig");
					if (ServerConfig != null && ServerConfigsToBuild == null)
					{
						this.ServerConfigsToBuild = new List<UnrealTargetConfiguration>();
						var Configs = new ParamList<string>(ServerConfig.Split('+'));
						foreach (var ConfigName in Configs)
						{
							this.ServerConfigsToBuild.Add((UnrealTargetConfiguration)Enum.Parse(typeof(UnrealTargetConfiguration), ConfigName, true));
						}
					}
				}
			}
			else
			{
				this.ServerConfigsToBuild = ServerConfigsToBuild;
			}
			if (NumClients.HasValue)
			{
				this.NumClients = NumClients.Value;
			}
			else if (Command != null)
			{
				this.NumClients = Command.ParseParamInt("numclients");
			}
            if (CrashIndex.HasValue)
            {
                this.CrashIndex = CrashIndex.Value;
            }
            else if (Command != null)
            {
                this.CrashIndex = Command.ParseParamInt("CrashIndex");
            }
            if (RunTimeoutSeconds.HasValue)
            {
                this.RunTimeoutSeconds = RunTimeoutSeconds.Value;
            }
            else if (Command != null)
            {
                this.RunTimeoutSeconds = Command.ParseParamInt("runtimeoutseconds");
            }

			AutodetectSettings(false);
			ValidateAndLog();
		}
        /// <summary>
        /// Main method.
        /// </summary>
        /// <param name="CommandLine">Command line</param>
        public static ExitCode Process(string[] CommandLine)
        {
            // Initial check for local or build machine runs BEFORE we parse the command line (We need this value set
            // in case something throws the exception while parsing the command line)
            IsBuildMachine = !String.IsNullOrEmpty(Environment.GetEnvironmentVariable("uebp_LOCAL_ROOT"));

            // Scan the command line for commands to execute.
            var    CommandsToExecute = new List <CommandInfo>();
            string OutScriptsForProjectFileName;
            var    AdditionalScriptsFolders = new List <string>();

            ParseCommandLine(CommandLine, CommandsToExecute, out OutScriptsForProjectFileName, AdditionalScriptsFolders);

            // Check for build machine override (force local)
            IsBuildMachine = GlobalCommandLine.ForceLocal ? false : IsBuildMachine;
            Log.TraceVerbose("IsBuildMachine={0}", IsBuildMachine);
            Environment.SetEnvironmentVariable("IsBuildMachine", IsBuildMachine ? "1" : "0");

            // should we kill processes on exit
            ShouldKillProcesses = !GlobalCommandLine.NoKill;
            Log.TraceVerbose("ShouldKillProcesses={0}", ShouldKillProcesses);

            if (CommandsToExecute.Count == 0 && GlobalCommandLine.Help)
            {
                DisplayHelp();
                return(ExitCode.Success);
            }

            // Disable AutoSDKs if specified on the command line
            if (GlobalCommandLine.NoAutoSDK)
            {
                UEBuildPlatformSDK.bAllowAutoSDKSwitching = false;
            }

            // Setup environment
            Log.TraceInformation("Setting up command environment.");
            CommandUtils.InitCommandEnvironment();

            // Change CWD to UE4 root.
            Environment.CurrentDirectory = CommandUtils.CmdEnv.LocalRoot;

            // Fill in the project info
            UnrealBuildTool.UProjectInfo.FillProjectInfo();

            // Clean rules folders up
            ProjectUtils.CleanupFolders();

            // Compile scripts.
            ScriptCompiler Compiler = new ScriptCompiler();

            using (TelemetryStopwatch ScriptCompileStopwatch = new TelemetryStopwatch("ScriptCompile"))
            {
                Compiler.FindAndCompileAllScripts(OutScriptsForProjectFileName, AdditionalScriptsFolders);
            }

            if (GlobalCommandLine.CompileOnly)
            {
                Log.TraceInformation("Compilation successful, exiting (CompileOnly)");
                return(ExitCode.Success);
            }

            if (GlobalCommandLine.List)
            {
                ListAvailableCommands(Compiler.Commands);
                return(ExitCode.Success);
            }

            if (GlobalCommandLine.Help)
            {
                DisplayHelp(CommandsToExecute, Compiler.Commands);
                return(ExitCode.Success);
            }

            // Enable or disable P4 support
            CommandUtils.InitP4Support(CommandsToExecute, Compiler.Commands);
            if (CommandUtils.P4Enabled)
            {
                Log.TraceInformation("Setting up Perforce environment.");
                CommandUtils.InitP4Environment();
                CommandUtils.InitDefaultP4Connection();
            }

            // Find and execute commands.
            return(Execute(CommandsToExecute, Compiler.Commands));
        }
        public override string GetMsBuildExe()
        {
            var DotNETToolsFolder = CommandUtils.CombinePaths(CommandUtils.GetEnvVar(EnvVarNames.NETFrameworkDir), CommandUtils.GetEnvVar(EnvVarNames.NETFrameworkVersion));
            var MsBuildExe        = CommandUtils.CombinePaths(DotNETToolsFolder, "MSBuild.exe");

            if (!CommandUtils.FileExists_NoExceptions(MsBuildExe))
            {
                throw new NotSupportedException("MsBuild.exe does not exist.");
            }
            return(MsBuildExe);
        }
        /// <summary>
        /// Entry point for the commandlet
        /// </summary>
        public override void ExecuteBuild()
        {
            string OutputDir = ParseRequiredStringParam("OutputDir");
            List <UnrealTargetPlatform> Platforms            = ParsePlatformsParamValue("Platforms");
            List <UnrealTargetPlatform> ContentOnlyPlatforms = ParsePlatformsParamValue("ContentOnlyPlatforms");
            string AnalyticsTypeOverride = ParseParamValue("AnalyticsTypeOverride");

            // Write InstalledBuild.txt to indicate Engine is installed
            string InstalledBuildFile = CommandUtils.CombinePaths(OutputDir, "Engine/Build/InstalledBuild.txt");

            CommandUtils.CreateDirectory(CommandUtils.GetDirectoryName(InstalledBuildFile));
            CommandUtils.WriteAllText(InstalledBuildFile, "");

            // Write InstalledBuild.txt to indicate Engine is installed
            string Project = ParseParamValue("Project");

            if (Project != null)
            {
                string InstalledProjectBuildFile = CommandUtils.CombinePaths(OutputDir, "Engine/Build/InstalledProjectBuild.txt");
                CommandUtils.CreateDirectory(CommandUtils.GetDirectoryName(InstalledProjectBuildFile));
                CommandUtils.WriteAllText(InstalledProjectBuildFile, new FileReference(Project).MakeRelativeTo(new DirectoryReference(OutputDir)));
            }

            string         OutputEnginePath     = Path.Combine(OutputDir, "Engine");
            string         OutputBaseEnginePath = Path.Combine(OutputEnginePath, "Config", "BaseEngine.ini");
            FileAttributes OutputAttributes     = FileAttributes.ReadOnly;
            List <String>  IniLines             = new List <String>();

            // Should always exist but if not, we don't need extra line
            if (File.Exists(OutputBaseEnginePath))
            {
                OutputAttributes = File.GetAttributes(OutputBaseEnginePath);
                IniLines.Add("");
            }
            else
            {
                CommandUtils.CreateDirectory(CommandUtils.GetDirectoryName(OutputBaseEnginePath));
                CommandUtils.WriteAllText(OutputBaseEnginePath, "");
                OutputAttributes = File.GetAttributes(OutputBaseEnginePath) | OutputAttributes;
            }

            // Create list of platform configurations installed in a Rocket build
            List <InstalledPlatformInfo.InstalledPlatformConfiguration> InstalledConfigs = new List <InstalledPlatformInfo.InstalledPlatformConfiguration>();

            // Add the editor platform, otherwise we'll never be able to run UAT
            string EditorArchitecture = PlatformExports.GetDefaultArchitecture(HostPlatform.Current.HostEditorPlatform, null);

            InstalledConfigs.Add(new InstalledPlatformInfo.InstalledPlatformConfiguration(UnrealTargetConfiguration.Development, HostPlatform.Current.HostEditorPlatform, TargetRules.TargetType.Editor, EditorArchitecture, "", EProjectType.Unknown, false));
            InstalledConfigs.Add(new InstalledPlatformInfo.InstalledPlatformConfiguration(UnrealTargetConfiguration.DebugGame, HostPlatform.Current.HostEditorPlatform, TargetRules.TargetType.Editor, EditorArchitecture, "", EProjectType.Unknown, false));

            foreach (UnrealTargetPlatform CodeTargetPlatform in Platforms)
            {
                string Architecture = PlatformExports.GetDefaultArchitecture(CodeTargetPlatform, null);

                // Try to parse additional Architectures from the command line
                string Architectures    = ParseParamValue(CodeTargetPlatform.ToString() + "Architectures");
                string GPUArchitectures = ParseParamValue(CodeTargetPlatform.ToString() + "GPUArchitectures");

                // Build a list of pre-compiled architecture combinations for this platform if any
                List <string> AllArchNames;

                if (!String.IsNullOrWhiteSpace(Architectures) && !String.IsNullOrWhiteSpace(GPUArchitectures))
                {
                    AllArchNames = (from Arch in Architectures.Split('+')
                                    from GPUArch in GPUArchitectures.Split('+')
                                    select "-" + Arch + "-" + GPUArch).ToList();
                }
                else if (!String.IsNullOrWhiteSpace(Architectures))
                {
                    AllArchNames = Architectures.Split('+').ToList();
                }
                // if there aren't any, use the default
                else
                {
                    AllArchNames = new List <string>()
                    {
                        Architecture
                    };
                }

                // Check whether this platform should only be used for content based projects
                EProjectType ProjectType = ContentOnlyPlatforms.Contains(CodeTargetPlatform) ? EProjectType.Content : EProjectType.Any;

                // Allow Content only platforms to be shown as options in all projects
                bool bCanBeDisplayed = ProjectType == EProjectType.Content;
                foreach (UnrealTargetConfiguration CodeTargetConfiguration in Enum.GetValues(typeof(UnrealTargetConfiguration)))
                {
                    Dictionary <String, TargetType> Targets = new Dictionary <string, TargetType>()
                    {
                        { "UE4Game", TargetType.Game },
                        { "UE4Client", TargetType.Client },
                        { "UE4Server", TargetType.Server }
                    };
                    foreach (KeyValuePair <string, TargetType> Target in Targets)
                    {
                        string     CurrentTargetName = Target.Key;
                        TargetType CurrentTargetType = Target.Value;

                        // Need to check for development receipt as we use that for the Engine code in DebugGame
                        UnrealTargetConfiguration EngineConfiguration = (CodeTargetConfiguration == UnrealTargetConfiguration.DebugGame) ? UnrealTargetConfiguration.Development : CodeTargetConfiguration;

                        // Android has multiple architecture flavors built without receipts, so use the default arch target instead
                        if (CodeTargetPlatform == UnrealTargetPlatform.Android)
                        {
                            FileReference ReceiptFileName = TargetReceipt.GetDefaultPath(new DirectoryReference(OutputEnginePath), CurrentTargetName, CodeTargetPlatform, EngineConfiguration, Architecture);
                            if (FileReference.Exists(ReceiptFileName))
                            {
                                // Strip the output folder so that this can be used on any machine
                                string RelativeReceiptFileName = ReceiptFileName.MakeRelativeTo(new DirectoryReference(OutputDir));

                                // Blindly append all of the architecture names
                                if (AllArchNames.Count > 0)
                                {
                                    foreach (string Arch in AllArchNames)
                                    {
                                        InstalledConfigs.Add(new InstalledPlatformInfo.InstalledPlatformConfiguration(CodeTargetConfiguration, CodeTargetPlatform, CurrentTargetType, Arch, RelativeReceiptFileName, ProjectType, bCanBeDisplayed));
                                    }
                                }
                                // if for some reason we didn't specify any flavors, just add the default one.
                                else
                                {
                                    InstalledConfigs.Add(new InstalledPlatformInfo.InstalledPlatformConfiguration(CodeTargetConfiguration, CodeTargetPlatform, CurrentTargetType, Architecture, RelativeReceiptFileName, ProjectType, bCanBeDisplayed));
                                }
                            }
                        }
                        // If we're not Android, check the existence of the target receipts for each architecture specified.
                        else
                        {
                            foreach (string Arch in AllArchNames)
                            {
                                FileReference ReceiptFileName = TargetReceipt.GetDefaultPath(new DirectoryReference(OutputEnginePath), CurrentTargetName, CodeTargetPlatform, EngineConfiguration, Arch);
                                if (FileReference.Exists(ReceiptFileName))
                                {
                                    string RelativeReceiptFileName = ReceiptFileName.MakeRelativeTo(new DirectoryReference(OutputDir));
                                    InstalledConfigs.Add(new InstalledPlatformInfo.InstalledPlatformConfiguration(CodeTargetConfiguration, CodeTargetPlatform, CurrentTargetType, Arch, RelativeReceiptFileName, ProjectType, bCanBeDisplayed));
                                }
                            }
                        }
                    }
                }
            }

            UnrealBuildTool.InstalledPlatformInfo.WriteConfigFileEntries(InstalledConfigs, ref IniLines);

            if (!String.IsNullOrEmpty(AnalyticsTypeOverride))
            {
                // Write Custom Analytics type setting
                IniLines.Add("");
                IniLines.Add("[Analytics]");
                IniLines.Add(String.Format("UE4TypeOverride=\"{0}\"", AnalyticsTypeOverride));
            }

            // Make sure we can write to the the config file
            File.SetAttributes(OutputBaseEnginePath, OutputAttributes & ~FileAttributes.ReadOnly);
            File.AppendAllLines(OutputBaseEnginePath, IniLines);
            File.SetAttributes(OutputBaseEnginePath, OutputAttributes);
        }
Exemple #23
0
        /// <summary>
        /// Initializes trace logging.
        /// </summary>
        /// <param name="CommandLine">Command line.</param>
        public static void InitLogging(string[] CommandLine)
        {
            // ensure UTF8Output flag is respected, since we are initializing logging early in the program.
            if (CommandLine.Any(Arg => Arg.Equals("-utf8output", StringComparison.InvariantCultureIgnoreCase)))
            {
                Console.OutputEncoding = new System.Text.UTF8Encoding(false, false);
            }

            UnrealBuildTool.Log.InitLogging(
                bLogTimestamps: CommandUtils.ParseParam(CommandLine, "-Timestamps"),
                InLogLevel: (UnrealBuildTool.LogEventType)Enum.Parse(typeof(UnrealBuildTool.LogEventType), CommandUtils.ParseParamValue(CommandLine, "-Verbose=", "Log")),
                bLogSeverity: true,
                bLogProgramNameWithSeverity: false,
                bLogSources: true,
                bLogSourcesToConsole: false,
                bColorConsoleOutput: true,
                TraceListeners: new TraceListener[]
            {
                new UEConsoleTraceListener(),
                // could return null, but InitLogging handles this gracefully.
                CreateLogFileListener(out LogFilename),
                //@todo - this is only used by GUBP nodes. Ideally we don't waste this 20MB if we are not running GUBP.
                new AutomationMemoryLogListener(),
            });
        }
 public override string GetUE4ExePath(string UE4Exe)
 {
     return(CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, RelativeBinariesFolder, UE4Exe));
 }
Exemple #25
0
 /// <summary>
 /// Gets a short project name (QAGame, Elemental, etc)
 /// </summary>
 /// <param name="RawProjectPath">Full project path.</param>
 /// <param name="bIsUProjectFile">True if a uproject.</param>
 /// <returns>Short project name</returns>
 public static string GetShortProjectName(FileReference RawProjectPath)
 {
     return(CommandUtils.GetFilenameWithoutAnyExtensions(RawProjectPath.FullName));
 }
        /// <summary>
        /// Initializes the environement.
        /// </summary>
        protected virtual void InitEnvironment()
        {
            SetUATLocation();

            LocalRoot = CommandUtils.GetEnvVar(EnvVarNames.LocalRoot);
            if (String.IsNullOrEmpty(CommandUtils.GetEnvVar(EnvVarNames.EngineSavedFolder)))
            {
                SetUATSavedPath();
            }

            if (LocalRoot.EndsWith(":"))
            {
                LocalRoot += Path.DirectorySeparatorChar;
            }

            EngineSavedFolder = CommandUtils.GetEnvVar(EnvVarNames.EngineSavedFolder);
            CSVFile           = CommandUtils.GetEnvVar(EnvVarNames.CSVFile);
            LogFolder         = CommandUtils.GetEnvVar(EnvVarNames.LogFolder);
            RobocopyExe       = GetSystemExePath("robocopy.exe");
            MountExe          = GetSystemExePath("mount.exe");
            CmdExe            = Utils.IsRunningOnMono ? "/bin/sh" : GetSystemExePath("cmd.exe");
            MallocNanoZone    = "0";
            CommandUtils.SetEnvVar(EnvVarNames.MacMallocNanoZone, MallocNanoZone);
            if (String.IsNullOrEmpty(LogFolder))
            {
                throw new AutomationException("Environment is not set up correctly: LogFolder is not set!");
            }

            if (String.IsNullOrEmpty(LocalRoot))
            {
                throw new AutomationException("Environment is not set up correctly: LocalRoot is not set!");
            }

            if (String.IsNullOrEmpty(EngineSavedFolder))
            {
                throw new AutomationException("Environment is not set up correctly: EngineSavedFolder is not set!");
            }

            // Make sure that the log folder exists
            var LogFolderInfo = new DirectoryInfo(LogFolder);

            if (!LogFolderInfo.Exists)
            {
                LogFolderInfo.Create();
            }

            // Setup the timestamp string
            DateTime LocalTime = DateTime.Now;

            string TimeStamp = LocalTime.Year + "-"
                               + LocalTime.Month.ToString("00") + "-"
                               + LocalTime.Day.ToString("00") + "_"
                               + LocalTime.Hour.ToString("00") + "."
                               + LocalTime.Minute.ToString("00") + "."
                               + LocalTime.Second.ToString("00");

            TimestampAsString = TimeStamp;

            SetupBuildEnvironment();

            LogSettings();
        }
Exemple #27
0
        /// <summary>
        /// Finds all targets for the project.
        /// </summary>
        /// <param name="Properties">Project properties.</param>
        /// <param name="ExtraSearchPaths">Additional search paths.</param>
        private static void DetectTargetsForProject(ProjectProperties Properties, List <string> ExtraSearchPaths = null)
        {
            Properties.Targets = new Dictionary <TargetRules.TargetType, SingleTargetProperties>();
            FileReference TargetsDllFilename;
            string        FullProjectPath = null;

            var GameFolders = new List <DirectoryReference>();
            var RulesFolder = new DirectoryReference(GetRulesAssemblyFolder());

            if (Properties.RawProjectPath != null)
            {
                CommandUtils.LogVerbose("Looking for targets for project {0}", Properties.RawProjectPath);

                TargetsDllFilename = FileReference.Combine(RulesFolder, String.Format("UATRules{0}.dll", Properties.RawProjectPath.GetHashCode()));

                FullProjectPath = CommandUtils.GetDirectoryName(Properties.RawProjectPath.FullName);
                GameFolders.Add(new DirectoryReference(FullProjectPath));
                CommandUtils.LogVerbose("Searching for target rule files in {0}", FullProjectPath);
            }
            else
            {
                TargetsDllFilename = FileReference.Combine(RulesFolder, String.Format("UATRules{0}.dll", "_BaseEngine_"));
            }

            // the UBT code assumes a certain CWD, but artists don't have this CWD.
            var  SourceDir = CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, "Engine", "Source");
            bool DirPushed = false;

            if (CommandUtils.DirectoryExists_NoExceptions(SourceDir))
            {
                CommandUtils.PushDir(SourceDir);
                DirPushed = true;
            }
            var ExtraSearchDirectories = (ExtraSearchPaths == null)? null : ExtraSearchPaths.Select(x => new DirectoryReference(x)).ToList();
            var TargetScripts          = RulesCompiler.FindAllRulesSourceFiles(RulesCompiler.RulesFileType.Target, GameFolders: GameFolders, ForeignPlugins: null, AdditionalSearchPaths: ExtraSearchDirectories);

            if (DirPushed)
            {
                CommandUtils.PopDir();
            }

            if (!CommandUtils.IsNullOrEmpty(TargetScripts))
            {
                // We only care about project target script so filter out any scripts not in the project folder, or take them all if we are just doing engine stuff
                var ProjectTargetScripts = new List <FileReference>();
                foreach (var TargetScript in TargetScripts)
                {
                    if (FullProjectPath == null || TargetScript.IsUnderDirectory(new DirectoryReference(FullProjectPath)))
                    {
                        ProjectTargetScripts.Add(TargetScript);
                    }
                }
                TargetScripts = ProjectTargetScripts;
            }

            if (!CommandUtils.IsNullOrEmpty(TargetScripts))
            {
                CommandUtils.LogVerbose("Found {0} target rule files:", TargetScripts.Count);
                foreach (var Filename in TargetScripts)
                {
                    CommandUtils.LogVerbose("  {0}", Filename);
                }

                // Check if the scripts require compilation
                bool DoNotCompile = false;
                if (!CommandUtils.IsBuildMachine && !CheckIfScriptAssemblyIsOutOfDate(TargetsDllFilename, TargetScripts))
                {
                    Log.TraceVerbose("Targets DLL {0} is up to date.", TargetsDllFilename);
                    DoNotCompile = true;
                }
                if (!DoNotCompile && CommandUtils.FileExists_NoExceptions(TargetsDllFilename.FullName))
                {
                    if (!CommandUtils.DeleteFile_NoExceptions(TargetsDllFilename.FullName, true))
                    {
                        DoNotCompile = true;
                        CommandUtils.LogVerbose("Could not delete {0} assuming it is up to date and reusable for a recursive UAT call.", TargetsDllFilename);
                    }
                }

                CompileAndLoadTargetsAssembly(Properties, TargetsDllFilename, DoNotCompile, TargetScripts);
            }
        }
Exemple #28
0
        /// <summary>
        /// Build a node
        /// </summary>
        /// <param name="Job">Information about the current job</param>
        /// <param name="Graph">The graph to which the node belongs. Used to determine which outputs need to be transferred to temp storage.</param>
        /// <param name="Node">The node to build</param>
        /// <param name="Storage">The temp storage backend which stores the shared state</param>
        /// <param name="bWithBanner">Whether to write a banner before and after this node's log output</param>
        /// <returns>True if the node built successfully, false otherwise.</returns>
        bool BuildNode(JobContext Job, Graph Graph, Node Node, TempStorage Storage, bool bWithBanner)
        {
            DirectoryReference RootDir = new DirectoryReference(CommandUtils.CmdEnv.LocalRoot);

            // Create the mapping of tag names to file sets
            Dictionary <string, HashSet <FileReference> > TagNameToFileSet = new Dictionary <string, HashSet <FileReference> >();

            // Read all the input tags for this node, and build a list of referenced input storage blocks
            HashSet <TempStorageBlock> InputStorageBlocks = new HashSet <TempStorageBlock>();

            foreach (NodeOutput Input in Node.Inputs)
            {
                TempStorageFileList FileList = Storage.ReadFileList(Input.ProducingNode.Name, Input.TagName);
                TagNameToFileSet[Input.TagName] = FileList.ToFileSet(RootDir);
                InputStorageBlocks.UnionWith(FileList.Blocks);
            }

            // Read the manifests for all the input storage blocks
            Dictionary <TempStorageBlock, TempStorageManifest> InputManifests = new Dictionary <TempStorageBlock, TempStorageManifest>();

            foreach (TempStorageBlock InputStorageBlock in InputStorageBlocks)
            {
                TempStorageManifest Manifest = Storage.Retreive(InputStorageBlock.NodeName, InputStorageBlock.OutputName);
                InputManifests[InputStorageBlock] = Manifest;
            }

            // Read all the input storage blocks, keeping track of which block each file came from
            Dictionary <FileReference, TempStorageBlock> FileToStorageBlock = new Dictionary <FileReference, TempStorageBlock>();

            foreach (KeyValuePair <TempStorageBlock, TempStorageManifest> Pair in InputManifests)
            {
                TempStorageBlock InputStorageBlock = Pair.Key;
                foreach (FileReference File in Pair.Value.Files.Select(x => x.ToFileReference(RootDir)))
                {
                    TempStorageBlock CurrentStorageBlock;
                    if (FileToStorageBlock.TryGetValue(File, out CurrentStorageBlock))
                    {
                        LogError("File '{0}' was produced by {1} and {2}", File, InputStorageBlock, CurrentStorageBlock);
                    }
                    FileToStorageBlock[File] = InputStorageBlock;
                }
            }

            // Add placeholder outputs for the current node
            foreach (NodeOutput Output in Node.Outputs)
            {
                TagNameToFileSet.Add(Output.TagName, new HashSet <FileReference>());
            }

            // Execute the node
            if (bWithBanner)
            {
                Console.WriteLine();
                CommandUtils.LogInformation("========== Starting: {0} ==========", Node.Name);
            }
            if (!Node.Build(Job, TagNameToFileSet))
            {
                return(false);
            }
            if (bWithBanner)
            {
                CommandUtils.LogInformation("========== Finished: {0} ==========", Node.Name);
                Console.WriteLine();
            }

            // Check that none of the inputs have been clobbered
            Dictionary <string, string> ModifiedFiles = new Dictionary <string, string>(StringComparer.InvariantCultureIgnoreCase);

            foreach (TempStorageFile File in InputManifests.Values.SelectMany(x => x.Files))
            {
                string Message;
                if (!ModifiedFiles.ContainsKey(File.RelativePath) && !File.Compare(CommandUtils.RootDirectory, out Message))
                {
                    ModifiedFiles.Add(File.RelativePath, Message);
                }
            }
            if (ModifiedFiles.Count > 0)
            {
                throw new AutomationException("Build {0} from a previous step have been modified:\n{1}", (ModifiedFiles.Count == 1)? "product" : "products", String.Join("\n", ModifiedFiles.Select(x => x.Value)));
            }

            // Determine all the output files which are required to be copied to temp storage (because they're referenced by nodes in another agent)
            HashSet <FileReference> ReferencedOutputFiles = new HashSet <FileReference>();

            foreach (Agent Agent in Graph.Agents)
            {
                bool bSameAgent = Agent.Nodes.Contains(Node);
                foreach (Node OtherNode in Agent.Nodes)
                {
                    if (!bSameAgent || Node.ControllingTrigger != OtherNode.ControllingTrigger)
                    {
                        foreach (NodeOutput Input in OtherNode.Inputs.Where(x => x.ProducingNode == Node))
                        {
                            ReferencedOutputFiles.UnionWith(TagNameToFileSet[Input.TagName]);
                        }
                    }
                }
            }

            // Find a block name for all new outputs
            Dictionary <FileReference, string> FileToOutputName = new Dictionary <FileReference, string>();

            foreach (NodeOutput Output in Node.Outputs)
            {
                HashSet <FileReference> Files = TagNameToFileSet[Output.TagName];
                foreach (FileReference File in Files)
                {
                    if (!FileToStorageBlock.ContainsKey(File) && File.IsUnderDirectory(RootDir))
                    {
                        if (Output == Node.DefaultOutput)
                        {
                            if (!FileToOutputName.ContainsKey(File))
                            {
                                FileToOutputName[File] = "";
                            }
                        }
                        else
                        {
                            string OutputName;
                            if (FileToOutputName.TryGetValue(File, out OutputName) && OutputName.Length > 0)
                            {
                                FileToOutputName[File] = String.Format("{0}+{1}", OutputName, Output.TagName.Substring(1));
                            }
                            else
                            {
                                FileToOutputName[File] = Output.TagName.Substring(1);
                            }
                        }
                    }
                }
            }

            // Invert the dictionary to make a mapping of storage block to the files each contains
            Dictionary <string, HashSet <FileReference> > OutputStorageBlockToFiles = new Dictionary <string, HashSet <FileReference> >();

            foreach (KeyValuePair <FileReference, string> Pair in FileToOutputName)
            {
                HashSet <FileReference> Files;
                if (!OutputStorageBlockToFiles.TryGetValue(Pair.Value, out Files))
                {
                    Files = new HashSet <FileReference>();
                    OutputStorageBlockToFiles.Add(Pair.Value, Files);
                }
                Files.Add(Pair.Key);
            }

            // Write all the storage blocks, and update the mapping from file to storage block
            foreach (KeyValuePair <string, HashSet <FileReference> > Pair in OutputStorageBlockToFiles)
            {
                TempStorageBlock OutputBlock = new TempStorageBlock(Node.Name, Pair.Key);
                foreach (FileReference File in Pair.Value)
                {
                    FileToStorageBlock.Add(File, OutputBlock);
                }
                Storage.Archive(Node.Name, Pair.Key, Pair.Value.ToArray(), Pair.Value.Any(x => ReferencedOutputFiles.Contains(x)));
            }

            // Publish all the output tags
            foreach (NodeOutput Output in Node.Outputs)
            {
                HashSet <FileReference> Files = TagNameToFileSet[Output.TagName];

                HashSet <TempStorageBlock> StorageBlocks = new HashSet <TempStorageBlock>();
                foreach (FileReference File in Files)
                {
                    TempStorageBlock StorageBlock;
                    if (FileToStorageBlock.TryGetValue(File, out StorageBlock))
                    {
                        StorageBlocks.Add(StorageBlock);
                    }
                }

                Storage.WriteFileList(Node.Name, Output.TagName, Files, StorageBlocks.ToArray());
            }

            // Mark the node as succeeded
            Storage.MarkAsComplete(Node.Name);
            return(true);
        }
        /// <summary>
        /// Runs GenerateDistillFileSets commandlet.
        /// </summary>
        /// <param name="ProjectName">Project name.</param>
        /// <param name="UE4Exe">The name of the UE4 Editor executable to use.</param>
        /// <param name="Maps">List of maps to cook, can be null in which case -MapIniSection=AllMaps is used.</param>
        /// <param name="TargetPlatform">Target platform.</param>
        /// <param name="Parameters">List of additional parameters.</param>
        public static List <string> GenerateDistillFileSetsCommandlet(FileReference ProjectName, string ManifestFile, string UE4Exe = "UE4Editor-Cmd.exe", string[] Maps = null, string Parameters = "")
        {
            string MapsToCook = "";

            if (!IsNullOrEmpty(Maps))
            {
                MapsToCook = CombineCommandletParams(Maps, " ").Trim();
            }
            var Dir      = Path.GetDirectoryName(ManifestFile);
            var Filename = Path.GetFileName(ManifestFile);

            if (String.IsNullOrEmpty(Dir) || String.IsNullOrEmpty(Filename))
            {
                throw new AutomationException("GenerateDistillFileSets should have a full path and file for {0}.", ManifestFile);
            }
            CreateDirectory_NoExceptions(Dir);
            if (FileExists_NoExceptions(ManifestFile))
            {
                DeleteFile(ManifestFile);
            }

            RunCommandlet(ProjectName, UE4Exe, "GenerateDistillFileSets", String.Format("{0} -OutputFolder={1} -Output={2} {3}", MapsToCook, CommandUtils.MakePathSafeToUseWithCommandLine(Dir), Filename, Parameters));

            if (!FileExists_NoExceptions(ManifestFile))
            {
                throw new AutomationException("GenerateDistillFileSets did not produce a manifest for {0}.", ProjectName);
            }
            var Lines = new List <string>(ReadAllLines(ManifestFile));

            if (Lines.Count < 1)
            {
                throw new AutomationException("GenerateDistillFileSets for {0} did not produce any files.", ProjectName);
            }
            var Result = new List <string>();

            foreach (var ThisFile in Lines)
            {
                var TestFile = CombinePaths(ThisFile);
                if (!FileExists_NoExceptions(TestFile))
                {
                    throw new AutomationException("GenerateDistillFileSets produced {0}, but {1} doesn't exist.", ThisFile, TestFile);
                }
                // we correct the case here
                var TestFileInfo = new FileInfo(TestFile);
                var FinalFile    = CombinePaths(TestFileInfo.FullName);
                if (!FileExists_NoExceptions(FinalFile))
                {
                    throw new AutomationException("GenerateDistillFileSets produced {0}, but {1} doesn't exist.", ThisFile, FinalFile);
                }
                Result.Add(FinalFile);
            }
            return(Result);
        }
Exemple #30
0
        /// <summary>
        /// Main entry point for the BuildGraph command
        /// </summary>
        public override ExitCode Execute()
        {
            // Parse the command line parameters
            string ScriptFileName        = ParseParamValue("Script", null);
            string TargetNames           = ParseParamValue("Target", null);
            string DocumentationFileName = ParseParamValue("Documentation", null);
            string SchemaFileName        = ParseParamValue("Schema", null);
            string ExportFileName        = ParseParamValue("Export", null);
            string PreprocessedFileName  = ParseParamValue("Preprocess", null);
            string SharedStorageDir      = ParseParamValue("SharedStorageDir", null);
            string SingleNodeName        = ParseParamValue("SingleNode", null);
            string TriggerName           = ParseParamValue("Trigger", null);

            string[] SkipTriggerNames          = ParseParamValue("SkipTrigger", "").Split(new char[] { '+', ';' }, StringSplitOptions.RemoveEmptyEntries).ToArray();
            bool     bSkipTriggers             = ParseParam("SkipTriggers");
            string   TokenSignature            = ParseParamValue("TokenSignature", null);
            bool     bSkipTargetsWithoutTokens = ParseParam("SkipTargetsWithoutTokens");
            bool     bResume               = SingleNodeName != null || ParseParam("Resume");
            bool     bListOnly             = ParseParam("ListOnly");
            bool     bShowDiagnostics      = ParseParam("ShowDiagnostics");
            bool     bWriteToSharedStorage = ParseParam("WriteToSharedStorage") || CommandUtils.IsBuildMachine;
            bool     bPublicTasksOnly      = ParseParam("PublicTasksOnly");
            string   ReportName            = ParseParamValue("ReportName", null);

            GraphPrintOptions PrintOptions = GraphPrintOptions.ShowCommandLineOptions;

            if (ParseParam("ShowDeps"))
            {
                PrintOptions |= GraphPrintOptions.ShowDependencies;
            }
            if (ParseParam("ShowNotifications"))
            {
                PrintOptions |= GraphPrintOptions.ShowNotifications;
            }

            // Parse any specific nodes to clean
            List <string> CleanNodes = new List <string>();

            foreach (string NodeList in ParseParamValues("CleanNode"))
            {
                foreach (string NodeName in NodeList.Split('+', ';'))
                {
                    CleanNodes.Add(NodeName);
                }
            }

            // Set up the standard properties which build scripts might need
            Dictionary <string, string> DefaultProperties = new Dictionary <string, string>(StringComparer.InvariantCultureIgnoreCase);

            DefaultProperties["Branch"]                 = P4Enabled ? P4Env.Branch : "Unknown";
            DefaultProperties["EscapedBranch"]          = P4Enabled ? CommandUtils.EscapePath(P4Env.Branch) : "Unknown";
            DefaultProperties["Change"]                 = P4Enabled ? P4Env.Changelist.ToString() : "0";
            DefaultProperties["CodeChange"]             = P4Enabled ? P4Env.CodeChangelist.ToString() : "0";
            DefaultProperties["RootDir"]                = CommandUtils.RootDirectory.FullName;
            DefaultProperties["IsBuildMachine"]         = IsBuildMachine ? "true" : "false";
            DefaultProperties["HostPlatform"]           = HostPlatform.Current.HostEditorPlatform.ToString();
            DefaultProperties["RestrictedFolderNames"]  = String.Join(";", RestrictedFolders.Names);
            DefaultProperties["RestrictedFolderFilter"] = String.Join(";", RestrictedFolders.Names.Select(x => String.Format(".../{0}/...", x)));

            // Attempt to read existing Build Version information
            BuildVersion Version;

            if (BuildVersion.TryRead(BuildVersion.GetDefaultFileName(), out Version))
            {
                DefaultProperties["EngineMajorVersion"]     = Version.MajorVersion.ToString();
                DefaultProperties["EngineMinorVersion"]     = Version.MinorVersion.ToString();
                DefaultProperties["EnginePatchVersion"]     = Version.PatchVersion.ToString();
                DefaultProperties["EngineCompatibleChange"] = Version.CompatibleChangelist.ToString();
            }

            // Add any additional custom arguments from the command line (of the form -Set:X=Y)
            Dictionary <string, string> Arguments = new Dictionary <string, string>(StringComparer.InvariantCultureIgnoreCase);

            foreach (string Param in Params)
            {
                const string Prefix = "set:";
                if (Param.StartsWith(Prefix, StringComparison.InvariantCultureIgnoreCase))
                {
                    int EqualsIdx = Param.IndexOf('=');
                    if (EqualsIdx >= 0)
                    {
                        Arguments[Param.Substring(Prefix.Length, EqualsIdx - Prefix.Length)] = Param.Substring(EqualsIdx + 1);
                    }
                    else
                    {
                        LogWarning("Missing value for '{0}'", Param.Substring(Prefix.Length));
                    }
                }
            }

            // Find all the tasks from the loaded assemblies
            Dictionary <string, ScriptTask> NameToTask = new Dictionary <string, ScriptTask>();

            if (!FindAvailableTasks(NameToTask, bPublicTasksOnly))
            {
                return(ExitCode.Error_Unknown);
            }

            // Generate documentation
            if (DocumentationFileName != null)
            {
                GenerateDocumentation(NameToTask, new FileReference(DocumentationFileName));
                return(ExitCode.Success);
            }

            // Create a schema for the given tasks
            ScriptSchema Schema = new ScriptSchema(NameToTask);

            if (SchemaFileName != null)
            {
                FileReference FullSchemaFileName = new FileReference(SchemaFileName);
                LogInformation("Writing schema to {0}...", FullSchemaFileName.FullName);
                Schema.Export(FullSchemaFileName);
                if (ScriptFileName == null)
                {
                    return(ExitCode.Success);
                }
            }

            // Check there was a script specified
            if (ScriptFileName == null)
            {
                LogError("Missing -Script= parameter for BuildGraph");
                return(ExitCode.Error_Unknown);
            }

            // Read the script from disk
            Graph Graph;

            if (!ScriptReader.TryRead(new FileReference(ScriptFileName), Arguments, DefaultProperties, Schema, out Graph))
            {
                return(ExitCode.Error_Unknown);
            }

            // Create the temp storage handler
            DirectoryReference RootDir = new DirectoryReference(CommandUtils.CmdEnv.LocalRoot);
            TempStorage        Storage = new TempStorage(RootDir, DirectoryReference.Combine(RootDir, "Engine", "Saved", "BuildGraph"), (SharedStorageDir == null)? null : new DirectoryReference(SharedStorageDir), bWriteToSharedStorage);

            if (!bResume)
            {
                Storage.CleanLocal();
            }
            foreach (string CleanNode in CleanNodes)
            {
                Storage.CleanLocalNode(CleanNode);
            }

            // Convert the supplied target references into nodes
            HashSet <Node> TargetNodes = new HashSet <Node>();

            if (TargetNames == null)
            {
                if (!bListOnly)
                {
                    LogError("Missing -Target= parameter for BuildGraph");
                    return(ExitCode.Error_Unknown);
                }
                TargetNodes.UnionWith(Graph.Agents.SelectMany(x => x.Nodes));
            }
            else
            {
                foreach (string TargetName in TargetNames.Split(new char[] { '+', ';' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()))
                {
                    Node[] Nodes;
                    if (!Graph.TryResolveReference(TargetName, out Nodes))
                    {
                        LogError("Target '{0}' is not in graph", TargetName);
                        return(ExitCode.Error_Unknown);
                    }
                    TargetNodes.UnionWith(Nodes);
                }
            }

            // Try to acquire tokens for all the target nodes we want to build
            if (TokenSignature != null)
            {
                // Find all the lock files
                HashSet <FileReference> RequiredTokens = new HashSet <FileReference>(TargetNodes.SelectMany(x => x.RequiredTokens));

                // List out all the required tokens
                if (SingleNodeName == null)
                {
                    CommandUtils.LogInformation("Required tokens:");
                    foreach (Node Node in TargetNodes)
                    {
                        foreach (FileReference RequiredToken in Node.RequiredTokens)
                        {
                            CommandUtils.LogInformation("  '{0}' requires {1}", Node, RequiredToken);
                        }
                    }
                }

                // Try to create all the lock files
                List <FileReference> CreatedTokens = new List <FileReference>();
                if (!bListOnly)
                {
                    CreatedTokens.AddRange(RequiredTokens.Where(x => WriteTokenFile(x, TokenSignature)));
                }

                // Find all the tokens that we don't have
                Dictionary <FileReference, string> MissingTokens = new Dictionary <FileReference, string>();
                foreach (FileReference RequiredToken in RequiredTokens)
                {
                    string CurrentOwner = ReadTokenFile(RequiredToken);
                    if (CurrentOwner != null && CurrentOwner != TokenSignature)
                    {
                        MissingTokens.Add(RequiredToken, CurrentOwner);
                    }
                }

                // If we want to skip all the nodes with missing locks, adjust the target nodes to account for it
                if (MissingTokens.Count > 0)
                {
                    if (bSkipTargetsWithoutTokens)
                    {
                        // Find all the nodes we're going to skip
                        HashSet <Node> SkipNodes = new HashSet <Node>();
                        foreach (IGrouping <string, FileReference> MissingTokensForBuild in MissingTokens.GroupBy(x => x.Value, x => x.Key))
                        {
                            LogInformation("Skipping the following nodes due to {0}:", MissingTokensForBuild.Key);
                            foreach (FileReference MissingToken in MissingTokensForBuild)
                            {
                                foreach (Node SkipNode in TargetNodes.Where(x => x.RequiredTokens.Contains(MissingToken) && SkipNodes.Add(x)))
                                {
                                    LogInformation("    {0}", SkipNode);
                                }
                            }
                        }

                        // Write a list of everything left over
                        if (SkipNodes.Count > 0)
                        {
                            TargetNodes.ExceptWith(SkipNodes);
                            LogInformation("Remaining target nodes:");
                            foreach (Node TargetNode in TargetNodes)
                            {
                                LogInformation("    {0}", TargetNode);
                            }
                            if (TargetNodes.Count == 0)
                            {
                                LogInformation("    None.");
                            }
                        }
                    }
                    else
                    {
                        foreach (KeyValuePair <FileReference, string> Pair in MissingTokens)
                        {
                            List <Node> SkipNodes = TargetNodes.Where(x => x.RequiredTokens.Contains(Pair.Key)).ToList();
                            LogError("Cannot run {0} due to previous build: {1}", String.Join(", ", SkipNodes), Pair.Value);
                        }
                        foreach (FileReference CreatedToken in CreatedTokens)
                        {
                            FileReference.Delete(CreatedToken);
                        }
                        return(ExitCode.Error_Unknown);
                    }
                }
            }

            // Cull the graph to include only those nodes
            Graph.Select(TargetNodes);

            // Collapse any triggers in the graph which are marked to be skipped
            HashSet <ManualTrigger> SkipTriggers = new HashSet <ManualTrigger>();

            if (bSkipTriggers)
            {
                SkipTriggers.UnionWith(Graph.NameToTrigger.Values);
            }
            else
            {
                foreach (string SkipTriggerName in SkipTriggerNames)
                {
                    ManualTrigger SkipTrigger;
                    if (!Graph.NameToTrigger.TryGetValue(TriggerName, out SkipTrigger))
                    {
                        LogError("Couldn't find trigger '{0}'", TriggerName);
                        return(ExitCode.Error_Unknown);
                    }
                    SkipTriggers.Add(SkipTrigger);
                }
            }
            Graph.SkipTriggers(SkipTriggers);

            // If a report for the whole build was requested, insert it into the graph
            if (ReportName != null)
            {
                Report NewReport = new Report(ReportName);
                NewReport.Nodes.UnionWith(Graph.Agents.SelectMany(x => x.Nodes));
                Graph.NameToReport.Add(ReportName, NewReport);
            }

            // Write out the preprocessed script
            if (PreprocessedFileName != null)
            {
                FileReference PreprocessedFileLocation = new FileReference(PreprocessedFileName);
                LogInformation("Writing {0}...", PreprocessedFileLocation);
                Graph.Write(PreprocessedFileLocation, (SchemaFileName != null)? new FileReference(SchemaFileName) : null);
                return(ExitCode.Success);
            }

            // Find the triggers which we are explicitly running.
            ManualTrigger Trigger = null;

            if (TriggerName != null && !Graph.NameToTrigger.TryGetValue(TriggerName, out Trigger))
            {
                LogError("Couldn't find trigger '{0}'", TriggerName);
                return(ExitCode.Error_Unknown);
            }

            // If we're just building a single node, find it
            Node SingleNode = null;

            if (SingleNodeName != null && !Graph.NameToNode.TryGetValue(SingleNodeName, out SingleNode))
            {
                LogError("Node '{0}' is not in the trimmed graph", SingleNodeName);
                return(ExitCode.Error_Unknown);
            }

            // If we just want to show the contents of the graph, do so and exit.
            if (bListOnly)
            {
                HashSet <Node> CompletedNodes = FindCompletedNodes(Graph, Storage);
                Graph.Print(CompletedNodes, PrintOptions);
            }

            // Print out all the diagnostic messages which still apply, unless we're running a step as part of a build system or just listing the contents of the file.
            if (SingleNode == null && (!bListOnly || bShowDiagnostics))
            {
                IEnumerable <GraphDiagnostic> Diagnostics = Graph.Diagnostics.Where(x => x.EnclosingTrigger == Trigger);
                foreach (GraphDiagnostic Diagnostic in Diagnostics)
                {
                    if (Diagnostic.EventType == LogEventType.Console)
                    {
                        CommandUtils.LogInformation(Diagnostic.Message);
                    }
                    else if (Diagnostic.EventType == LogEventType.Warning)
                    {
                        CommandUtils.LogWarning(Diagnostic.Message);
                    }
                    else
                    {
                        CommandUtils.LogError(Diagnostic.Message);
                    }
                }
                if (Diagnostics.Any(x => x.EventType == LogEventType.Error))
                {
                    return(ExitCode.Error_Unknown);
                }
            }

            // Export the graph to a file
            if (ExportFileName != null)
            {
                HashSet <Node> CompletedNodes = FindCompletedNodes(Graph, Storage);
                Graph.Print(CompletedNodes, PrintOptions);
                Graph.Export(new FileReference(ExportFileName), Trigger, CompletedNodes);
                return(ExitCode.Success);
            }

            // Execute the command
            if (!bListOnly)
            {
                if (SingleNode != null)
                {
                    if (!BuildNode(new JobContext(this), Graph, SingleNode, Storage, bWithBanner: true))
                    {
                        return(ExitCode.Error_Unknown);
                    }
                }
                else
                {
                    if (!BuildAllNodes(new JobContext(this), Graph, Storage))
                    {
                        return(ExitCode.Error_Unknown);
                    }
                }
            }
            return(ExitCode.Success);
        }
        /// <summary>
        /// Runs Cook commandlet.
        /// </summary>
        /// <param name="ProjectName">Project name.</param>
        /// <param name="UE4Exe">The name of the UE4 Editor executable to use.</param>
        /// <param name="Maps">List of maps to cook, can be null in which case -MapIniSection=AllMaps is used.</param>
        /// <param name="Dirs">List of directories to cook, can be null</param>
        /// <param name="InternationalizationPreset">The name of a prebuilt set of internationalization data to be included.</param>
        /// <param name="CulturesToCook">List of culture names whose localized assets should be cooked, can be null (implying defaults should be used).</param>
        /// <param name="TargetPlatform">Target platform.</param>
        /// <param name="Parameters">List of additional parameters.</param>
        public static void CookCommandlet(FileReference ProjectName, string UE4Exe = "UE4Editor-Cmd.exe", string[] Maps = null, string[] Dirs = null, string InternationalizationPreset = "", string[] CulturesToCook = null, string TargetPlatform = "WindowsNoEditor", string Parameters = "-Unversioned")
        {
            string CommandletArguments = "";

            if (IsNullOrEmpty(Maps))
            {
                // MapsToCook = "-MapIniSection=AllMaps";
            }
            else
            {
                string MapsToCookArg = "-Map=" + CombineCommandletParams(Maps).Trim();
                CommandletArguments += (CommandletArguments.Length > 0 ? " " : "") + MapsToCookArg;
            }

            if (!IsNullOrEmpty(Dirs))
            {
                foreach (string Dir in Dirs)
                {
                    CommandletArguments += (CommandletArguments.Length > 0 ? " " : "") + String.Format("-CookDir={0}", CommandUtils.MakePathSafeToUseWithCommandLine(Dir));
                }
            }

            if (!String.IsNullOrEmpty(InternationalizationPreset))
            {
                CommandletArguments += (CommandletArguments.Length > 0 ? " " : "") + InternationalizationPreset;
            }

            if (!IsNullOrEmpty(CulturesToCook))
            {
                string CulturesToCookArg = "-CookCultures=" + CombineCommandletParams(CulturesToCook).Trim();
                CommandletArguments += (CommandletArguments.Length > 0 ? " " : "") + CulturesToCookArg;
            }

            RunCommandlet(ProjectName, UE4Exe, "Cook", String.Format("{0} -TargetPlatform={1} {2}", CommandletArguments, TargetPlatform, Parameters));
        }
Exemple #32
0
        /// <summary>
        /// Print the contents of the graph
        /// </summary>
        /// <param name="CompletedNodes">Set of nodes which are already complete</param>
        /// <param name="PrintOptions">Options for how to print the graph</param>
        public void Print(HashSet <Node> CompletedNodes, GraphPrintOptions PrintOptions)
        {
            // Print the options
            if ((PrintOptions & GraphPrintOptions.ShowCommandLineOptions) != 0)
            {
                // Get the list of messages
                List <string> Messages = new List <string>();
                foreach (GraphOption Option in Options)
                {
                    StringBuilder Message = new StringBuilder();
                    Message.AppendFormat("-set:{0}=... {1}", Option.Name, Option.Description);
                    if (!String.IsNullOrEmpty(Option.DefaultValue))
                    {
                        Message.AppendFormat(" (Default: {0})", Option.DefaultValue);
                    }
                    Messages.Add(Message.ToString());
                }

                // Format them to the log
                if (Messages.Count > 0)
                {
                    CommandUtils.Log("");
                    CommandUtils.Log("Options:");
                    CommandUtils.Log("");
                    foreach (string Line in CommandUtils.FormatParams(Messages, 4, 24))
                    {
                        CommandUtils.Log(Line);
                    }
                }
            }

            // Get a list of all the triggers, including the null global one
            List <ManualTrigger> AllTriggers = new List <ManualTrigger>();

            AllTriggers.Add(null);
            AllTriggers.AddRange(NameToTrigger.Values.OrderBy(x => x.QualifiedName));

            // Output all the triggers in order
            CommandUtils.Log("");
            CommandUtils.Log("Graph:");
            foreach (ManualTrigger Trigger in AllTriggers)
            {
                // Filter everything by this trigger
                Dictionary <Agent, Node[]> FilteredAgentToNodes = new Dictionary <Agent, Node[]>();
                foreach (Agent Agent in Agents)
                {
                    Node[] Nodes = Agent.Nodes.Where(x => x.ControllingTrigger == Trigger).ToArray();
                    if (Nodes.Length > 0)
                    {
                        FilteredAgentToNodes[Agent] = Nodes;
                    }
                }

                // Skip this trigger if there's nothing to display
                if (FilteredAgentToNodes.Count == 0)
                {
                    continue;
                }

                // Print the trigger name
                CommandUtils.Log("    Trigger: {0}", (Trigger == null)? "None" : Trigger.QualifiedName);
                if (Trigger != null && PrintOptions.HasFlag(GraphPrintOptions.ShowNotifications))
                {
                    foreach (string User in Trigger.NotifyUsers)
                    {
                        CommandUtils.Log("            notify> {0}", User);
                    }
                }

                // Output all the agents for this trigger
                foreach (Agent Agent in Agents)
                {
                    Node[] Nodes;
                    if (FilteredAgentToNodes.TryGetValue(Agent, out Nodes))
                    {
                        CommandUtils.Log("        Agent: {0} ({1})", Agent.Name, String.Join(";", Agent.PossibleTypes));
                        foreach (Node Node in Nodes)
                        {
                            CommandUtils.Log("            Node: {0}{1}", Node.Name, CompletedNodes.Contains(Node)? " (completed)" : "");
                            if (PrintOptions.HasFlag(GraphPrintOptions.ShowDependencies))
                            {
                                HashSet <Node> InputDependencies = new HashSet <Node>(Node.GetDirectInputDependencies());
                                foreach (Node InputDependency in InputDependencies)
                                {
                                    CommandUtils.Log("                input> {0}", InputDependency.Name);
                                }
                                HashSet <Node> OrderDependencies = new HashSet <Node>(Node.GetDirectOrderDependencies());
                                foreach (Node OrderDependency in OrderDependencies.Except(InputDependencies))
                                {
                                    CommandUtils.Log("                after> {0}", OrderDependency.Name);
                                }
                            }
                            if (PrintOptions.HasFlag(GraphPrintOptions.ShowNotifications))
                            {
                                string Label = Node.bNotifyOnWarnings? "warnings" : "errors";
                                foreach (string User in Node.NotifyUsers)
                                {
                                    CommandUtils.Log("                {0}> {1}", Label, User);
                                }
                                foreach (string Submitter in Node.NotifySubmitters)
                                {
                                    CommandUtils.Log("                {0}> submitters to {1}", Label, Submitter);
                                }
                            }
                        }
                    }
                }
            }
            CommandUtils.Log("");

            // Print out all the aggregates
            string[] AggregateNames = AggregateNameToNodes.Keys.OrderBy(x => x).ToArray();
            if (AggregateNames.Length > 0)
            {
                CommandUtils.Log("Aggregates:");
                foreach (string AggregateName in AggregateNames)
                {
                    CommandUtils.Log("    {0}", AggregateName);
                }
                CommandUtils.Log("");
            }
        }
 public override void SetupOptionsForRun(ref string AppName, ref CommandUtils.ERunOptions Options, ref string CommandLine)
 {
 }
Exemple #34
0
        /// <summary>
        /// Parses command line parameter.
        /// </summary>
        /// <param name="ParamIndex">Parameter index</param>
        /// <param name="CommandLine">Command line</param>
        /// <param name="CurrentCommand">Recently parsed command</param>
        /// <param name="OutScriptsForProjectFileName">The only project to build scripts for</param>
        /// <param name="OutAdditionalScriptsFolders">Additional script locations</param>
        /// <returns>True if the parameter has been successfully parsed.</returns>
        private static void ParseParam(string CurrentParam, CommandInfo CurrentCommand, ref string OutScriptsForProjectFileName, List <string> OutAdditionalScriptsFolders)
        {
            bool bGlobalParam = false;

            foreach (var RegisteredParam in GlobalCommandLine.RegisteredArgs)
            {
                if (String.Compare(CurrentParam, RegisteredParam.Key, StringComparison.InvariantCultureIgnoreCase) == 0)
                {
                    // Register and exit, we're done here.
                    RegisteredParam.Value.Set();
                    bGlobalParam = true;
                    break;
                }
            }

            // The parameter was not found in the list of global parameters, continue looking...
            if (CurrentParam.StartsWith("-ScriptsForProject=", StringComparison.InvariantCultureIgnoreCase))
            {
                if (OutScriptsForProjectFileName != null)
                {
                    throw new AutomationException("The -ProjectScripts argument may only be specified once");
                }
                var ProjectFileName = CurrentParam.Substring(CurrentParam.IndexOf('=') + 1).Replace("\"", "");
                if (!File.Exists(ProjectFileName))
                {
                    throw new AutomationException("Project '{0}' does not exist", ProjectFileName);
                }
                OutScriptsForProjectFileName = Path.GetFullPath(ProjectFileName);
            }
            else if (CurrentParam.StartsWith("-ScriptDir=", StringComparison.InvariantCultureIgnoreCase))
            {
                var ScriptDir = CurrentParam.Substring(CurrentParam.IndexOf('=') + 1);
                if (Directory.Exists(ScriptDir))
                {
                    OutAdditionalScriptsFolders.Add(ScriptDir);
                    Log.TraceVerbose("Found additional script dir: {0}", ScriptDir);
                }
                else
                {
                    throw new AutomationException("Specified ScriptDir doesn't exist: {0}", ScriptDir);
                }
            }
            else if (CurrentParam.StartsWith("-"))
            {
                if (CurrentCommand != null)
                {
                    CurrentCommand.Arguments.Add(CurrentParam.Substring(1));
                }
                else if (!bGlobalParam)
                {
                    throw new AutomationException("Unknown parameter {0} in the command line that does not belong to any command.", CurrentParam);
                }
            }
            else if (CurrentParam.Contains("="))
            {
                // Environment variable
                int    ValueStartIndex = CurrentParam.IndexOf('=') + 1;
                string EnvVarName      = CurrentParam.Substring(0, ValueStartIndex - 1);
                if (String.IsNullOrEmpty(EnvVarName))
                {
                    throw new AutomationException("Unable to parse environment variable that has no name. Error when parsing command line param {0}", CurrentParam);
                }
                string EnvVarValue = CurrentParam.Substring(ValueStartIndex);
                CommandUtils.SetEnvVar(EnvVarName, EnvVarValue);
            }
        }
Exemple #35
0
 /// <summary>
 /// Gets a parameter value from the command line if it hasn't been specified in the constructor. 
 /// If the command line is not available, default value will be used.
 /// </summary>
 /// <param name="Command">Command to parse the command line for. Can be null.</param>
 /// <param name="SpecifiedValue">Value specified in the constructor (or not)</param>
 /// <param name="ParamName">Command line parameter name to parse.</param>
 /// <param name="Default">Default value</param>
 /// <returns>Parameter value.</returns>
 string ParseParamValueIfNotSpecified(CommandUtils Command, string SpecifiedValue, string ParamName, string Default = "")
 {
     if (SpecifiedValue != null)
     {
         return SpecifiedValue;
     }
     else if (Command != null)
     {
         return Command.ParseParamValue(ParamName, Default);
     }
     else
     {
         return Default;
     }
 }
Exemple #36
0
        /// <summary>
        /// Main method.
        /// </summary>
        /// <param name="Arguments">Command line</param>
        public static ExitCode Process(string[] Arguments, StartupTraceListener StartupListener)
        {
            // Initial check for local or build machine runs BEFORE we parse the command line (We need this value set
            // in case something throws the exception while parsing the command line)
            IsBuildMachine = !String.IsNullOrEmpty(Environment.GetEnvironmentVariable("uebp_LOCAL_ROOT")) || Arguments.Any(x => x.Equals("-BuildMachine", StringComparison.InvariantCultureIgnoreCase));

            // Scan the command line for commands to execute.
            var    CommandsToExecute = new List <CommandInfo>();
            string OutScriptsForProjectFileName;
            var    AdditionalScriptsFolders = new List <string>();

            ParseCommandLine(Arguments, CommandsToExecute, out OutScriptsForProjectFileName, AdditionalScriptsFolders);

            // Get the path to the telemetry file, if present
            string TelemetryFile = CommandUtils.ParseParamValue(Arguments, "-Telemetry");

            Log.TraceVerbose("IsBuildMachine={0}", IsBuildMachine);
            Environment.SetEnvironmentVariable("IsBuildMachine", IsBuildMachine ? "1" : "0");

            // should we kill processes on exit
            ShouldKillProcesses = !GlobalCommandLine.NoKill;
            Log.TraceVerbose("ShouldKillProcesses={0}", ShouldKillProcesses);

            if (CommandsToExecute.Count == 0 && GlobalCommandLine.Help)
            {
                DisplayHelp();
                return(ExitCode.Success);
            }

            // Disable AutoSDKs if specified on the command line
            if (GlobalCommandLine.NoAutoSDK)
            {
                PlatformExports.PreventAutoSDKSwitching();
            }

            // Setup environment
            Log.TraceLog("Setting up command environment.");
            CommandUtils.InitCommandEnvironment();

            // Determine if the engine is installed
            bIsEngineInstalled = GlobalCommandLine.Installed;
            string InstalledBuildFile = Path.Combine(CommandUtils.CmdEnv.LocalRoot, "Engine", "Build", "InstalledBuild.txt");

            bIsEngineInstalled |= File.Exists(InstalledBuildFile);
            if (bIsEngineInstalled.Value)
            {
                bIsEngineInstalled = !GlobalCommandLine.NotInstalledEngine;
            }
            else
            {
                bIsEngineInstalled = GlobalCommandLine.InstalledEngine;
            }

            // Create the log file, and flush the startup listener to it
            TraceListener LogTraceListener = LogUtils.AddLogFileListener(CommandUtils.CmdEnv.LogFolder, CommandUtils.CmdEnv.FinalLogFolder);

            StartupListener.CopyTo(LogTraceListener);
            Trace.Listeners.Remove(StartupListener);

            // Initialize UBT
            if (!UnrealBuildTool.PlatformExports.Initialize(bIsEngineInstalled.Value))
            {
                Log.TraceInformation("Failed to initialize UBT");
                return(ExitCode.Error_Unknown);
            }

            // Fill in the project info
            UnrealBuildTool.UProjectInfo.FillProjectInfo();

            // Clean rules folders up
            ProjectUtils.CleanupFolders();

            // Compile scripts.
            ScriptCompiler Compiler = new ScriptCompiler();

            using (TelemetryStopwatch ScriptCompileStopwatch = new TelemetryStopwatch("ScriptCompile"))
            {
                Compiler.FindAndCompileAllScripts(OutScriptsForProjectFileName, AdditionalScriptsFolders);
            }

            if (GlobalCommandLine.CompileOnly)
            {
                Log.TraceInformation("Compilation successful, exiting (CompileOnly)");
                return(ExitCode.Success);
            }

            if (GlobalCommandLine.List)
            {
                ListAvailableCommands(Compiler.Commands);
                return(ExitCode.Success);
            }

            if (GlobalCommandLine.Help)
            {
                DisplayHelp(CommandsToExecute, Compiler.Commands);
                return(ExitCode.Success);
            }

            // Enable or disable P4 support
            CommandUtils.InitP4Support(CommandsToExecute, Compiler.Commands);
            if (CommandUtils.P4Enabled)
            {
                Log.TraceLog("Setting up Perforce environment.");
                CommandUtils.InitP4Environment();
                CommandUtils.InitDefaultP4Connection();
            }

            // Find and execute commands.
            ExitCode Result = Execute(CommandsToExecute, Compiler.Commands);

            if (TelemetryFile != null)
            {
                Directory.CreateDirectory(Path.GetDirectoryName(TelemetryFile));
                CommandUtils.Telemetry.Write(TelemetryFile);
            }
            return(Result);
        }
Exemple #37
0
		/// <summary>
		/// Sets up platforms
		/// </summary>
        /// <param name="DependentPlatformMap">Set with a mapping from source->destination if specified on command line</param>
		/// <param name="Command">The command line to parse</param>
		/// <param name="OverrideTargetPlatforms">If passed use this always</param>
        /// <param name="DefaultTargetPlatforms">Use this if nothing is passed on command line</param>
		/// <param name="AllowPlatformParams">Allow raw -platform options</param>
		/// <param name="PlatformParamNames">Possible -parameters to check for</param>
		/// <returns>List of platforms parsed from the command line</returns>
		private List<UnrealTargetPlatform> SetupTargetPlatforms(ref Dictionary<UnrealTargetPlatform,UnrealTargetPlatform> DependentPlatformMap, CommandUtils Command, List<UnrealTargetPlatform> OverrideTargetPlatforms, List<UnrealTargetPlatform> DefaultTargetPlatforms, bool AllowPlatformParams, params string[] PlatformParamNames)
		{
			List<UnrealTargetPlatform> TargetPlatforms = null;
			if (CommandUtils.IsNullOrEmpty(OverrideTargetPlatforms))
			{
				if (Command != null)
				{
					// Parse the command line, we support the following params:
					// -'PlatformParamNames[n]'=Platform_1+Platform_2+...+Platform_k
					// or (if AllowPlatformParams is true)
					// -Platform_1 -Platform_2 ... -Platform_k
					string CmdLinePlatform = null;
					foreach (var ParamName in PlatformParamNames)
					{
						CmdLinePlatform = Command.ParseParamValue(ParamName);
						if (!String.IsNullOrEmpty(CmdLinePlatform))
						{
							break;
						}
					}

					if (!String.IsNullOrEmpty(CmdLinePlatform))
					{
						// Get all platforms from the param value: Platform_1+Platform_2+...+Platform_k
						TargetPlatforms = new List<UnrealTargetPlatform>();
						var Platforms = new List<string>(CmdLinePlatform.Split('+'));
						foreach (var PlatformName in Platforms)
						{
                            // Look for dependent platforms, Source_1.Dependent_1+Source_2.Dependent_2+Standalone_3
                            var SubPlatforms = new List<string>(PlatformName.Split('.'));

                            foreach (var SubPlatformName in SubPlatforms)
                            {
                                UnrealTargetPlatform NewPlatform = (UnrealTargetPlatform)Enum.Parse(typeof(UnrealTargetPlatform), SubPlatformName, true);
                                TargetPlatforms.Add(NewPlatform);

                                if (SubPlatformName != SubPlatforms[0])
                                {
                                    // We're a dependent platform so add ourselves to the map, pointing to the first element in the list
                                    DependentPlatformMap.Add(NewPlatform, (UnrealTargetPlatform)Enum.Parse(typeof(UnrealTargetPlatform), SubPlatforms[0], true));
                                }
                            }
						}
					}
					else if (AllowPlatformParams)
					{
						// Look up platform names in the command line: -Platform_1 -Platform_2 ... -Platform_k
						TargetPlatforms = new List<UnrealTargetPlatform>();
						foreach (var Plat in CommandUtils.KnownTargetPlatforms)
						{
							if (Command.ParseParam(Plat.ToString()))
							{
								TargetPlatforms.Add(Plat);
							}
						}
					}
				}
			}
			else
			{
				TargetPlatforms = OverrideTargetPlatforms;
			}
			if (CommandUtils.IsNullOrEmpty(TargetPlatforms))
			{
				// Revert to single default platform - the current platform we're running
				TargetPlatforms = DefaultTargetPlatforms;
			}
			return TargetPlatforms;
		}
Exemple #38
0
 /// <summary>
 /// Display AutomationTool.exe help.
 /// </summary>
 private static void DisplayHelp()
 {
     CommandUtils.LogHelp(typeof(Automation));
 }
		/// <summary>
		/// Sets up platforms
		/// </summary>
        /// <param name="DependentPlatformMap">Set with a mapping from source->destination if specified on command line</param>
		/// <param name="Command">The command line to parse</param>
		/// <param name="OverrideTargetPlatforms">If passed use this always</param>
        /// <param name="DefaultTargetPlatforms">Use this if nothing is passed on command line</param>
		/// <param name="AllowPlatformParams">Allow raw -platform options</param>
		/// <param name="PlatformParamNames">Possible -parameters to check for</param>
		/// <returns>List of platforms parsed from the command line</returns>
		private List<TargetPlatformDescriptor> SetupTargetPlatforms(ref Dictionary<TargetPlatformDescriptor, TargetPlatformDescriptor> DependentPlatformMap, CommandUtils Command, List<TargetPlatformDescriptor> OverrideTargetPlatforms, List<TargetPlatformDescriptor> DefaultTargetPlatforms, bool AllowPlatformParams, params string[] PlatformParamNames)
		{
			List<TargetPlatformDescriptor> TargetPlatforms = null;
			if (CommandUtils.IsNullOrEmpty(OverrideTargetPlatforms))
			{
				if (Command != null)
				{
					// Parse the command line, we support the following params:
					// -'PlatformParamNames[n]'=Platform_1+Platform_2+...+Platform_k
					// or (if AllowPlatformParams is true)
					// -Platform_1 -Platform_2 ... -Platform_k
					string CmdLinePlatform = null;
					foreach (var ParamName in PlatformParamNames)
					{
						CmdLinePlatform = Command.ParseParamValue(ParamName);
						if (!String.IsNullOrEmpty(CmdLinePlatform))
						{
							break;
						}
					}

                    List<string> CookFlavors = null;
                    {
                        string CmdLineCookFlavor = Command.ParseParamValue("cookflavor");
                        if (!String.IsNullOrEmpty(CmdLineCookFlavor))
                        {
                            CookFlavors = new List<string>(CmdLineCookFlavor.Split('+'));
                        }
                    }

                    if (!String.IsNullOrEmpty(CmdLinePlatform))
					{
						// Get all platforms from the param value: Platform_1+Platform_2+...+Platform_k
						TargetPlatforms = new List<TargetPlatformDescriptor>();
						var PlatformNames = new List<string>(CmdLinePlatform.Split('+'));
						foreach (var PlatformName in PlatformNames)
						{
                            // Look for dependent platforms, Source_1.Dependent_1+Source_2.Dependent_2+Standalone_3
                            var SubPlatformNames = new List<string>(PlatformName.Split('.'));

                            foreach (var SubPlatformName in SubPlatformNames)
                            {
                                UnrealTargetPlatform NewPlatformType = (UnrealTargetPlatform)Enum.Parse(typeof(UnrealTargetPlatform), SubPlatformName, true);
                                // generate all valid platform descriptions for this platform type + cook flavors
                                List<TargetPlatformDescriptor> PlatformDescriptors = Platform.GetValidTargetPlatforms(NewPlatformType, CookFlavors);
                                TargetPlatforms.AddRange(PlatformDescriptors);
                                                              
                                if (SubPlatformName != SubPlatformNames[0])
                                {
                                    // This is not supported with cook flavors
                                    if (!CommandUtils.IsNullOrEmpty(CookFlavors))
                                    {
                                        throw new AutomationException("Cook flavors are not supported for dependent platforms!");
                                    }

                                    // We're a dependent platform so add ourselves to the map, pointing to the first element in the list
                                    UnrealTargetPlatform FirstPlatformType = (UnrealTargetPlatform)Enum.Parse(typeof(UnrealTargetPlatform), SubPlatformNames[0], true);
                                    DependentPlatformMap.Add(new TargetPlatformDescriptor(NewPlatformType), new TargetPlatformDescriptor(FirstPlatformType));
                                }
                            }
						}
					}
					else if (AllowPlatformParams)
					{
						// Look up platform names in the command line: -Platform_1 -Platform_2 ... -Platform_k
						TargetPlatforms = new List<TargetPlatformDescriptor>();
						foreach (UnrealTargetPlatform PlatType in Enum.GetValues(typeof(UnrealTargetPlatform)))
						{
							if (PlatType != UnrealTargetPlatform.Unknown)
							{
								if (Command.ParseParam(PlatType.ToString()))
								{
                                    List<TargetPlatformDescriptor> PlatformDescriptors = Platform.GetValidTargetPlatforms(PlatType, CookFlavors);
                                    TargetPlatforms.AddRange(PlatformDescriptors);
								}
							}
						}
					}
				}
			}
			else
			{
				TargetPlatforms = OverrideTargetPlatforms;
			}
			if (CommandUtils.IsNullOrEmpty(TargetPlatforms))
			{
				// Revert to single default platform - the current platform we're running
				TargetPlatforms = DefaultTargetPlatforms;
			}
			return TargetPlatforms;
		}
Exemple #40
0
        /// <summary>
        /// Runs UBT with the specified commandline. Automatically creates a logfile. When
        /// no LogName is specified, the executable name is used as logfile base name.
        /// </summary>
        /// <param name="Env">Environment to use.</param>
        /// <param name="CommandLine">Commandline to pass on to UBT.</param>
        /// <param name="LogName">Optional logfile name.</param>
        public static void RunUBT(CommandEnvironment Env, string UBTExecutable, string CommandLine)
        {
            if (!FileExists(UBTExecutable))
            {
                throw new AutomationException("Unable to find UBT executable: " + UBTExecutable);
            }

            if (GlobalCommandLine.VS2015)
            {
                CommandLine += " -2015";
            }
            if (!IsBuildMachine && UnrealBuildTool.BuildHostPlatform.Current.Platform == UnrealBuildTool.UnrealTargetPlatform.Mac)
            {
                CommandLine += " -nocreatestub";
            }
            CommandLine += " -NoHotReload";
            if (bJunkDeleted || GlobalCommandLine.IgnoreJunk)
            {
                // UBT has already deleted junk files, make sure it doesn't do it again
                CommandLine += " -ignorejunk";
            }
            else
            {
                // UBT will delete junk on first run
                bJunkDeleted = true;
            }

            string BaseLogName = String.Format("UBT-{0}", String.Join("-", SharedUtils.ParseCommandLine(CommandLine).Where(x => !x.Contains('/') && !x.Contains('\\') && !x.StartsWith("-"))));
            string LogName;

            for (int Attempt = 1;; Attempt++)
            {
                LogName = String.Format("{0}.txt", (Attempt == 1)? BaseLogName : String.Format("{0}_{1}", BaseLogName, Attempt));

                FileReference LogLocation = FileReference.Combine(new DirectoryReference(Env.LogFolder), LogName);
                if (!FileReference.Exists(LogLocation))
                {
                    CommandLine += String.Format(" -log=\"{0}\"", LogLocation);
                    break;
                }

                if (Attempt >= 50)
                {
                    throw new AutomationException("Unable to find name for UBT log file after {0} attempts", Attempt);
                }
            }

            IProcessResult Result = Run(UBTExecutable, CommandLine, Options: ERunOptions.AllowSpew | ERunOptions.NoStdOutCapture);

            if (Result.ExitCode != 0)
            {
                throw new AutomationException((ExitCode)Result.ExitCode, "UnrealBuildTool failed. See log for more details. ({0})", CommandUtils.CombinePaths(Env.FinalLogFolder, LogName));
            }
        }
		/// <summary>
		/// Constructor. Be sure to use this.ParamName to set the actual property name as parameter names and property names
		/// overlap here.
		/// If a parameter value is not set, it will be parsed from the command line; if the command is null, the default value will be used.
		/// </summary>
		public ProjectParams(			
			FileReference RawProjectPath,

			CommandUtils Command = null,
			string Device = null,			
			string MapToRun = null,	
			string AdditionalServerMapParams = null,
			ParamList<string> Port = null,
			string RunCommandline = null,						
			string StageCommandline = null,
            string BundleName = null,
            string StageDirectoryParam = null,
			string UE4Exe = null,
			string SignPak = null,
			List<UnrealTargetConfiguration> ClientConfigsToBuild = null,
			List<UnrealTargetConfiguration> ServerConfigsToBuild = null,
			ParamList<string> MapsToCook = null,
			ParamList<string> DirectoriesToCook = null,
            string InternationalizationPreset = null,
            ParamList<string> CulturesToCook = null,
			ParamList<string> ClientCookedTargets = null,
			ParamList<string> EditorTargets = null,
			ParamList<string> ServerCookedTargets = null,
			List<TargetPlatformDescriptor> ClientTargetPlatforms = null,
            Dictionary<TargetPlatformDescriptor, TargetPlatformDescriptor> ClientDependentPlatformMap = null,
			List<TargetPlatformDescriptor> ServerTargetPlatforms = null,
            Dictionary<TargetPlatformDescriptor, TargetPlatformDescriptor> ServerDependentPlatformMap = null,
			bool? Build = null,
			bool? Cook = null,
			bool? Run = null,
			bool? SkipServer = null,
			bool? Clean = null,
            bool? Compressed = null,
            bool? UseDebugParamForEditorExe = null,
            bool? IterativeCooking = null,
            bool? CookAll = null,
			bool? CookPartialGC = null,
            bool? CookMapsOnly = null,
            bool? CookOnTheFly = null,
            bool? CookOnTheFlyStreaming = null,
            bool? UnversionedCookedContent = null,
			bool? EncryptIniFiles = null,
            bool? SkipCookingEditorContent = null,
            int? NumCookersToSpawn = null,
            string AdditionalCookerOptions = null,
            string BasedOnReleaseVersion = null,
            string CreateReleaseVersion = null,
			string CreateReleaseVersionBasePath = null,
			string BasedOnReleaseVersionBasePath = null,
            bool? GeneratePatch = null,
            string DLCName = null,
            string DiffCookedContentPath = null,
            bool? DLCIncludeEngineContent = null,
            bool? NewCook = null,
            bool? OldCook = null,
			bool? CrashReporter = null,
			bool? DedicatedServer = null,
			bool? Client = null,
			bool? Deploy = null,
			bool? FileServer = null,
			bool? Foreign = null,
			bool? ForeignCode = null,
			bool? LogWindow = null,
			bool? NoCleanStage = null,
			bool? NoClient = null,
			bool? NoDebugInfo = null,
			bool? NoXGE = null,
			bool? Package = null,
			bool? Pak = null,
			bool? Prereqs = null,
			string AppLocalDirectory = null,
			bool? NoBootstrapExe = null,
            bool? SignedPak = null,
            bool? NullRHI = null,
            bool? FakeClient = null,
            bool? EditorTest = null,
            bool? RunAutomationTests = null,
            string RunAutomationTest = null,
            int? CrashIndex = null,
			bool? SkipCook = null,
			bool? SkipCookOnTheFly = null,
			bool? SkipPak = null,
			bool? SkipStage = null,
			bool? Stage = null,
			bool? Manifests = null,
            bool? CreateChunkInstall = null,
			bool? Unattended = null,
			int? NumClients = null,
			bool? Archive = null,
			string ArchiveDirectoryParam = null,
			bool? ArchiveMetaData = null,
			bool? CreateAppBundle = null,
			ParamList<string> ProgramTargets = null,
			bool? Distribution = null,
            bool? Prebuilt = null,
            int? RunTimeoutSeconds = null,
			string SpecifiedArchitecture = null,
            bool? IterativeDeploy = null,
			bool? FastCook = null,
			bool? IgnoreCookErrors = null,
            bool? RunAssetNativization = null,
			bool? CodeSign = null,
			bool? TreatNonShippingBinariesAsDebugFiles = null,
			string Provision = null,
			string Certificate = null,
			ParamList<string> InMapsToRebuildLightMaps = null,
			ParamList<string> TitleID = null
			)
		{
			//
			//// Use this.Name with properties and fields!
			//

			this.RawProjectPath = RawProjectPath;
			if (DirectoriesToCook != null)
			{
				this.DirectoriesToCook = DirectoriesToCook;
			}
            this.InternationalizationPreset = ParseParamValueIfNotSpecified(Command, InternationalizationPreset, "i18npreset");

            // If not specified in parameters, check commandline.
            if (CulturesToCook == null)
            {
                if (Command != null)
                {
                    var CookCulturesString = Command.ParseParamValue("CookCultures");
                    if (CookCulturesString != null)
                    {
                        this.CulturesToCook = new ParamList<string>(CookCulturesString.Split(','));
                    }
                }
            }
            else
            {
                this.CulturesToCook = CulturesToCook;
            }

			if (ClientCookedTargets != null)
			{
				this.ClientCookedTargets = ClientCookedTargets;
			}
			if (ServerCookedTargets != null)
			{
				this.ServerCookedTargets = ServerCookedTargets;
			}
			if (EditorTargets != null)
			{
				this.EditorTargets = EditorTargets;
			}
			if (ProgramTargets != null)
			{
				this.ProgramTargets = ProgramTargets;
			}

			// Parse command line params for client platforms "-TargetPlatform=Win64+Mac", "-Platform=Win64+Mac" and also "-Win64", "-Mac" etc.
            if (ClientDependentPlatformMap != null)
            {
                this.ClientDependentPlatformMap = ClientDependentPlatformMap;
            }

            List<TargetPlatformDescriptor> DefaultTargetPlatforms = new ParamList<TargetPlatformDescriptor>(new TargetPlatformDescriptor(HostPlatform.Current.HostEditorPlatform));
            this.ClientTargetPlatforms = SetupTargetPlatforms(ref this.ClientDependentPlatformMap, Command, ClientTargetPlatforms, DefaultTargetPlatforms, true, "TargetPlatform", "Platform");

            // Parse command line params for server platforms "-ServerTargetPlatform=Win64+Mac", "-ServerPlatform=Win64+Mac". "-Win64" etc is not allowed here
            if (ServerDependentPlatformMap != null)
            {
                this.ServerDependentPlatformMap = ServerDependentPlatformMap;
            }
            this.ServerTargetPlatforms = SetupTargetPlatforms(ref this.ServerDependentPlatformMap, Command, ServerTargetPlatforms, this.ClientTargetPlatforms, false, "ServerTargetPlatform", "ServerPlatform");

			this.Build = GetParamValueIfNotSpecified(Command, Build, this.Build, "build");
			this.Run = GetParamValueIfNotSpecified(Command, Run, this.Run, "run");
			this.Cook = GetParamValueIfNotSpecified(Command, Cook, this.Cook, "cook");
            this.NewCook = GetParamValueIfNotSpecified(Command, NewCook, this.NewCook, "NewCook");
            this.OldCook = GetParamValueIfNotSpecified(Command, OldCook, this.OldCook, "OldCook");
			this.CreateReleaseVersionBasePath = ParseParamValueIfNotSpecified(Command, CreateReleaseVersionBasePath, "createreleaseversionroot", String.Empty);
			this.BasedOnReleaseVersionBasePath = ParseParamValueIfNotSpecified(Command, BasedOnReleaseVersionBasePath, "basedonreleaseversionroot", String.Empty);
            this.CreateReleaseVersion = ParseParamValueIfNotSpecified(Command, CreateReleaseVersion, "createreleaseversion", String.Empty);
            this.BasedOnReleaseVersion = ParseParamValueIfNotSpecified(Command, BasedOnReleaseVersion, "basedonreleaseversion", String.Empty);
            this.GeneratePatch = GetParamValueIfNotSpecified(Command, GeneratePatch, this.GeneratePatch, "GeneratePatch");
            this.AdditionalCookerOptions = ParseParamValueIfNotSpecified(Command, AdditionalCookerOptions, "AdditionalCookerOptions", String.Empty);
            this.DLCName = ParseParamValueIfNotSpecified(Command, DLCName, "DLCName", String.Empty);
            this.DiffCookedContentPath = ParseParamValueIfNotSpecified(Command, DiffCookedContentPath, "DiffCookedContentPath", String.Empty);
            this.DLCIncludeEngineContent = GetParamValueIfNotSpecified(Command, DLCIncludeEngineContent, this.DLCIncludeEngineContent, "DLCIncludeEngineContent");
			this.SkipCook = GetParamValueIfNotSpecified(Command, SkipCook, this.SkipCook, "skipcook");
			if (this.SkipCook)
			{
				this.Cook = true;
			}
			this.Clean = GetOptionalParamValueIfNotSpecified(Command, Clean, this.Clean, "clean", null);
			this.SignPak = ParseParamValueIfNotSpecified(Command, SignPak, "signpak", String.Empty);
			this.SignedPak = !String.IsNullOrEmpty(this.SignPak) || GetParamValueIfNotSpecified(Command, SignedPak, this.SignedPak, "signedpak");
			if (string.IsNullOrEmpty(this.SignPak))
			{
				this.SignPak = Path.Combine(RawProjectPath.Directory.FullName, @"Build\NoRedist\Keys.txt");
				if (!File.Exists(this.SignPak))
				{
					this.SignPak = null;
				}
			}
			this.Pak = GetParamValueIfNotSpecified(Command, Pak, this.Pak, "pak");
			this.SkipPak = GetParamValueIfNotSpecified(Command, SkipPak, this.SkipPak, "skippak");
			if (this.SkipPak)
			{
				this.Pak = true;
			}
			this.NoXGE = GetParamValueIfNotSpecified(Command, NoXGE, this.NoXGE, "noxge");
			this.CookOnTheFly = GetParamValueIfNotSpecified(Command, CookOnTheFly, this.CookOnTheFly, "cookonthefly");
            if (this.CookOnTheFly && this.SkipCook)
            {
                this.Cook = false;
            }
            this.CookOnTheFlyStreaming = GetParamValueIfNotSpecified(Command, CookOnTheFlyStreaming, this.CookOnTheFlyStreaming, "cookontheflystreaming");
            this.UnversionedCookedContent = GetParamValueIfNotSpecified(Command, UnversionedCookedContent, this.UnversionedCookedContent, "UnversionedCookedContent");
			this.EncryptIniFiles = GetParamValueIfNotSpecified(Command, EncryptIniFiles, this.EncryptIniFiles, "EncryptIniFiles");
			this.SkipCookingEditorContent = GetParamValueIfNotSpecified(Command, SkipCookingEditorContent, this.SkipCookingEditorContent, "SkipCookingEditorContent");
            if (NumCookersToSpawn.HasValue)
            {
                this.NumCookersToSpawn = NumCookersToSpawn.Value;
            }
            else if (Command != null)
            {
                this.NumCookersToSpawn = Command.ParseParamInt("NumCookersToSpawn");
            }
            this.Compressed = GetParamValueIfNotSpecified(Command, Compressed, this.Compressed, "compressed");
            this.UseDebugParamForEditorExe = GetParamValueIfNotSpecified(Command, UseDebugParamForEditorExe, this.UseDebugParamForEditorExe, "UseDebugParamForEditorExe");
            this.IterativeCooking = GetParamValueIfNotSpecified(Command, IterativeCooking, this.IterativeCooking, new string[] { "iterativecooking", "iterate" } );
			this.SkipCookOnTheFly = GetParamValueIfNotSpecified(Command, SkipCookOnTheFly, this.SkipCookOnTheFly, "skipcookonthefly");
			this.CookAll = GetParamValueIfNotSpecified(Command, CookAll, this.CookAll, "CookAll");
			this.CookPartialGC = GetParamValueIfNotSpecified(Command, CookPartialGC, this.CookPartialGC, "CookPartialGC");
            this.CookMapsOnly = GetParamValueIfNotSpecified(Command, CookMapsOnly, this.CookMapsOnly, "CookMapsOnly");
			this.FileServer = GetParamValueIfNotSpecified(Command, FileServer, this.FileServer, "fileserver");
			this.DedicatedServer = GetParamValueIfNotSpecified(Command, DedicatedServer, this.DedicatedServer, "dedicatedserver", "server");
			this.Client = GetParamValueIfNotSpecified(Command, Client, this.Client, "client");
			/*if( this.Client )
			{
				this.DedicatedServer = true;
			}*/
			this.NoClient = GetParamValueIfNotSpecified(Command, NoClient, this.NoClient, "noclient");
			this.LogWindow = GetParamValueIfNotSpecified(Command, LogWindow, this.LogWindow, "logwindow");
			this.Stage = GetParamValueIfNotSpecified(Command, Stage, this.Stage, "stage");
			this.SkipStage = GetParamValueIfNotSpecified(Command, SkipStage, this.SkipStage, "skipstage");
			if (this.SkipStage)
			{
				this.Stage = true;
			}
			this.StageDirectoryParam = ParseParamValueIfNotSpecified(Command, StageDirectoryParam, "stagingdirectory", String.Empty, true);
			this.bCodeSign = GetParamValueIfNotSpecified(Command, CodeSign, CommandUtils.IsBuildMachine, "CodeSign");
			this.bTreatNonShippingBinariesAsDebugFiles = GetParamValueIfNotSpecified(Command, TreatNonShippingBinariesAsDebugFiles, false, "TreatNonShippingBinariesAsDebugFiles");
			this.Manifests = GetParamValueIfNotSpecified(Command, Manifests, this.Manifests, "manifests");
            this.CreateChunkInstall = GetParamValueIfNotSpecified(Command, CreateChunkInstall, this.CreateChunkInstall, "createchunkinstall");
			this.ChunkInstallDirectory = ParseParamValueIfNotSpecified(Command, ChunkInstallDirectory, "chunkinstalldirectory", String.Empty, true);
			this.ChunkInstallVersionString = ParseParamValueIfNotSpecified(Command, ChunkInstallVersionString, "chunkinstallversion", String.Empty, true);
			this.Archive = GetParamValueIfNotSpecified(Command, Archive, this.Archive, "archive");
			this.ArchiveDirectoryParam = ParseParamValueIfNotSpecified(Command, ArchiveDirectoryParam, "archivedirectory", String.Empty, true);
			this.ArchiveMetaData = GetParamValueIfNotSpecified(Command, ArchiveMetaData, this.ArchiveMetaData, "archivemetadata");
			this.CreateAppBundle = GetParamValueIfNotSpecified(Command, CreateAppBundle, true, "createappbundle");
			this.Distribution = GetParamValueIfNotSpecified(Command, Distribution, this.Distribution, "distribution");
			this.Prereqs = GetParamValueIfNotSpecified(Command, Prereqs, this.Prereqs, "prereqs");
			this.AppLocalDirectory = ParseParamValueIfNotSpecified(Command, AppLocalDirectory, "applocaldirectory", String.Empty, true);
			this.NoBootstrapExe = GetParamValueIfNotSpecified(Command, NoBootstrapExe, this.NoBootstrapExe, "nobootstrapexe");
            this.Prebuilt = GetParamValueIfNotSpecified(Command, Prebuilt, this.Prebuilt, "prebuilt");
            if (this.Prebuilt)
            {
                this.SkipCook = true;
                /*this.SkipPak = true;
                this.SkipStage = true;
                this.Pak = true;
                this.Stage = true;*/
                this.Cook = true;
                this.Archive = true;
                
                this.Deploy = true;
                this.Run = true;
                //this.StageDirectoryParam = this.PrebuiltDir;
            }
            this.NoDebugInfo = GetParamValueIfNotSpecified(Command, NoDebugInfo, this.NoDebugInfo, "nodebuginfo");
			this.NoCleanStage = GetParamValueIfNotSpecified(Command, NoCleanStage, this.NoCleanStage, "nocleanstage");
			this.MapToRun = ParseParamValueIfNotSpecified(Command, MapToRun, "map", String.Empty);
			this.AdditionalServerMapParams = ParseParamValueIfNotSpecified(Command, AdditionalServerMapParams, "AdditionalServerMapParams", String.Empty);
			this.Foreign = GetParamValueIfNotSpecified(Command, Foreign, this.Foreign, "foreign");
			this.ForeignCode = GetParamValueIfNotSpecified(Command, ForeignCode, this.ForeignCode, "foreigncode");
			this.StageCommandline = ParseParamValueIfNotSpecified(Command, StageCommandline, "cmdline");
			this.BundleName = ParseParamValueIfNotSpecified(Command, BundleName, "bundlename");
			this.RunCommandline = ParseParamValueIfNotSpecified(Command, RunCommandline, "addcmdline");
			this.RunCommandline = this.RunCommandline.Replace('\'', '\"'); // replace any single quotes with double quotes
			this.ServerCommandline = ParseParamValueIfNotSpecified(Command, ServerCommandline, "servercmdline");
			this.ServerCommandline = this.ServerCommandline.Replace('\'', '\"'); // replace any single quotes with double quotes
            this.Package = GetParamValueIfNotSpecified(Command, Package, this.Package, "package");
			this.Deploy = GetParamValueIfNotSpecified(Command, Deploy, this.Deploy, "deploy");
			this.IterativeDeploy = GetParamValueIfNotSpecified(Command, IterativeDeploy, this.IterativeDeploy, new string[] {"iterativedeploy", "iterate" } );
			this.FastCook = GetParamValueIfNotSpecified(Command, FastCook, this.FastCook, "FastCook");
			this.IgnoreCookErrors = GetParamValueIfNotSpecified(Command, IgnoreCookErrors, this.IgnoreCookErrors, "IgnoreCookErrors");
            this.RunAssetNativization = GetParamValueIfNotSpecified(Command, RunAssetNativization, this.RunAssetNativization, "nativizeAssets");

            string DeviceString = ParseParamValueIfNotSpecified(Command, Device, "device", String.Empty).Trim(new char[] { '\"' });
            if(DeviceString == "")
            {
                this.Devices = new ParamList<string>("");
                this.DeviceNames = new ParamList<string>("");
            }
            else
            {
                this.Devices = new ParamList<string>(DeviceString.Split('+'));
                this.DeviceNames = new ParamList<string>();
                foreach (var d in this.Devices)
                {
                    // strip the platform prefix the specified device.
                    if (d.Contains("@"))
                    {
                        this.DeviceNames.Add(d.Substring(d.IndexOf("@") + 1));
                    }
                    else
                    {
                        this.DeviceNames.Add(d);
                    }
                }
            }

			this.Provision = ParseParamValueIfNotSpecified(Command, Provision, "provision", String.Empty, true);
			this.Certificate = ParseParamValueIfNotSpecified(Command, Certificate, "certificate", String.Empty, true);

			this.ServerDevice = ParseParamValueIfNotSpecified(Command, ServerDevice, "serverdevice", this.Devices.Count > 0 ? this.Devices[0] : "");
			this.NullRHI = GetParamValueIfNotSpecified(Command, NullRHI, this.NullRHI, "nullrhi");
			this.FakeClient = GetParamValueIfNotSpecified(Command, FakeClient, this.FakeClient, "fakeclient");
			this.EditorTest = GetParamValueIfNotSpecified(Command, EditorTest, this.EditorTest, "editortest");
            this.RunAutomationTest = ParseParamValueIfNotSpecified(Command, RunAutomationTest, "RunAutomationTest");
            this.RunAutomationTests = this.RunAutomationTest != "" || GetParamValueIfNotSpecified(Command, RunAutomationTests, this.RunAutomationTests, "RunAutomationTests");
            this.SkipServer = GetParamValueIfNotSpecified(Command, SkipServer, this.SkipServer, "skipserver");
			this.UE4Exe = ParseParamValueIfNotSpecified(Command, UE4Exe, "ue4exe", "UE4Editor-Cmd.exe");
			this.Unattended = GetParamValueIfNotSpecified(Command, Unattended, this.Unattended, "unattended");
			this.DeviceUsername = ParseParamValueIfNotSpecified(Command, DeviceUsername, "deviceuser", String.Empty);
			this.DevicePassword = ParseParamValueIfNotSpecified(Command, DevicePassword, "devicepass", String.Empty);
			this.CrashReporter = GetParamValueIfNotSpecified(Command, CrashReporter, this.CrashReporter, "crashreporter");
			this.SpecifiedArchitecture = ParseParamValueIfNotSpecified(Command, SpecifiedArchitecture, "specifiedarchitecture", String.Empty);

			if (ClientConfigsToBuild == null)
			{
				if (Command != null)
				{
					var ClientConfig = Command.ParseParamValue("clientconfig");

                    if (ClientConfig == null)
                        ClientConfig = Command.ParseParamValue("config");

                    if (ClientConfig != null)
					{
						this.ClientConfigsToBuild = new List<UnrealTargetConfiguration>();
						var Configs = new ParamList<string>(ClientConfig.Split('+'));
						foreach (var ConfigName in Configs)
						{
							this.ClientConfigsToBuild.Add((UnrealTargetConfiguration)Enum.Parse(typeof(UnrealTargetConfiguration), ConfigName, true));
						}
					}
				}
			}
			else
			{
				this.ClientConfigsToBuild = ClientConfigsToBuild;
			}

            if (Port == null)
            {
                if( Command != null )
                {
                    this.Port = new ParamList<string>();

                    var PortString = Command.ParseParamValue("port");
                    if (String.IsNullOrEmpty(PortString) == false)
                    {
                        var Ports = new ParamList<string>(PortString.Split('+'));
                        foreach (var P in Ports)
                        {
                            this.Port.Add(P);
                        }
                    }
                    
                }
            }
            else
            {
                this.Port = Port;
            }

            if (MapsToCook == null)
            {
                if (Command != null)
                {
                    this.MapsToCook = new ParamList<string>();

                    var MapsString = Command.ParseParamValue("MapsToCook");
                    if (String.IsNullOrEmpty(MapsString) == false)
                    {
                        var MapNames = new ParamList<string>(MapsString.Split('+'));
                        foreach ( var M in MapNames ) 
                        {
                            this.MapsToCook.Add( M );
                        }
                    }
                }
            }
            else
            {
                this.MapsToCook = MapsToCook;
            }

            if (String.IsNullOrEmpty(this.MapToRun) == false)
            {
                this.MapsToCook.Add(this.MapToRun);
            }

			if (InMapsToRebuildLightMaps == null)
			{
				if (Command != null)
				{
					this.MapsToRebuildLightMaps = new ParamList<string>();

					var MapsString = Command.ParseParamValue("MapsToRebuildLightMaps");
					if (String.IsNullOrEmpty(MapsString) == false)
					{
						var MapNames = new ParamList<string>(MapsString.Split('+'));
						foreach (var M in MapNames)
						{
							this.MapsToRebuildLightMaps.Add(M);
						}
					}
				}
			}
			else
			{
				this.MapsToRebuildLightMaps = InMapsToRebuildLightMaps;
			}

			if (TitleID == null)
			{
				if (Command != null)
				{
					this.TitleID = new ParamList<string>();

					var TitleString = Command.ParseParamValue("TitleID");
					if (String.IsNullOrEmpty(TitleString) == false)
					{
						var TitleIDs = new ParamList<string>(TitleString.Split('+'));
						foreach (var T in TitleIDs)
						{
							this.TitleID.Add(T);
						}
					}
				}
			}
			else
			{
				this.TitleID = TitleID;
			}

			if (ServerConfigsToBuild == null)
			{
				if (Command != null)
				{
					var ServerConfig = Command.ParseParamValue("serverconfig");

                    if (ServerConfig == null)
                        ServerConfig = Command.ParseParamValue("config");

                    if (ServerConfig != null)
					{
						this.ServerConfigsToBuild = new List<UnrealTargetConfiguration>();
						var Configs = new ParamList<string>(ServerConfig.Split('+'));
						foreach (var ConfigName in Configs)
						{
							this.ServerConfigsToBuild.Add((UnrealTargetConfiguration)Enum.Parse(typeof(UnrealTargetConfiguration), ConfigName, true));
						}
					}
				}
			}
			else
			{
				this.ServerConfigsToBuild = ServerConfigsToBuild;
			}
			if (NumClients.HasValue)
			{
				this.NumClients = NumClients.Value;
			}
			else if (Command != null)
			{
				this.NumClients = Command.ParseParamInt("numclients");
			}
            if (CrashIndex.HasValue)
            {
                this.CrashIndex = CrashIndex.Value;
            }
            else if (Command != null)
            {
                this.CrashIndex = Command.ParseParamInt("CrashIndex");
            }
            if (RunTimeoutSeconds.HasValue)
            {
                this.RunTimeoutSeconds = RunTimeoutSeconds.Value;
            }
            else if (Command != null)
            {
                this.RunTimeoutSeconds = Command.ParseParamInt("runtimeoutseconds");
            }

			AutodetectSettings(false);
			ValidateAndLog();
		}
Exemple #42
0
        /// <summary>
        /// Builds a UBT Commandline.
        /// </summary>
        /// <param name="Project">Unreal project to build (optional)</param>
        /// <param name="Target">Target to build.</param>
        /// <param name="Platform">Platform to build for.</param>
        /// <param name="Config">Configuration to build.</param>
        /// <param name="AdditionalArgs">Additional arguments to pass on to UBT.</param>
        public static string UBTCommandline(FileReference Project, string Target, UnrealTargetPlatform Platform, UnrealTargetConfiguration Config, string AdditionalArgs = "")
        {
            string CmdLine;

            if (Project == null)
            {
                CmdLine = String.Format("{0} {1} {2} {3}", Target, Platform, Config, AdditionalArgs);
            }
            else
            {
                CmdLine = String.Format("{0} {1} {2} -Project={3} {4}", Target, Platform, Config, CommandUtils.MakePathSafeToUseWithCommandLine(Project.FullName), AdditionalArgs);
            }
            return(CmdLine);
        }
		/// <summary>
		/// Gets a parameter value from the command line if it hasn't been specified in the constructor. 
		/// If the command line is not available, default value will be used.
		/// </summary>
		/// <param name="Command">Command to parse the command line for. Can be null.</param>
		/// <param name="SpecifiedValue">Value specified in the constructor (or not)</param>
		/// <param name="ParamName">Command line parameter name to parse.</param>
		/// <param name="Default">Default value</param>
		/// <param name="bTrimQuotes">If set, the leading and trailing quotes will be removed, e.g. instead of "/home/User Name" it will return /home/User Name</param>
		/// <returns>Parameter value.</returns>
		string ParseParamValueIfNotSpecified(CommandUtils Command, string SpecifiedValue, string ParamName, string Default = "", bool bTrimQuotes = false)
		{
			string Result = Default;

			if (SpecifiedValue != null)
			{
				Result = SpecifiedValue;
			}
			else if (Command != null)
			{
				Result = Command.ParseParamValue(ParamName, Default);
			}

			return bTrimQuotes ? Result.Trim( new char[]{'\"'} ) : Result;
		}
        /// <summary>
        /// Sets up platforms
        /// </summary>
        /// <param name="Command"></param>
        /// <param name="OverrideTargetPlatforms"></param>
        /// <param name="AllowPlatformParams"></param>
        /// <param name="PlatformParamNames"></param>
        /// <returns>List of platforms parsed from the command line</returns>
        private List<UnrealTargetPlatform> SetupTargetPlatforms(CommandUtils Command, List<UnrealTargetPlatform> OverrideTargetPlatforms, List<UnrealTargetPlatform> DefaultTargetPlatforms, bool AllowPlatformParams, params string[] PlatformParamNames)
        {
            List<UnrealTargetPlatform> TargetPlatforms = null;
            if (CommandUtils.IsNullOrEmpty(OverrideTargetPlatforms))
            {
                if (Command != null)
                {
                    // Parse the command line, we support the following params:
                    // -'PlatformParamNames[n]'=Platform_1+Platform_2+...+Platform_k
                    // or (if AllowPlatformParams is true)
                    // -Platform_1 -Platform_2 ... -Platform_k
                    string CmdLinePlatform = null;
                    foreach (var ParamName in PlatformParamNames)
                    {
                        CmdLinePlatform = Command.ParseParamValue(ParamName);
                        if (!String.IsNullOrEmpty(CmdLinePlatform))
                        {
                            break;
                        }
                    }

                    if (!String.IsNullOrEmpty(CmdLinePlatform))
                    {
                        // Get all platforms from the param value: Platform_1+Platform_2+...+Platform_k
                        TargetPlatforms = new List<UnrealTargetPlatform>();
                        var Platforms = new List<string>(CmdLinePlatform.Split('+'));
                        foreach (var PlatformName in Platforms)
                        {
                            TargetPlatforms.Add((UnrealTargetPlatform)Enum.Parse(typeof(UnrealTargetPlatform), PlatformName, true));
                        }
                    }
                    else if (AllowPlatformParams)
                    {
                        // Look up platform names in the command line: -Platform_1 -Platform_2 ... -Platform_k
                        TargetPlatforms = new List<UnrealTargetPlatform>();
                        foreach (var Plat in CommandUtils.KnownTargetPlatforms)
                        {
                            if (Command.ParseParam(Plat.ToString()))
                            {
                                TargetPlatforms.Add(Plat);
                            }
                        }
                    }
                }
            }
            else
            {
                TargetPlatforms = OverrideTargetPlatforms;
            }
            if (CommandUtils.IsNullOrEmpty(TargetPlatforms))
            {
                // Revert to single default platform: Win64
                TargetPlatforms = DefaultTargetPlatforms;
            }
            return TargetPlatforms;
        }