public static void ApplyStagingManifest(ProjectParams Params, DeploymentContext SC) { MaybeConvertToLowerCase(Params, SC); if (SC.Stage && !Params.NoCleanStage && !Params.SkipStage) { DeleteDirectory(SC.StageDirectory); } if (ShouldCreatePak(Params, SC)) { if (Params.Manifests && DoesChunkPakManifestExist(Params, SC)) { CreatePaksUsingChunkManifests(Params, SC); } else { CreatePakUsingStagingManifest(Params, SC); } } if (!SC.Stage || Params.SkipStage) { return; } DumpManifest(SC, CombinePaths(CmdEnv.LogFolder, "FinalCopy" + (SC.DedicatedServer ? "_Server" : "")), !Params.UsePak(SC.StageTargetPlatform)); CopyUsingStagingManifest(Params, SC); var ThisPlatform = SC.StageTargetPlatform; ThisPlatform.PostStagingFileCopy(Params, SC); }
public static void ApplyStagingManifest(ProjectParams Params, DeploymentContext SC) { MaybeConvertToLowerCase(Params, SC); if (SC.Stage && !Params.NoCleanStage && !Params.SkipStage && !Params.IterativeDeploy) { try { DeleteDirectory(SC.StageDirectory); } catch (Exception Ex) { // Delete cooked data (if any) as it may be incomplete / corrupted. Log("Failed to delete staging directory "+SC.StageDirectory); AutomationTool.ErrorReporter.Error("Stage Failed.", (int)AutomationTool.ErrorCodes.Error_FailedToDeleteStagingDirectory); throw Ex; } } else { try { // delete old pak files DeletePakFiles(SC.StageDirectory); } catch (Exception Ex) { // Delete cooked data (if any) as it may be incomplete / corrupted. Log("Failed to delete pak files in "+SC.StageDirectory); AutomationTool.ErrorReporter.Error("Stage Failed.", (int)AutomationTool.ErrorCodes.Error_FailedToDeleteStagingDirectory); throw Ex; } } if (ShouldCreatePak(Params, SC)) { if (Params.Manifests && DoesChunkPakManifestExist(Params, SC)) { CreatePaksUsingChunkManifests(Params, SC); } else { CreatePakUsingStagingManifest(Params, SC); } } if (!SC.Stage || Params.SkipStage) { return; } DumpManifest(SC, CombinePaths(CmdEnv.LogFolder, "FinalCopy" + (SC.DedicatedServer ? "_Server" : "")), !Params.UsePak(SC.StageTargetPlatform)); CopyUsingStagingManifest(Params, SC); var ThisPlatform = SC.StageTargetPlatform; ThisPlatform.PostStagingFileCopy(Params, SC); }
public override void GetFilesToDeployOrStage(ProjectParams Params, DeploymentContext SC) { List<string> Exes = GetExecutableNames(SC); foreach (var Exe in Exes) { if (Exe.StartsWith(CombinePaths(SC.RuntimeProjectRootDir, "Binaries", SC.PlatformDir))) { StageAppBundle(SC, CombinePaths(SC.ProjectRoot, "Binaries", SC.PlatformDir, Path.GetFileNameWithoutExtension(Exe) + ".app"), CombinePaths(SC.ShortProjectName, "Binaries", SC.PlatformDir, Path.GetFileNameWithoutExtension(Exe) + ".app")); } else if (Exe.StartsWith(CombinePaths(SC.RuntimeRootDir, "Engine/Binaries", SC.PlatformDir))) { StageAppBundle(SC, CombinePaths(SC.LocalRoot, "Engine/Binaries", SC.PlatformDir, Path.GetFileNameWithoutExtension(Exe) + ".app"), CombinePaths("Engine/Binaries", SC.PlatformDir, Path.GetFileNameWithoutExtension(Exe) + ".app")); } } // Copy the splash screen, Mac specific SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Content/Splash"), "Splash.bmp", false, null, null, true); SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.LocalRoot, "Engine/Content/Localization/ICU"), "*", true, null, null, false, !Params.UsePak(SC.StageTargetPlatform)); }
public static void CopyUsingStagingManifest(ProjectParams Params, DeploymentContext SC) { CopyManifestFilesToStageDir(SC.NonUFSStagingFiles, SC.StageDirectory, "NonUFSFiles", SC.StageTargetPlatform.GetFilesForCRCCheck()); if (!Params.NoDebugInfo) { CopyManifestFilesToStageDir(SC.NonUFSStagingFilesDebug, SC.StageDirectory, "DebugFiles", SC.StageTargetPlatform.GetFilesForCRCCheck()); } bool bStageUnrealFileSystemFiles = !Params.CookOnTheFly && !Params.UsePak(SC.StageTargetPlatform) && !Params.FileServer; if (bStageUnrealFileSystemFiles) { CopyManifestFilesToStageDir(SC.UFSStagingFiles, SC.StageDirectory, "UFSFiles", SC.StageTargetPlatform.GetFilesForCRCCheck()); } }
public static void CreateStagingManifest(ProjectParams Params, DeploymentContext SC) { if (!Params.Stage) { return; } var ThisPlatform = SC.StageTargetPlatform; LogConsole("Creating Staging Manifest..."); if (Params.HasDLCName) { string DLCName = Params.DLCName; // Making a plugin, grab the binaries too SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Plugins", DLCName), "*.uplugin", true, null, null, true); SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Plugins", DLCName, "Binaries"), "libUE4-*.so", true, null, null, true); SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Plugins", DLCName, "Binaries"), "UE4-*.dll", true, null, null, true); SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Plugins", DLCName, "Binaries"), "libUE4Server-*.so", true, null, null, true); SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Plugins", DLCName, "Binaries"), "UE4Server-*.dll", true, null, null, true); // Put all of the cooked dir into the staged dir // Dedicated server cook doesn't save shaders so no Engine dir is created if ((!SC.DedicatedServer) && (!Params.DLCIncludeEngineContent)) { if (Directory.Exists(CombinePaths(SC.ProjectRoot, "Plugins", DLCName, "Saved", "Cooked", SC.CookPlatform, "Engine"))) { SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.ProjectRoot, "Plugins", DLCName, "Saved", "Cooked", SC.CookPlatform), "*", true, new[] { CommandUtils.CombinePaths("Engine", "*") }, "", true, !Params.UsePak(SC.StageTargetPlatform)); } } SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.ProjectRoot, "Plugins", DLCName, "Saved", "Cooked", SC.CookPlatform), "*", true, new[] { "AssetRegistry.bin" }, "", true, !Params.UsePak(SC.StageTargetPlatform)); return; } ThisPlatform.GetFilesToDeployOrStage(Params, SC); // Stage any extra runtime dependencies from the receipts foreach(TargetReceipt Receipt in SC.StageTargetReceipts) { SC.StageRuntimeDependenciesFromReceipt(Receipt); } // Get the build.properties file // this file needs to be treated as a UFS file for casing, but NonUFS for being put into the .pak file // @todo: Maybe there should be a new category - UFSNotForPak string BuildPropertiesPath = CombinePaths(SC.LocalRoot, "Engine/Build"); if (SC.StageTargetPlatform.DeployLowerCaseFilenames(true)) { BuildPropertiesPath = BuildPropertiesPath.ToLowerInvariant(); } SC.StageFiles(StagedFileType.NonUFS, BuildPropertiesPath, "Build.version", false, null, null, true); // move the UE4Commandline.txt file to the root of the stage // this file needs to be treated as a UFS file for casing, but NonUFS for being put into the .pak file // @todo: Maybe there should be a new category - UFSNotForPak string CommandLineFile = "UE4CommandLine.txt"; if (SC.StageTargetPlatform.DeployLowerCaseFilenames(true)) { CommandLineFile = CommandLineFile.ToLowerInvariant(); } SC.StageFiles(StagedFileType.NonUFS, GetIntermediateCommandlineDir(SC), CommandLineFile, false, null, "", true, false); ConfigCacheIni PlatformGameConfig = new ConfigCacheIni(SC.StageTargetPlatform.PlatformType, "Game", CommandUtils.GetDirectoryName(Params.RawProjectPath)); var ProjectContentRoot = CombinePaths(SC.ProjectRoot, "Content"); var StageContentRoot = CombinePaths(SC.RelativeProjectRootForStage, "Content"); if (!Params.CookOnTheFly && !Params.SkipCookOnTheFly) // only stage the UFS files if we are not using cook on the fly { // Initialize internationalization preset. string InternationalizationPreset = null; // Use parameters if provided. if (string.IsNullOrEmpty(InternationalizationPreset)) { InternationalizationPreset = Params.InternationalizationPreset; } // Use configuration if otherwise lacking an internationalization preset. if (string.IsNullOrEmpty(InternationalizationPreset)) { if (PlatformGameConfig != null) { PlatformGameConfig.GetString("/Script/UnrealEd.ProjectPackagingSettings", "InternationalizationPreset", out InternationalizationPreset); } } // Error if no preset has been provided. if (string.IsNullOrEmpty(InternationalizationPreset)) { throw new AutomationException("No internationalization preset was specified for packaging. This will lead to fatal errors when launching. Specify preset via commandline (-I18NPreset=) or project packaging settings (InternationalizationPreset)."); } // Initialize cultures to stage. List<string> CulturesToStage = null; // Use parameters if provided. if (Params.CulturesToCook != null && Params.CulturesToCook.Count > 0) { CulturesToStage = Params.CulturesToCook; } // Use configuration if otherwise lacking cultures to stage. if (CulturesToStage == null || CulturesToStage.Count == 0) { if (PlatformGameConfig != null) { PlatformGameConfig.GetArray("/Script/UnrealEd.ProjectPackagingSettings", "CulturesToStage", out CulturesToStage); } } // Error if no cultures have been provided. if (CulturesToStage == null || CulturesToStage.Count == 0) { throw new AutomationException("No cultures were specified for cooking and packaging. This will lead to fatal errors when launching. Specify culture codes via commandline (-CookCultures=) or using project packaging settings (+CulturesToStage)."); } // Stage ICU internationalization data from Engine. SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.LocalRoot, "Engine", "Content", "Internationalization", InternationalizationPreset), "*", true, null, CombinePaths("Engine", "Content", "Internationalization"), true, !Params.UsePak(SC.StageTargetPlatform)); // Engine ufs (content) SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.LocalRoot, "Engine/Config"), "*", true, null, null, false, !Params.UsePak(SC.StageTargetPlatform)); // TODO: Exclude localization data generation config files. // Stat prefix/suffix files (used for FPSChart, etc...) //@TODO: Avoid packaging stat files in shipping builds (only 6 KB, but still more than zero) SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.LocalRoot, "Engine/Content/Stats"), "*", true, null, null, false, !Params.UsePak(SC.StageTargetPlatform)); if (Params.bUsesSlate) { if (Params.bUsesSlateEditorStyle) { SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.LocalRoot, "Engine/Content/Editor/Slate"), "*", true, null, null, false, !Params.UsePak(SC.StageTargetPlatform)); } SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.LocalRoot, "Engine/Content/Slate"), "*", true, null, null, false, !Params.UsePak(SC.StageTargetPlatform)); SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.ProjectRoot, "Content/Slate"), "*", true, new string[] { "*.uasset" }, CombinePaths(SC.RelativeProjectRootForStage, "Content/Slate"), true, !Params.UsePak(SC.StageTargetPlatform)); } foreach (string Culture in CulturesToStage) { StageLocalizationDataForCulture(SC, Culture, CombinePaths(SC.LocalRoot, "Engine/Content/Localization/Engine"), null, !Params.UsePak(SC.StageTargetPlatform)); } // Engine & Game Plugins. Push the Engine/Source working directory so UBT code has a correct RelativeEnginePath in ReadAvailablePlugins ProjectDescriptor Project = ProjectDescriptor.FromFile(SC.RawProjectPath); Log("Searching for plugins with CurrentWorkingDir: " + Directory.GetCurrentDirectory()); Log("Searching for plugins in: " + SC.RawProjectPath); List<PluginInfo> AvailablePlugins = Plugins.ReadAvailablePlugins(CombinePaths(SC.LocalRoot, "Engine"), SC.RawProjectPath); foreach (PluginInfo Plugin in AvailablePlugins) { Log("Considering Plugin for Stage: " + Plugin.FileName); if (UProjectInfo.IsPluginEnabledForProject(Plugin, Project, SC.StageTargetPlatform.PlatformType)) { Log("EnabledPlugin: " + Plugin.FileName); SC.StageFiles(StagedFileType.UFS, Plugin.Directory, "*.uplugin", false, null, null, true, !Params.UsePak(SC.StageTargetPlatform), null, true, false); } } // Game ufs (content) SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.ProjectRoot), "*.uproject", false, null, CombinePaths(SC.RelativeProjectRootForStage), true, !Params.UsePak(SC.StageTargetPlatform)); if (SC.StageTargetPlatform.PlatformType != UnrealTargetPlatform.HTML5 && SC.bUseWebsocketNetDriver) { var EngineIniPath = Path.Combine(SC.ProjectRoot, "Config", "DefaultEngine.ini"); var IntermediateEngineIniDir = Path.Combine(GetIntermediateCommandlineDir(SC), SC.RelativeProjectRootForStage, "Config"); Directory.CreateDirectory(IntermediateEngineIniDir); var IntermediateEngineIniPath = Path.Combine(IntermediateEngineIniDir, "DefaultEngine.ini"); List<String> IniLines = new List<String>(); if (File.Exists(EngineIniPath)) { IniLines = File.ReadAllLines(EngineIniPath).ToList(); } IniLines.Add("[/Script/Engine.GameEngine]"); IniLines.Add("!NetDriverDefinitions=ClearArray"); IniLines.Add("+NetDriverDefinitions=(DefName=\"GameNetDriver\", DriverClassName=\"/Script/HTML5Networking.WebSocketNetDriver\", DriverClassNameFallback=\"/Script/HTML5Networking.WebSocketNetDriver\")"); File.WriteAllLines(IntermediateEngineIniPath, IniLines); SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.ProjectRoot, "Config"), "*", true, new string[] {"DefaultEngine.ini"}, CombinePaths(SC.RelativeProjectRootForStage, "Config"), true, !Params.UsePak(SC.StageTargetPlatform)); // TODO: Exclude localization data generation config files. SC.StageFiles(StagedFileType.UFS, IntermediateEngineIniDir, "*.ini", true, null, CombinePaths(SC.RelativeProjectRootForStage, "Config"), true, !Params.UsePak(SC.StageTargetPlatform)); // TODO: Exclude localization data generation config files. } else { SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.ProjectRoot, "Config"), "*", true, null, CombinePaths(SC.RelativeProjectRootForStage, "Config"), true, !Params.UsePak(SC.StageTargetPlatform)); // TODO: Exclude localization data generation config files. } foreach (string Culture in CulturesToStage) { StageLocalizationDataForCulture(SC, Culture, CombinePaths(SC.ProjectRoot, "Content/Localization/Game"), CombinePaths(SC.RelativeProjectRootForStage, "Content/Localization/Game"), !Params.UsePak(SC.StageTargetPlatform)); } // Stage any additional UFS and NonUFS paths specified in the project ini files; these dirs are relative to the game content directory if (PlatformGameConfig != null) { List<string> ExtraUFSDirs; if (PlatformGameConfig.GetArray("/Script/UnrealEd.ProjectPackagingSettings", "DirectoriesToAlwaysStageAsUFS", out ExtraUFSDirs)) { // Each string has the format '(Path="TheDirToStage")' foreach (var PathStr in ExtraUFSDirs) { var PathParts = PathStr.Split('"'); if (PathParts.Length == 3) { var RelativePath = PathParts[1]; SC.StageFiles(StagedFileType.UFS, CombinePaths(ProjectContentRoot, RelativePath), "*", true, null, CombinePaths(StageContentRoot, RelativePath), true, !Params.UsePak(SC.StageTargetPlatform)); } else if (PathParts.Length == 1) { var RelativePath = PathParts[0]; SC.StageFiles(StagedFileType.UFS, CombinePaths(ProjectContentRoot, RelativePath), "*", true, null, CombinePaths(StageContentRoot, RelativePath), true, !Params.UsePak(SC.StageTargetPlatform)); } } } List<string> ExtraNonUFSDirs; if (PlatformGameConfig.GetArray("/Script/UnrealEd.ProjectPackagingSettings", "DirectoriesToAlwaysStageAsNonUFS", out ExtraNonUFSDirs)) { // Each string has the format '(Path="TheDirToStage")' foreach (var PathStr in ExtraNonUFSDirs) { var PathParts = PathStr.Split('"'); if (PathParts.Length == 3) { var RelativePath = PathParts[1]; SC.StageFiles(StagedFileType.NonUFS, CombinePaths(ProjectContentRoot, RelativePath)); } else if (PathParts.Length == 1) { var RelativePath = PathParts[0]; SC.StageFiles(StagedFileType.UFS, CombinePaths(ProjectContentRoot, RelativePath), "*", true, null, CombinePaths(StageContentRoot, RelativePath), true, !Params.UsePak(SC.StageTargetPlatform)); } } } } StagedFileType StagedFileTypeForMovies = StagedFileType.NonUFS; if (Params.FileServer) { // UFS is required when using a file server StagedFileTypeForMovies = StagedFileType.UFS; } if (SC.StageTargetPlatform.StageMovies) { SC.StageFiles(StagedFileTypeForMovies, CombinePaths(SC.LocalRoot, "Engine/Content/Movies"), "*", true, new string[] { "*.uasset", "*.umap" }, CombinePaths(SC.RelativeProjectRootForStage, "Engine/Content/Movies"), true, !Params.UsePak(SC.StageTargetPlatform)); SC.StageFiles(StagedFileTypeForMovies, CombinePaths(SC.ProjectRoot, "Content/Movies"), "*", true, new string[] { "*.uasset", "*.umap" }, CombinePaths(SC.RelativeProjectRootForStage, "Content/Movies"), true, !Params.UsePak(SC.StageTargetPlatform)); } // eliminate the sand box SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.ProjectRoot, "Saved", "Cooked", SC.CookPlatform), "*", true, new string[] { "*.json" }, "", true, !Params.UsePak(SC.StageTargetPlatform)); // CrashReportClient is a standalone slate app that does not look in the generated pak file, so it needs the Content/Slate and Shaders/StandaloneRenderer folders Non-UFS // @todo Make CrashReportClient more portable so we don't have to do this if (SC.bStageCrashReporter && UnrealBuildTool.UnrealBuildTool.PlatformSupportsCrashReporter(SC.StageTargetPlatform.PlatformType) && !SC.DedicatedServer) { //If the .dat file needs to be staged as NonUFS for non-Windows/Linux hosts we need to change the casing as we do with the build properties file above. SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Content/Slate")); SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Shaders/StandaloneRenderer")); SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine", "Content", "Internationalization", InternationalizationPreset), "*", true, null, CombinePaths("Engine", "Content", "Internationalization"), false, true); // Linux platform stages ICU in GetFilesToDeployOrStage(), accounting for the actual architecture if (SC.StageTargetPlatform.PlatformType == UnrealTargetPlatform.Win64 || SC.StageTargetPlatform.PlatformType == UnrealTargetPlatform.Win32 || SC.StageTargetPlatform.PlatformType == UnrealTargetPlatform.Mac) { SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/ICU")); } // SSL libraries are only available for Win64 builds. // @see FPerforceSourceControlProvider::LoadSSLLibraries if (SC.StageTargetPlatform.PlatformType == UnrealTargetPlatform.Win64) { SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/OpenSSL")); } } } else { if (PlatformGameConfig != null) { List<string> ExtraNonUFSDirs; if (PlatformGameConfig.GetArray("/Script/UnrealEd.ProjectPackagingSettings", "DirectoriesToAlwaysStageAsNonUFS", out ExtraNonUFSDirs)) { // Each string has the format '(Path="TheDirToStage")' foreach (var PathStr in ExtraNonUFSDirs) { var PathParts = PathStr.Split('"'); if (PathParts.Length == 3) { var RelativePath = PathParts[1]; SC.StageFiles(StagedFileType.NonUFS, CombinePaths(ProjectContentRoot, RelativePath)); } else if (PathParts.Length == 1) { var RelativePath = PathParts[0]; SC.StageFiles(StagedFileType.UFS, CombinePaths(ProjectContentRoot, RelativePath), "*", true, null, CombinePaths(StageContentRoot, RelativePath), true, !Params.UsePak(SC.StageTargetPlatform)); } } } } } }
public static void MaybeConvertToLowerCase(ProjectParams Params, DeploymentContext SC) { var BuildPlatform = SC.StageTargetPlatform; if (BuildPlatform.DeployLowerCaseFilenames(false)) { SC.NonUFSStagingFiles = ConvertToLower(SC.NonUFSStagingFiles); SC.NonUFSStagingFilesDebug = ConvertToLower(SC.NonUFSStagingFilesDebug); } if (Params.UsePak(SC.StageTargetPlatform) && BuildPlatform.DeployPakInternalLowerCaseFilenames()) { SC.UFSStagingFiles = ConvertToLower(SC.UFSStagingFiles); } else if (!Params.UsePak(SC.StageTargetPlatform) && BuildPlatform.DeployLowerCaseFilenames(true)) { SC.UFSStagingFiles = ConvertToLower(SC.UFSStagingFiles); } }
private static ProcessResult RunDedicatedServer(ProjectParams Params, string ServerLogFile, string AdditionalCommandLine) { ProjectParams ServerParams = new ProjectParams(Params); ServerParams.Device = Params.ServerDevice; if (ServerParams.ServerTargetPlatforms.Count == 0) { throw new AutomationException("No ServerTargetPlatform set for RunDedicatedServer."); } var DeployContextList = CreateDeploymentContext(ServerParams, true); if (DeployContextList.Count == 0) { throw new AutomationException("No DeployContextList for RunDedicatedServer."); } var SC = DeployContextList[0]; var ServerApp = CombinePaths(CmdEnv.LocalRoot, "Engine/Binaries/Win64/UE4Editor.exe"); if (ServerParams.Cook) { List<string> Exes = SC.StageTargetPlatform.GetExecutableNames(SC); ServerApp = Exes[0]; } var Args = ServerParams.Cook ? "" : (SC.ProjectArgForCommandLines + " "); Console.WriteLine(Params.ServerDeviceAddress); UnrealTargetPlatform ServerPlatform = ServerParams.ServerTargetPlatforms[0]; if (ServerParams.Cook && ServerPlatform == UnrealTargetPlatform.Linux && !String.IsNullOrEmpty(ServerParams.ServerDeviceAddress)) { ServerApp = @"C:\Windows\system32\cmd.exe"; string plinkPath = CombinePaths(Environment.GetEnvironmentVariable("LINUX_ROOT"), "bin/PLINK.exe "); string exePath = CombinePaths(SC.ShortProjectName, "Binaries", ServerPlatform.ToString(), SC.ShortProjectName + "Server"); if (ServerParams.ServerConfigsToBuild[0] != UnrealTargetConfiguration.Development) { exePath += "-" + ServerPlatform.ToString() + "-" + ServerParams.ServerConfigsToBuild[0].ToString(); } exePath = CombinePaths("LinuxServer", exePath.ToLower()).Replace("\\", "/"); Args = String.Format("/k {0} -batch -ssh -t -i {1} {2}@{3} {4} {5} {6} -server -Messaging", plinkPath, ServerParams.DevicePassword, ServerParams.DeviceUsername, ServerParams.ServerDeviceAddress, exePath, Args, ServerParams.MapToRun); } else { var Map = ServerParams.MapToRun; if (!String.IsNullOrEmpty(ServerParams.AdditionalServerMapParams)) { Map += ServerParams.AdditionalServerMapParams; } if (Params.FakeClient) { Map += "?fake"; } Args += String.Format("{0} -server -abslog={1} -unattended -FORCELOGFLUSH -log -Messaging -nomcp", Map, CommandUtils.MakePathSafeToUseWithCommandLine(ServerLogFile)); } if (ServerParams.UsePak(SC.StageTargetPlatform) || ServerParams.SignedPak) { if (ServerParams.SignedPak) { Args += " -signedpak"; } else { Args += " -pak"; } } if (IsBuildMachine || Params.Unattended) { Args += " -buildmachine"; } Args += " -CrashForUAT"; Args += " " + AdditionalCommandLine; if (ServerParams.Cook && ServerPlatform == UnrealTargetPlatform.Linux && !String.IsNullOrEmpty(ServerParams.ServerDeviceAddress)) { Args += String.Format(" 2>&1 > {0}", ServerLogFile); } PushDir(Path.GetDirectoryName(ServerApp)); var Result = Run(ServerApp, Args, null, ERunOptions.AllowSpew | ERunOptions.NoWaitForExit | ERunOptions.AppMustExist | ERunOptions.NoStdOutRedirect); PopDir(); return Result; }
private static void SetupClientParams(List<DeploymentContext> DeployContextList, ProjectParams Params, string ClientLogFile, out ERunOptions ClientRunFlags, out string ClientApp, out string ClientCmdLine) { if (Params.ClientTargetPlatforms.Count == 0) { throw new AutomationException("No ClientTargetPlatform set for SetupClientParams."); } // var DeployContextList = CreateDeploymentContext(Params, false); if (DeployContextList.Count == 0) { throw new AutomationException("No DeployContextList for SetupClientParams."); } var SC = DeployContextList[0]; // Get client app name and command line. ClientRunFlags = ERunOptions.AllowSpew | ERunOptions.AppMustExist; ClientApp = ""; ClientCmdLine = ""; string TempCmdLine = ""; var PlatformName = Params.ClientTargetPlatforms[0].ToString(); if (Params.Cook || Params.CookOnTheFly) { List<string> Exes = SC.StageTargetPlatform.GetExecutableNames(SC, true); ClientApp = Exes[0]; if (SC.StageTargetPlatform.PlatformType != UnrealTargetPlatform.IOS) { TempCmdLine += SC.ProjectArgForCommandLines + " "; } TempCmdLine += Params.MapToRun + " "; if (Params.CookOnTheFly || Params.FileServer) { TempCmdLine += "-filehostip="; bool FirstParam = true; if (UnrealBuildTool.BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac) { NetworkInterface[] Interfaces = NetworkInterface.GetAllNetworkInterfaces(); foreach (NetworkInterface adapter in Interfaces) { if (adapter.NetworkInterfaceType != NetworkInterfaceType.Loopback) { IPInterfaceProperties IP = adapter.GetIPProperties(); for (int Index = 0; Index < IP.UnicastAddresses.Count; ++Index) { if (IP.UnicastAddresses[Index].IsDnsEligible && IP.UnicastAddresses[Index].Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) { if (!IsNullOrEmpty(Params.Port)) { foreach (var Port in Params.Port) { if (!FirstParam) { TempCmdLine += "+"; } FirstParam = false; string[] PortProtocol = Port.Split(new char[] { ':' }); if (PortProtocol.Length > 1) { TempCmdLine += String.Format("{0}://{1}:{2}", PortProtocol[0], IP.UnicastAddresses[Index].Address.ToString(), PortProtocol[1]); } else { TempCmdLine += IP.UnicastAddresses[Index].Address.ToString(); TempCmdLine += ":"; TempCmdLine += Params.Port; } } } else { if (!FirstParam) { TempCmdLine += "+"; } FirstParam = false; // use default port TempCmdLine += IP.UnicastAddresses[Index].Address.ToString(); } } } } } } else { NetworkInterface[] Interfaces = NetworkInterface.GetAllNetworkInterfaces(); foreach (NetworkInterface adapter in Interfaces) { if (adapter.OperationalStatus == OperationalStatus.Up) { IPInterfaceProperties IP = adapter.GetIPProperties(); for (int Index = 0; Index < IP.UnicastAddresses.Count; ++Index) { if (IP.UnicastAddresses[Index].IsDnsEligible) { if (!IsNullOrEmpty(Params.Port)) { foreach (var Port in Params.Port) { if (!FirstParam) { TempCmdLine += "+"; } FirstParam = false; string[] PortProtocol = Port.Split(new char[] { ':' }); if (PortProtocol.Length > 1) { TempCmdLine += String.Format("{0}://{1}:{2}", PortProtocol[0], IP.UnicastAddresses[Index].Address.ToString(), PortProtocol[1]); } else { TempCmdLine += IP.UnicastAddresses[Index].Address.ToString(); TempCmdLine += ":"; TempCmdLine += Params.Port; } } } else { if (!FirstParam) { TempCmdLine += "+"; } FirstParam = false; // use default port TempCmdLine += IP.UnicastAddresses[Index].Address.ToString(); } } } } } } const string LocalHost = "127.0.0.1"; if (!IsNullOrEmpty(Params.Port)) { foreach (var Port in Params.Port) { if (!FirstParam) { TempCmdLine += "+"; } FirstParam = false; string[] PortProtocol = Port.Split(new char[] { ':' }); if (PortProtocol.Length > 1) { TempCmdLine += String.Format("{0}://{1}:{2}", PortProtocol[0], LocalHost, PortProtocol[1]); } else { TempCmdLine += LocalHost; TempCmdLine += ":"; TempCmdLine += Params.Port; } } } else { if (!FirstParam) { TempCmdLine += "+"; } FirstParam = false; // use default port TempCmdLine += LocalHost; } TempCmdLine += " "; if (Params.CookOnTheFlyStreaming) { TempCmdLine += "-streaming "; } else if (SC.StageTargetPlatform.PlatformType != UnrealTargetPlatform.IOS) { // per josh, allowcaching is deprecated/doesn't make sense for iOS. TempCmdLine += "-allowcaching "; } } else if (Params.UsePak(SC.StageTargetPlatform) || Params.SignedPak) { if (Params.SignedPak) { TempCmdLine += "-signedpak "; } else { TempCmdLine += "-pak "; } } else if (!Params.Stage) { var SandboxPath = CombinePaths(SC.RuntimeProjectRootDir, "Saved", "Cooked", SC.CookPlatform); if (!SC.StageTargetPlatform.LaunchViaUFE) { TempCmdLine += "-sandbox=" + CommandUtils.MakePathSafeToUseWithCommandLine(SandboxPath) + " "; } else { TempCmdLine += "-sandbox=\'" + SandboxPath + "\' "; } } } else { ClientApp = CombinePaths(CmdEnv.LocalRoot, "Engine/Binaries", PlatformName, "UE4Editor.exe"); TempCmdLine += SC.ProjectArgForCommandLines + " "; if (!Params.EditorTest) { TempCmdLine += "-game " + Params.MapToRun + " "; } } if (Params.LogWindow) { // Without NoStdOutRedirect '-log' doesn't log anything to the window ClientRunFlags |= ERunOptions.NoStdOutRedirect; TempCmdLine += "-log "; } else { TempCmdLine += "-stdout "; } if (Params.Unattended) { TempCmdLine += "-unattended "; } if (IsBuildMachine || Params.Unattended) { TempCmdLine += "-buildmachine "; } if (Params.CrashIndex > 0) { int RealIndex = Params.CrashIndex - 1; if (RealIndex < 0 || RealIndex >= CrashCommands.Count()) { throw new AutomationException("CrashIndex {0} is out of range...max={1}", Params.CrashIndex, CrashCommands.Count()); } TempCmdLine += String.Format("-execcmds=\"debug {0}\" ", CrashCommands[RealIndex]); } else if (Params.RunAutomationTest != "") { TempCmdLine += "-execcmds=\"automation list;runtests " + Params.RunAutomationTest + "\" "; } else if (Params.RunAutomationTests) { TempCmdLine += "-execcmds=\"automation list;runall\" "; } if (SC.StageTargetPlatform.UseAbsLog) { TempCmdLine += "-abslog=" + CommandUtils.MakePathSafeToUseWithCommandLine(ClientLogFile) + " "; } if (SC.StageTargetPlatform.PlatformType != UnrealTargetPlatform.IOS) { TempCmdLine += "-Messaging -nomcp -Windowed "; } else { // skip arguments which don't make sense for iOS TempCmdLine += "-Messaging -nomcp "; } if (Params.NullRHI && SC.StageTargetPlatform.PlatformType != UnrealTargetPlatform.Mac) // all macs have GPUs, and currently the mac dies with nullrhi { TempCmdLine += "-nullrhi "; } if (Params.Deploy && SC.StageTargetPlatform.PlatformType == UnrealTargetPlatform.PS4) { TempCmdLine += "-deployedbuild "; } TempCmdLine += "-CrashForUAT "; TempCmdLine += Params.RunCommandline; // todo: move this into the platform if (SC.StageTargetPlatform.LaunchViaUFE) { ClientCmdLine = "-run=Launch "; ClientCmdLine += "-Device=" + Params.Device + " "; ClientCmdLine += "-Exe=\"" + ClientApp + "\" "; ClientCmdLine += "-Targetplatform=" + Params.ClientTargetPlatforms[0].ToString() + " "; ClientCmdLine += "-Params=\"" + TempCmdLine + "\""; ClientApp = CombinePaths(CmdEnv.LocalRoot, "Engine/Binaries/Win64/UnrealFrontend.exe"); LogConsole("Launching via UFE:"); LogConsole("\tClientCmdLine: " + ClientCmdLine + ""); } else { ClientCmdLine = TempCmdLine; } }
public static void CreateStagingManifest(ProjectParams Params, DeploymentContext SC) { if (!Params.Stage) { return; } var ThisPlatform = SC.StageTargetPlatform; ThisPlatform.GetFilesToDeployOrStage(Params, SC); // Get the build.properties file // this file needs to be treated as a UFS file for casing, but NonUFS for being put into the .pak file // @todo: Maybe there should be a new category - UFSNotForPak string BuildPropertiesPath = CombinePaths(SC.LocalRoot, "Engine/Build"); if (SC.StageTargetPlatform.DeployLowerCaseFilenames(true)) { BuildPropertiesPath = BuildPropertiesPath.ToLower(); } SC.StageFiles(StagedFileType.NonUFS, BuildPropertiesPath, "build.properties", false, null, null, true); // move the UE4Commandline.txt file to the root of the stage // this file needs to be treated as a UFS file for casing, but NonUFS for being put into the .pak file // @todo: Maybe there should be a new category - UFSNotForPak string CommandLineFile = "UE4CommandLine.txt"; if (SC.StageTargetPlatform.DeployLowerCaseFilenames(true)) { CommandLineFile = CommandLineFile.ToLower(); } SC.StageFiles(StagedFileType.NonUFS, GetIntermediateCommandlineDir(SC), CommandLineFile, false, null, "", true, false); if (!Params.CookOnTheFly && !Params.SkipCookOnTheFly) // only stage the UFS files if we are not using cook on the fly { ConfigCacheIni PlatformGameConfig = new ConfigCacheIni(SC.StageTargetPlatform.PlatformType, "Game", CommandUtils.GetDirectoryName(Params.RawProjectPath)); // Initialize cultures to stage. List<string> CulturesToStage = null; // Use parameters if provided. if (Params.CulturesToCook != null && Params.CulturesToCook.Count > 0) { CulturesToStage = Params.CulturesToCook; } // Use configuration if otherwise lacking cultures to stage. if (CulturesToStage == null || CulturesToStage.Count == 0) { if (PlatformGameConfig != null) { PlatformGameConfig.GetArray("/Script/UnrealEd.ProjectPackagingSettings", "CulturesToStage", out CulturesToStage); } } // Error if no cultures have been provided. if (CulturesToStage == null || CulturesToStage.Count == 0) { throw new AutomationException("No cultures were specified for cooking and packaging. This will lead to fatal errors when launching. Specify culture codes via commandline (-CookCultures=) or using project packaging settings (+CulturesToStage)."); } // Engine ufs (content) SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.LocalRoot, "Engine/Config"), "*", true, null, null, false, !Params.UsePak(SC.StageTargetPlatform)); // TODO: Exclude localization data generation config files. if (Params.bUsesSlate) { if (Params.bUsesSlateEditorStyle) { SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.LocalRoot, "Engine/Content/Editor/Slate"), "*", true, null, null, false, !Params.UsePak(SC.StageTargetPlatform)); } SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.LocalRoot, "Engine/Content/Slate"), "*", true, null, null, false, !Params.UsePak(SC.StageTargetPlatform)); SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.ProjectRoot, "Content/Slate"), "*", true, null, CombinePaths(SC.RelativeProjectRootForStage, "Content/Slate"), true, !Params.UsePak(SC.StageTargetPlatform)); } foreach (string Culture in CulturesToStage) { StageLocalizationDataForCulture(SC, Culture, CombinePaths(SC.LocalRoot, "Engine/Content/Localization/Engine"), null, !Params.UsePak(SC.StageTargetPlatform)); } SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.LocalRoot, "Engine/Plugins"), "*.uplugin", true, null, null, true, !Params.UsePak(SC.StageTargetPlatform)); // Game ufs (content) SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.ProjectRoot), "*.uproject", false, null, CombinePaths(SC.RelativeProjectRootForStage), true, !Params.UsePak(SC.StageTargetPlatform)); SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.ProjectRoot, "Config"), "*", true, null, CombinePaths(SC.RelativeProjectRootForStage, "Config"), true, !Params.UsePak(SC.StageTargetPlatform)); // TODO: Exclude localization data generation config files. SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.ProjectRoot, "Plugins"), "*.uplugin", true, null, null, true, !Params.UsePak(SC.StageTargetPlatform)); foreach (string Culture in CulturesToStage) { StageLocalizationDataForCulture(SC, Culture, CombinePaths(SC.ProjectRoot, "Content/Localization/Game"), CombinePaths(SC.RelativeProjectRootForStage, "Content/Localization/Game"), !Params.UsePak(SC.StageTargetPlatform)); } // Stage any additional UFS and NonUFS paths specified in the project ini files; these dirs are relative to the game content directory if (PlatformGameConfig != null) { var ProjectContentRoot = CombinePaths(SC.ProjectRoot, "Content"); var StageContentRoot = CombinePaths(SC.RelativeProjectRootForStage, "Content"); List<string> ExtraUFSDirs; if (PlatformGameConfig.GetArray("/Script/UnrealEd.ProjectPackagingSettings", "DirectoriesToAlwaysStageAsUFS", out ExtraUFSDirs)) { // Each string has the format '(Path="TheDirToStage")' foreach (var PathStr in ExtraUFSDirs) { var PathParts = PathStr.Split('"'); if (PathParts.Length == 3) { var RelativePath = PathParts[1]; SC.StageFiles(StagedFileType.UFS, CombinePaths(ProjectContentRoot, RelativePath), "*", true, null, CombinePaths(StageContentRoot, RelativePath), true, !Params.UsePak(SC.StageTargetPlatform)); } } } List<string> ExtraNonUFSDirs; if (PlatformGameConfig.GetArray("/Script/UnrealEd.ProjectPackagingSettings", "DirectoriesToAlwaysStageAsNonUFS", out ExtraNonUFSDirs)) { // Each string has the format '(Path="TheDirToStage")' foreach (var PathStr in ExtraNonUFSDirs) { var PathParts = PathStr.Split('"'); if (PathParts.Length == 3) { var RelativePath = PathParts[1]; SC.StageFiles(StagedFileType.NonUFS, CombinePaths(ProjectContentRoot, RelativePath)); } } } } StagedFileType StagedFileTypeForMovies = StagedFileType.NonUFS; if (Params.FileServer) { // UFS is required when using a file server StagedFileTypeForMovies = StagedFileType.UFS; } if (SC.StageTargetPlatform.StageMovies) { SC.StageFiles(StagedFileTypeForMovies, CombinePaths(SC.LocalRoot, "Engine/Content/Movies"), "*", true, null, CombinePaths(SC.RelativeProjectRootForStage, "Engine/Content/Movies"), true, !Params.UsePak(SC.StageTargetPlatform)); SC.StageFiles(StagedFileTypeForMovies, CombinePaths(SC.ProjectRoot, "Content/Movies"), "*", true, null, CombinePaths(SC.RelativeProjectRootForStage, "Content/Movies"), true, !Params.UsePak(SC.StageTargetPlatform)); } // eliminate the sand box SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.ProjectRoot, "Saved", "Cooked", SC.CookPlatform), "*", true, null, "", true, !Params.UsePak(SC.StageTargetPlatform)); // CrashReportClient is a standalone slate app that does not look in the generated pak file, so it needs the Content/Slate and Shaders/StandaloneRenderer folders Non-UFS // @todo Make CrashReportClient more portable so we don't have to do this if (SC.bStageCrashReporter && UnrealBuildTool.UnrealBuildTool.PlatformSupportsCrashReporter(SC.StageTargetPlatform.PlatformType) && !SC.DedicatedServer) { //If the .dat file needs to be staged as NonUFS for non-Windows/Linux hosts we need to change the casing as we do with the build properties file above. SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Content/Slate")); SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Shaders/StandaloneRenderer")); SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Content/Localization/ICU")); // Linux platform stages ICU in GetFilesToDeployOrStage(), accounting for the actual architecture if (SC.StageTargetPlatform.PlatformType == UnrealTargetPlatform.Win64 || SC.StageTargetPlatform.PlatformType == UnrealTargetPlatform.Win32 || SC.StageTargetPlatform.PlatformType == UnrealTargetPlatform.Mac) { SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/ICU")); } // SSL libraries are only available for Win64 builds. // @see FPerforceSourceControlProvider::LoadSSLLibraries if (SC.StageTargetPlatform.PlatformType == UnrealTargetPlatform.Win64) { SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/OpenSSL")); } } } }
/// <summary> /// Deploy the application on the current platform /// </summary> /// <param name="Params"></param> /// <param name="SC"></param> public override void Deploy(ProjectParams Params, DeploymentContext SC) { if (!String.IsNullOrEmpty(Params.ServerDeviceAddress)) { string sourcePath = CombinePaths(Params.BaseStageDirectory, GetCookPlatform(Params.DedicatedServer, false, "")); string destPath = Params.DeviceUsername + "@" + Params.ServerDeviceAddress + ":."; RunAndLog(CmdEnv, pscpPath, String.Format("-batch -i {0} -r {1} {2}", Params.DevicePassword, sourcePath, destPath)); List<string> Exes = GetExecutableNames(SC); string binPath = CombinePaths(GetCookPlatform(Params.DedicatedServer, false, ""), SC.RelativeProjectRootForStage, "Binaries", SC.PlatformDir, Path.GetFileName(Exes[0])).Replace("\\", "/"); string iconPath = CombinePaths(GetCookPlatform(Params.DedicatedServer, false, ""), SC.RelativeProjectRootForStage, SC.ShortProjectName + ".png").Replace("\\", "/"); string DesiredGLVersion = "4.3"; // Begin Bash Shell Script string script = String.Format(@"#!/bin/bash # Check for OpenGL4 support glarg='' if command -v glxinfo >/dev/null 2>&1 ; then export DISPLAY="":0"" glversion=$(glxinfo | grep ""OpenGL version string:"" | sed 's/[^0-9.]*\([0-9.]*\).*/\1/') glmatch=$(echo -e ""$glversion\n{0}"" | sort -Vr | head -1) [[ ""$glmatch"" = ""$glversion"" ]] && glarg=' -opengl4' fi # Create .desktop file cat > $HOME/Desktop/{1}.desktop << EOF [Desktop Entry] Type=Application Name={2} Comment=UE4 Game Exec=$HOME/{3}{4}$glarg Icon=$HOME/{5} Terminal=false Categories=Game; EOF # Set permissions chmod 755 $HOME/{3} chmod 700 $HOME/Desktop/{1}.desktop", DesiredGLVersion, SC.ShortProjectName, SC.ShortProjectName, binPath, (Params.UsePak(SC.StageTargetPlatform) ? " -pak" : ""), iconPath); // End Bash Shell Script string scriptFile = Path.GetTempFileName(); File.WriteAllText(scriptFile, script); RunAndLog(CmdEnv, plinkPath, String.Format("-ssh -t -batch -l {0} -i {1} {2} -m {3}", Params.DeviceUsername, Params.DevicePassword, Params.ServerDeviceAddress, scriptFile)); File.Delete(scriptFile); } }
public static void CreateStagingManifest(ProjectParams Params, DeploymentContext SC) { if (!Params.Stage) { return; } var ThisPlatform = SC.StageTargetPlatform; Log("Creating Staging Manifest..."); if (Params.HasDLCName) { string DLCName = Params.DLCName; // Making a plugin, grab the binaries too SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Plugins", DLCName), "*.uplugin", false, null, null, true); SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Plugins", DLCName, "Binaries"), "libUE4-*.so", true, null, null, true); SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Plugins", DLCName, "Binaries"), "UE4-*.dll", true, null, null, true); SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Plugins", DLCName, "Binaries"), "libUE4Server-*.so", true, null, null, true); SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Plugins", DLCName, "Binaries"), "UE4Server-*.dll", true, null, null, true); // Put all of the cooked dir into the staged dir string PlatformCookDir = CombinePaths(SC.ProjectRoot, "Plugins", DLCName, "Saved", "Cooked", SC.CookPlatform); string[] ExcludeWildCards = {"AssetRegistry.bin"}; // Stage any loose files in the root folder SC.StageFiles(StagedFileType.UFS, PlatformCookDir, "*", false, ExcludeWildCards, SC.RelativeProjectRootForStage, true, !Params.UsePak(SC.StageTargetPlatform)); // Stage each sub directory separately so that we can skip Engine if need be string[] SubDirs = CommandUtils.FindDirectories(true, "*", false, new string[] { PlatformCookDir }); foreach (string SubDir in SubDirs) { // Dedicated server cook doesn't save shaders so no Engine dir is created if ((!SC.DedicatedServer) && (!Params.DLCIncludeEngineContent) && CommandUtils.GetLastDirectoryName(SubDir).Equals("Engine", StringComparison.InvariantCultureIgnoreCase)) { continue; } // SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.ProjectRoot, "Plugins", DLCName, "Saved", "Cooked", SC.CookPlatform), "*", true, new[] { CommandUtils.CombinePaths("Engine", "*") }, "", true, !Params.UsePak(SC.StageTargetPlatform)); string MountPoint = SubDir.Substring(PlatformCookDir.Length); if ( MountPoint.StartsWith("\\") || MountPoint.StartsWith("/") ) { MountPoint = MountPoint.Substring(1); } SC.StageFiles(StagedFileType.UFS, SubDir, "*", true, ExcludeWildCards, MountPoint, true, !Params.UsePak(SC.StageTargetPlatform)); //SC.StageFiles(StagedFileType.UFS, SubDir, "*", true, ExcludeWildCards, SC.RelativeProjectRootForStage, true, !Params.UsePak(SC.StageTargetPlatform)); } return; } ThisPlatform.GetFilesToDeployOrStage(Params, SC); // Stage any extra runtime dependencies from the receipts foreach(StageTarget Target in SC.StageTargets) { SC.StageRuntimeDependenciesFromReceipt(Target.Receipt, Target.RequireFilesExist, Params.UsePak(SC.StageTargetPlatform)); } // Get the build.properties file // this file needs to be treated as a UFS file for casing, but NonUFS for being put into the .pak file // @todo: Maybe there should be a new category - UFSNotForPak string BuildPropertiesPath = CombinePaths(SC.LocalRoot, "Engine/Build"); if (SC.StageTargetPlatform.DeployLowerCaseFilenames(true)) { BuildPropertiesPath = BuildPropertiesPath.ToLowerInvariant(); } SC.StageFiles(StagedFileType.NonUFS, BuildPropertiesPath, "Build.version", false, null, null, true); // move the UE4Commandline.txt file to the root of the stage // this file needs to be treated as a UFS file for casing, but NonUFS for being put into the .pak file // @todo: Maybe there should be a new category - UFSNotForPak string CommandLineFile = "UE4CommandLine.txt"; if (SC.StageTargetPlatform.DeployLowerCaseFilenames(true)) { CommandLineFile = CommandLineFile.ToLowerInvariant(); } SC.StageFiles(StagedFileType.NonUFS, GetIntermediateCommandlineDir(SC), CommandLineFile, false, null, "", true, false); ConfigCacheIni PlatformGameConfig = ConfigCacheIni.CreateConfigCacheIni(SC.StageTargetPlatform.IniPlatformType, "Game", new DirectoryReference(CommandUtils.GetDirectoryName(Params.RawProjectPath.FullName))); var ProjectContentRoot = CombinePaths(SC.ProjectRoot, "Content"); var StageContentRoot = CombinePaths(SC.RelativeProjectRootForStage, "Content"); if (!Params.CookOnTheFly && !Params.SkipCookOnTheFly) // only stage the UFS files if we are not using cook on the fly { // Initialize internationalization preset. string InternationalizationPreset = null; // Use parameters if provided. if (string.IsNullOrEmpty(InternationalizationPreset)) { InternationalizationPreset = Params.InternationalizationPreset; } // Use configuration if otherwise lacking an internationalization preset. if (string.IsNullOrEmpty(InternationalizationPreset)) { if (PlatformGameConfig != null) { PlatformGameConfig.GetString("/Script/UnrealEd.ProjectPackagingSettings", "InternationalizationPreset", out InternationalizationPreset); } } // Error if no preset has been provided. if (string.IsNullOrEmpty(InternationalizationPreset)) { throw new AutomationException("No internationalization preset was specified for packaging. This will lead to fatal errors when launching. Specify preset via commandline (-I18NPreset=) or project packaging settings (InternationalizationPreset)."); } // Initialize cultures to stage. List<string> CulturesToStage = null; // Use parameters if provided. if (Params.CulturesToCook != null && Params.CulturesToCook.Count > 0) { CulturesToStage = Params.CulturesToCook; } // Use configuration if otherwise lacking cultures to stage. if (CulturesToStage == null || CulturesToStage.Count == 0) { if (PlatformGameConfig != null) { PlatformGameConfig.GetArray("/Script/UnrealEd.ProjectPackagingSettings", "CulturesToStage", out CulturesToStage); } } // Error if no cultures have been provided. if (CulturesToStage == null || CulturesToStage.Count == 0) { throw new AutomationException("No cultures were specified for cooking and packaging. This will lead to fatal errors when launching. Specify culture codes via commandline (-CookCultures=) or using project packaging settings (+CulturesToStage)."); } // Stage ICU internationalization data from Engine. SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.LocalRoot, "Engine", "Content", "Internationalization", InternationalizationPreset), "*", true, null, CombinePaths("Engine", "Content", "Internationalization"), true, !Params.UsePak(SC.StageTargetPlatform)); // Engine ufs (content) SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.LocalRoot, "Engine/Config"), "*", true, null, null, false, !Params.UsePak(SC.StageTargetPlatform)); // TODO: Exclude localization data generation config files. foreach (string Culture in CulturesToStage) { StageLocalizationDataForCulture(SC, Culture, CombinePaths(SC.LocalRoot, "Engine/Content/Localization/Engine"), null, !Params.UsePak(SC.StageTargetPlatform)); } // Game ufs (content) SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.ProjectRoot), "*.uproject", false, null, CombinePaths(SC.RelativeProjectRootForStage), true, !Params.UsePak(SC.StageTargetPlatform)); if (SC.StageTargetPlatform.PlatformType != UnrealTargetPlatform.HTML5 && SC.bUseWebsocketNetDriver) { var EngineIniPath = Path.Combine(SC.ProjectRoot, "Config", "DefaultEngine.ini"); var IntermediateEngineIniDir = Path.Combine(GetIntermediateCommandlineDir(SC), SC.RelativeProjectRootForStage, "Config"); Directory.CreateDirectory(IntermediateEngineIniDir); var IntermediateEngineIniPath = Path.Combine(IntermediateEngineIniDir, "DefaultEngine.ini"); List<String> IniLines = new List<String>(); if (File.Exists(EngineIniPath)) { IniLines = File.ReadAllLines(EngineIniPath).ToList(); } IniLines.Add("[/Script/Engine.GameEngine]"); IniLines.Add("!NetDriverDefinitions=ClearArray"); IniLines.Add("+NetDriverDefinitions=(DefName=\"GameNetDriver\", DriverClassName=\"/Script/HTML5Networking.WebSocketNetDriver\", DriverClassNameFallback=\"/Script/HTML5Networking.WebSocketNetDriver\")"); File.WriteAllLines(IntermediateEngineIniPath, IniLines); SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.ProjectRoot, "Config"), "*", true, new string[] {"DefaultEngine.ini"}, CombinePaths(SC.RelativeProjectRootForStage, "Config"), true, !Params.UsePak(SC.StageTargetPlatform)); // TODO: Exclude localization data generation config files. SC.StageFiles(StagedFileType.UFS, IntermediateEngineIniDir, "*.ini", true, null, CombinePaths(SC.RelativeProjectRootForStage, "Config"), true, !Params.UsePak(SC.StageTargetPlatform)); // TODO: Exclude localization data generation config files. } else { SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.ProjectRoot, "Config"), "*", true, null, CombinePaths(SC.RelativeProjectRootForStage, "Config"), true, !Params.UsePak(SC.StageTargetPlatform)); // TODO: Exclude localization data generation config files. } // Stage all project localization targets { var ProjectLocRootDirectory = CombinePaths(SC.ProjectRoot, "Content/Localization"); if (DirectoryExists(ProjectLocRootDirectory)) { string[] ProjectLocTargetDirectories = CommandUtils.FindDirectories(true, "*", false, new string[] { ProjectLocRootDirectory }); foreach (string ProjectLocTargetDirectory in ProjectLocTargetDirectories) { foreach (string Culture in CulturesToStage) { StageLocalizationDataForCulture(SC, Culture, ProjectLocTargetDirectory, null, !Params.UsePak(SC.StageTargetPlatform)); } } } } // Stage all plugin localization targets { ProjectDescriptor Project = ProjectDescriptor.FromFile(SC.RawProjectPath.FullName); List<PluginInfo> AvailablePlugins = Plugins.ReadAvailablePlugins(new DirectoryReference(CombinePaths(SC.LocalRoot, "Engine")), new FileReference(CombinePaths(SC.ProjectRoot, Params.ShortProjectName + ".uproject")), Project.AdditionalPluginDirectories); foreach (var Plugin in AvailablePlugins) { if (!UProjectInfo.IsPluginEnabledForProject(Plugin, Project, SC.StageTargetPlatform.PlatformType, TargetRules.TargetType.Game) && UProjectInfo.IsPluginEnabledForProject(Plugin, Project, SC.StageTargetPlatform.PlatformType, TargetRules.TargetType.Client)) { // skip editor plugins continue; } if (Plugin.Descriptor.LocalizationTargets == null || Plugin.Descriptor.LocalizationTargets.Length == 0) { // skip plugins with no localization targets continue; } foreach (var LocalizationTarget in Plugin.Descriptor.LocalizationTargets) { if (LocalizationTarget.LoadingPolicy != LocalizationTargetDescriptorLoadingPolicy.Always && LocalizationTarget.LoadingPolicy != LocalizationTargetDescriptorLoadingPolicy.Game) { // skip targets not loaded by the game continue; } var PluginLocTargetDirectory = CombinePaths(Plugin.Directory.FullName, "Content", "Localization", LocalizationTarget.Name); if (DirectoryExists(PluginLocTargetDirectory)) { foreach (string Culture in CulturesToStage) { StageLocalizationDataForCulture(SC, Culture, PluginLocTargetDirectory, null, !Params.UsePak(SC.StageTargetPlatform)); } } } } } // Stage any additional UFS and NonUFS paths specified in the project ini files; these dirs are relative to the game content directory if (PlatformGameConfig != null) { List<string> ExtraUFSDirs; if (PlatformGameConfig.GetArray("/Script/UnrealEd.ProjectPackagingSettings", "DirectoriesToAlwaysStageAsUFS", out ExtraUFSDirs)) { // Each string has the format '(Path="TheDirToStage")' foreach (var PathStr in ExtraUFSDirs) { var PathParts = PathStr.Split('"'); if (PathParts.Length == 3) { var RelativePath = PathParts[1]; SC.StageFiles(StagedFileType.UFS, CombinePaths(ProjectContentRoot, RelativePath), "*", true, new string[] { "*.uasset", "*.umap" }, CombinePaths(StageContentRoot, RelativePath), true, !Params.UsePak(SC.StageTargetPlatform)); } else if (PathParts.Length == 1) { var RelativePath = PathParts[0]; SC.StageFiles(StagedFileType.UFS, CombinePaths(ProjectContentRoot, RelativePath), "*", true, new string[] { "*.uasset", "*.umap" }, CombinePaths(StageContentRoot, RelativePath), true, !Params.UsePak(SC.StageTargetPlatform)); } } } List<string> ExtraNonUFSDirs; if (PlatformGameConfig.GetArray("/Script/UnrealEd.ProjectPackagingSettings", "DirectoriesToAlwaysStageAsNonUFS", out ExtraNonUFSDirs)) { // Each string has the format '(Path="TheDirToStage")' // NonUFS files are never in pak files and should always be remapped foreach (var PathStr in ExtraNonUFSDirs) { var PathParts = PathStr.Split('"'); if (PathParts.Length == 3) { var RelativePath = PathParts[1]; SC.StageFiles(StagedFileType.NonUFS, CombinePaths(ProjectContentRoot, RelativePath), "*", true, null, CombinePaths(StageContentRoot, RelativePath), true, true); } else if (PathParts.Length == 1) { var RelativePath = PathParts[0]; SC.StageFiles(StagedFileType.NonUFS, CombinePaths(ProjectContentRoot, RelativePath), "*", true, null, CombinePaths(StageContentRoot, RelativePath), true, true); } } } } StagedFileType StagedFileTypeForMovies = StagedFileType.NonUFS; if (Params.FileServer) { // UFS is required when using a file server StagedFileTypeForMovies = StagedFileType.UFS; } if (SC.StageTargetPlatform.StageMovies && !SC.DedicatedServer) { bool bRemap = (StagedFileTypeForMovies == StagedFileType.NonUFS); SC.StageFiles(StagedFileTypeForMovies, CombinePaths(SC.LocalRoot, "Engine/Content/Movies"), "*", true, new string[] { "*.uasset", "*.umap" }, CombinePaths(SC.RelativeProjectRootForStage, "Engine/Content/Movies"), true, bRemap); SC.StageFiles(StagedFileTypeForMovies, CombinePaths(SC.ProjectRoot, "Content/Movies"), "*", true, new string[] { "*.uasset", "*.umap" }, CombinePaths(SC.RelativeProjectRootForStage, "Content/Movies"), true, bRemap); } // eliminate the sand box SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.ProjectRoot, "Saved", "Cooked", SC.CookPlatform), "*", true, new string[] { "*.json" }, "", true, !Params.UsePak(SC.StageTargetPlatform)); // CrashReportClient is a standalone slate app that does not look in the generated pak file, so it needs the Content/Slate and Shaders/StandaloneRenderer folders Non-UFS // @todo Make CrashReportClient more portable so we don't have to do this if (SC.bStageCrashReporter && UnrealBuildTool.UnrealBuildTool.PlatformSupportsCrashReporter(SC.StageTargetPlatform.PlatformType)) { //If the .dat file needs to be staged as NonUFS for non-Windows/Linux hosts we need to change the casing as we do with the build properties file above. SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Content/Slate")); SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Shaders/StandaloneRenderer")); SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine", "Content", "Internationalization", InternationalizationPreset), "*", true, null, CombinePaths("Engine", "Content", "Internationalization"), false, true); // Get the architecture in use string Architecture = Params.SpecifiedArchitecture; if (string.IsNullOrEmpty(Architecture)) { Architecture = ""; var BuildPlatform = UEBuildPlatform.GetBuildPlatform(SC.StageTargetPlatform.PlatformType, true); if (BuildPlatform != null) { Architecture = BuildPlatform.CreateContext(Params.RawProjectPath).GetActiveArchitecture(); } } // Get the target receipt path for CrashReportClient DirectoryReference EngineDir = new DirectoryReference(CombinePaths(SC.LocalRoot, "Engine")); string ReceiptFileName = TargetReceipt.GetDefaultPath(EngineDir.FullName, "CrashReportClient", SC.StageTargetPlatform.PlatformType, UnrealTargetConfiguration.Shipping, Architecture); if (!File.Exists(ReceiptFileName)) { throw new AutomationException(ExitCode.Error_MissingExecutable, "Stage Failed. Missing receipt '{0}'. Check that this target has been built.", Path.GetFileName(ReceiptFileName)); } // Read the receipt for this target TargetReceipt Receipt; if (!TargetReceipt.TryRead(ReceiptFileName, out Receipt)) { throw new AutomationException("Missing or invalid target receipt ({0})", ReceiptFileName); } // Stage any runtime dependencies for CrashReportClient Receipt.ExpandPathVariables(EngineDir, EngineDir); SC.StageRuntimeDependenciesFromReceipt(Receipt, true, Params.UsePak(SC.StageTargetPlatform)); // Add config files. SC.StageFiles( StagedFileType.NonUFS, CombinePaths( SC.LocalRoot, "Engine/Programs/CrashReportClient/Config" ) ); } } else { if (PlatformGameConfig != null) { List<string> ExtraNonUFSDirs; if (PlatformGameConfig.GetArray("/Script/UnrealEd.ProjectPackagingSettings", "DirectoriesToAlwaysStageAsNonUFS", out ExtraNonUFSDirs)) { // Each string has the format '(Path="TheDirToStage")' foreach (var PathStr in ExtraNonUFSDirs) { var PathParts = PathStr.Split('"'); if (PathParts.Length == 3) { var RelativePath = PathParts[1]; SC.StageFiles(StagedFileType.NonUFS, CombinePaths(ProjectContentRoot, RelativePath)); } else if (PathParts.Length == 1) { var RelativePath = PathParts[0]; SC.StageFiles(StagedFileType.UFS, CombinePaths(ProjectContentRoot, RelativePath), "*", true, null, CombinePaths(StageContentRoot, RelativePath), true, !Params.UsePak(SC.StageTargetPlatform)); } } } } } }
public override void GetFilesToDeployOrStage(ProjectParams Params, DeploymentContext SC) { if (UnrealBuildTool.BuildHostPlatform.Current.Platform != UnrealTargetPlatform.Mac) { // copy the icons/launch screens from the engine { string SourcePath = CombinePaths(SC.LocalRoot, "Engine", "Build", "IOS", "Resources", "Graphics"); SC.StageFiles(StagedFileType.NonUFS, SourcePath, "*.png", false, null, "", true, false); } // copy any additional framework assets that will be needed at runtime { string SourcePath = CombinePaths( ( SC.IsCodeBasedProject ? SC.ProjectRoot : SC.LocalRoot + "\\Engine" ), "Intermediate", "IOS", "FrameworkAssets" ); if ( Directory.Exists( SourcePath ) ) { SC.StageFiles( StagedFileType.NonUFS, SourcePath, "*.*", true, null, "", true, false ); } } // copy the icons/launch screens from the game (may stomp the engine copies) { string SourcePath = CombinePaths(SC.ProjectRoot, "Build", "IOS", "Resources", "Graphics"); SC.StageFiles(StagedFileType.NonUFS, SourcePath, "*.png", false, null, "", true, false); } // copy the plist (only if code signing, as it's protected by the code sign blob in the executable and can't be modified independently) if (GetCodeSignDesirability(Params)) { string SourcePListFile = CombinePaths(SC.LocalRoot, "Engine", "Build", "IOS", "UE4Game-Info.plist"); if (File.Exists(SC.ProjectRoot + "/Build/IOS/Info.plist")) { SourcePListFile = CombinePaths(SC.ProjectRoot, "Build", "IOS", "Info.plist"); } else if (File.Exists(SC.ProjectRoot + "/Build/IOS/" + SC.ShortProjectName + "-Info.plist")) { SourcePListFile = CombinePaths(SC.ProjectRoot, "Build", "IOS", SC.ShortProjectName + "-Info.plist"); } else if (Directory.Exists(SC.ProjectRoot + "/Build/IOS")) { // look for any plist file string[] Plists = Directory.GetFiles(SC.ProjectRoot + "/Build/IOS", "*.plist"); if (Plists.Length > 0) { SourcePListFile = Plists[0]; } } //@TODO: This is writing to the engine directory! string SourcePath = CombinePaths((SC.IsCodeBasedProject ? SC.ProjectRoot : SC.LocalRoot + "\\Engine"), "Intermediate", "IOS"); string TargetPListFile = Path.Combine(SourcePath, (SC.IsCodeBasedProject ? SC.ShortProjectName : "UE4Game") + "-Info.plist"); Dictionary<string, string> Replacements = new Dictionary<string, string>(); Replacements.Add("${EXECUTABLE_NAME}", (SC.IsCodeBasedProject ? SC.ShortProjectName : "UE4Game")); Replacements.Add("${BUNDLE_IDENTIFIER}", SC.ShortProjectName.Replace("_", "")); CopyFileWithReplacements(SourcePListFile, TargetPListFile, Replacements); SC.StageFiles(StagedFileType.NonUFS, SourcePath, Path.GetFileName(TargetPListFile), false, null, "", false, false, "Info.plist"); } } // copy the movies from the project { SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Build/IOS/Resources/Movies"), "*", false, null, "", true, false); SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Content/Movies"), "*", true, null, "", true, false); } // stage required icu files SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.LocalRoot, "Engine/Content/Localization/ICU"), "*", true, null, null, false, !Params.UsePak(SC.StageTargetPlatform)); }
public override void GetFilesToDeployOrStage(ProjectParams Params, DeploymentContext SC) { // Engine non-ufs (binaries) if (SC.bStageCrashReporter) { StageExecutable("exe", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries", SC.PlatformDir), "CrashReportClient."); } //todo we need to support shipping and test executables //todo this should all be partially based on UBT manifests and not hard coded //monolithic assumption StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/Ogg", SC.PlatformDir), "*.", true); StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/Vorbis", SC.PlatformDir), "*.", true); string PhysXVer = "VS" + WindowsPlatform.GetVisualStudioCompilerVersionName(); string ApexVer = "VS" + WindowsPlatform.GetVisualStudioCompilerVersionName(); string PhysXMaskForDebugConfiguration = Params.bDebugBuildsActuallyUseDebugCRT ? "*DEBUG*.*" : "*PROFILE*.*"; if (SC.StageTargetConfigurations.Contains(UnrealTargetConfiguration.Debug) && !Params.Rocket) { StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/PhysX/APEX-1.3", SC.PlatformDir, ApexVer), PhysXMaskForDebugConfiguration, true); StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/PhysX/PhysX-3.3", SC.PlatformDir, PhysXVer), PhysXMaskForDebugConfiguration, true); StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/PhysX/PhysX-3.3", SC.PlatformDir, PhysXVer), "nvToolsExt*.", true); } if (SC.StageTargetConfigurations.Any(x => x != UnrealTargetConfiguration.Debug) || Params.Rocket) { StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/PhysX/APEX-1.3", SC.PlatformDir, ApexVer), "*.", true, new string[] { "*DEBUG*.*", "*CHECKED*.*" }); StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/PhysX/PhysX-3.3", SC.PlatformDir, PhysXVer), "*.", true, new string[] { "*DEBUG*.*", "*CHECKED*.*" }); } if (Params.bUsesSteam) { string SteamVersion = "Steamv130"; // Check that the TPS directory exists. We don't distribute binaries for Steam in Rocket. if (Directory.Exists(CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/Steamworks/" + SteamVersion))) { if (SC.StageTargetPlatform.PlatformType == UnrealTargetPlatform.Win32) { StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/Steamworks/" + SteamVersion, SC.PlatformDir), "steam_api."); if (SC.DedicatedServer) { StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/Steamworks/" + SteamVersion, SC.PlatformDir), "steamclient."); StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/Steamworks/" + SteamVersion, SC.PlatformDir), "tier0_s."); StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/Steamworks/" + SteamVersion, SC.PlatformDir), "vstdlib_s."); } } else { StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/Steamworks/" + SteamVersion, SC.PlatformDir), "steam_api64."); if (SC.DedicatedServer) { StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/Steamworks/" + SteamVersion, SC.PlatformDir), "steamclient64."); StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/Steamworks/" + SteamVersion, SC.PlatformDir), "tier0_s64."); StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/Steamworks/" + SteamVersion, SC.PlatformDir), "vstdlib_s64."); } } } } // Copy the splash screen, windows specific SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Content/Splash"), "Splash.bmp", false, null, null, true); SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.LocalRoot, "Engine/Content/Localization/ICU"), "*", true, null, null, false, !Params.UsePak(SC.StageTargetPlatform)); if (Params.StageNonMonolithic) { if (SC.DedicatedServer) { StageExecutable("exe", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries", SC.PlatformDir), "UE4Server."); StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries", SC.PlatformDir), "UE4Server-*."); StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Plugins"), "UE4Server-*.", true); StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.ProjectRoot, "Binaries", SC.PlatformDir), "UE4Server-*."); StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.ProjectRoot, "Plugins"), "UE4Server-*.", true); StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/ICU/icu4c-53_1", SC.PlatformDir, "VS2013"), "*."); } else { StageExecutable("exe", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries", SC.PlatformDir), "UE4."); StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries", SC.PlatformDir), "UE4-*."); StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Plugins"), "UE4-*.", true); StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.ProjectRoot, "Binaries", SC.PlatformDir), "UE4-*."); StageExecutable("dll", SC, CommandUtils.CombinePaths(SC.ProjectRoot, "Plugins"), "UE4-*.", true); } } else { List<string> Exes = GetExecutableNames(SC); // the first exe is the "main" one, the rest are marked as debug files StagedFileType WorkingFileType = StagedFileType.NonUFS; foreach (var Exe in Exes) { if (Exe.StartsWith(CombinePaths(SC.RuntimeProjectRootDir, "Binaries", SC.PlatformDir))) { // remap the project root. string SourceFile = CombinePaths(SC.ProjectRoot, "Binaries", SC.PlatformDir, Path.GetFileName(Exe)); StageExecutable("exe", SC, Path.GetDirectoryName(SourceFile), Path.GetFileNameWithoutExtension(SourceFile) + ".", true, null, CommandUtils.CombinePaths(SC.RelativeProjectRootForStage, "Binaries", SC.PlatformDir), false, WorkingFileType); if(Exe == Exes[0]) { StageBootstrapExecutable(SC, SourceFile, CombinePaths(SC.RelativeProjectRootForStage, "Binaries", SC.PlatformDir, Path.GetFileName(Exe)), ""); } } else if (Exe.StartsWith(CombinePaths(SC.RuntimeRootDir, "Engine/Binaries", SC.PlatformDir))) { // keep it in the engine directory. string SourceFile = CombinePaths(SC.LocalRoot, "Engine", "Binaries", SC.PlatformDir, Path.GetFileName(Exe)); StageExecutable("exe", SC, CombinePaths(SC.LocalRoot, "Engine/Binaries", SC.PlatformDir), Path.GetFileNameWithoutExtension(SourceFile) + ".", true, null, null, false, WorkingFileType); if(Exe == Exes[0]) { StageBootstrapExecutable(SC, SourceFile, CombinePaths("Engine", "Binaries", SC.PlatformDir, Path.GetFileName(Exe)), String.Format("..\\..\\..\\{0}\\{0}.uproject", SC.ShortProjectName)); } } else { throw new AutomationException("Can't stage the exe {0} because it doesn't start with {1} or {2}", Exe, CombinePaths(SC.RuntimeProjectRootDir, "Binaries", SC.PlatformDir), CombinePaths(SC.RuntimeRootDir, "Engine/Binaries", SC.PlatformDir)); } // the first exe is the "main" one, the rest are marked as debug files WorkingFileType = StagedFileType.DebugNonUFS; } } }
public override void GetFilesToDeployOrStage(ProjectParams Params, DeploymentContext SC) { if (SC.bStageCrashReporter) { SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Binaries", SC.PlatformDir), "CrashReportClient", false); } { SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/ICU/icu4c-53_1/", SC.PlatformDir, "x86_64-unknown-linux-gnu"), Params.bDebugBuildsActuallyUseDebugCRT ? "*d.so*" : "*.so*", false, new[] { Params.bDebugBuildsActuallyUseDebugCRT ? "*.so*" : "*d.so*" }, CombinePaths("Engine/Binaries", SC.PlatformDir)); } // assume that we always have to deploy Steam (FIXME: should be automatic) { string SteamVersion = "Steamv130"; // Check if the Steam directory exists. We need it for Steam controller support, so we include it whenever we can. if (Directory.Exists(CommandUtils.CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/Steamworks/" + SteamVersion))) { SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/Steamworks/" + SteamVersion, SC.PlatformDir), "libsteam_api.so", false, null, CombinePaths("Engine/Binaries", SC.PlatformDir)); } SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Config"), "controller.vdf", false, null, CommandUtils.CombinePaths(SC.RelativeProjectRootForStage, "Saved/Config")); // copy optional perfcounters definition file SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Config"), "PerfCounters.json", false, null, CommandUtils.CombinePaths(SC.RelativeProjectRootForStage, "Saved/Config"), true); } // assume that we always have to deploy OpenAL (FIXME: should be automatic) { SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Binaries/ThirdParty/OpenAL/", SC.PlatformDir), "libopenal.so.1", false, null, CombinePaths("Engine/Binaries", SC.PlatformDir)); } SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Content/Splash"), "Splash.bmp", false, null, null, true); SC.StageFiles(StagedFileType.UFS, CombinePaths(SC.LocalRoot, "Engine/Content/Localization/ICU"), "*", true, null, null, false, !Params.UsePak(SC.StageTargetPlatform)); if (Params.StageNonMonolithic) { if (SC.DedicatedServer) { SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Binaries", SC.PlatformDir), "UE4Server"); SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Binaries", SC.PlatformDir), "libUE4Server-*.so"); SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Plugins"), "libUE4Server-*.so", true, null, null, true); SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Binaries", SC.PlatformDir), "libUE4Server-*.so"); SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Plugins"), "libUE4Server-*.so", true, null, null, true); } else { SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Binaries", SC.PlatformDir), "UE4"); SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Binaries", SC.PlatformDir), "libUE4-*.so"); SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Plugins"), "libUE4-*.so", true, null, null, true); SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Binaries", SC.PlatformDir), "libUE4-*.so"); SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Plugins"), "libUE4-*.so", true, null, null, true); } } else { List<string> Exes = GetExecutableNames(SC); foreach (var Exe in Exes) { if (Exe.StartsWith(CombinePaths(SC.RuntimeProjectRootDir, "Binaries", SC.PlatformDir))) { // remap the project root. For content-only projects, rename the executable to the project name. if (!Params.IsCodeBasedProject && Exe == Exes[0]) { SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Binaries", SC.PlatformDir), Path.GetFileNameWithoutExtension(Exe), true, null, CommandUtils.CombinePaths(SC.RelativeProjectRootForStage, "Binaries", SC.PlatformDir), false, true, SC.ShortProjectName); } else { SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.ProjectRoot, "Binaries", SC.PlatformDir), Path.GetFileNameWithoutExtension(Exe), true, null, CommandUtils.CombinePaths(SC.RelativeProjectRootForStage, "Binaries", SC.PlatformDir), false); } } else if (Exe.StartsWith(CombinePaths(SC.RuntimeRootDir, "Engine/Binaries", SC.PlatformDir))) { // Move the executable for content-only projects into the project directory, using the project name, so it can figure out the UProject to look for and is consistent with code projects. if (!Params.IsCodeBasedProject && Exe == Exes[0]) { SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Binaries", SC.PlatformDir), Path.GetFileNameWithoutExtension(Exe), true, null, CommandUtils.CombinePaths(SC.RelativeProjectRootForStage, "Binaries", SC.PlatformDir), false, true, SC.ShortProjectName); } else { SC.StageFiles(StagedFileType.NonUFS, CombinePaths(SC.LocalRoot, "Engine/Binaries", SC.PlatformDir), Path.GetFileNameWithoutExtension(Exe), true, null, null, false); } } else { throw new AutomationException("Can't stage the exe {0} because it doesn't start with {1} or {2}", Exe, CombinePaths(SC.RuntimeProjectRootDir, "Binaries", SC.PlatformDir), CombinePaths(SC.RuntimeRootDir, "Engine/Binaries", SC.PlatformDir)); } } } }