/// <summary> /// Stage a single file to its default location /// </summary> /// <param name="FileType">The type of file being staged</param> /// <param name="InputFile">Path to the file</param> public void StageFile(StagedFileType FileType, FileReference InputFile) { StagedFileReference OutputFile; if (InputFile.IsUnderDirectory(ProjectRoot)) { OutputFile = StagedFileReference.Combine(RelativeProjectRootForStage, InputFile.MakeRelativeTo(ProjectRoot)); } else if (InputFile.HasExtension(".uplugin")) { if (InputFile.IsUnderDirectory(EngineRoot)) { OutputFile = new StagedFileReference(InputFile.MakeRelativeTo(LocalRoot)); } else { // This is a plugin that lives outside of the Engine/Plugins or Game/Plugins directory so needs to be remapped for staging/packaging // We need to remap C:\SomePath\PluginName\PluginName.uplugin to RemappedPlugins\PluginName\PluginName.uplugin OutputFile = new StagedFileReference(String.Format("RemappedPlugins/{0}/{1}", InputFile.GetFileNameWithoutExtension(), InputFile.GetFileName())); } } else if (InputFile.IsUnderDirectory(LocalRoot)) { OutputFile = new StagedFileReference(InputFile.MakeRelativeTo(LocalRoot)); } else { throw new AutomationException("Can't deploy {0} because it doesn't start with {1} or {2}", InputFile, ProjectRoot, LocalRoot); } StageFile(FileType, InputFile, OutputFile); }
/// <summary> /// Gets the default location to stage an input file /// </summary> /// <param name="InputFile">Location of the file in the file system</param> /// <returns>Staged file location</returns> public StagedFileReference GetStagedFileLocation(FileReference InputFile) { StagedFileReference OutputFile; if (InputFile.IsUnderDirectory(ProjectRoot)) { OutputFile = StagedFileReference.Combine(RelativeProjectRootForStage, InputFile.MakeRelativeTo(ProjectRoot)); } else if (InputFile.HasExtension(".uplugin")) { DirectoryReference EnterpriseRoot = DirectoryReference.Combine(EngineRoot, "..", "Enterprise"); // Enterprise plugins aren't under the project additional plugin directories, so they shouldn't be remapped if (InputFile.IsUnderDirectory(EngineRoot) || InputFile.IsUnderDirectory(EnterpriseRoot)) { OutputFile = new StagedFileReference(InputFile.MakeRelativeTo(LocalRoot)); } else { // This is a plugin that lives outside of the Engine/Plugins or Game/Plugins directory so needs to be remapped for staging/packaging // We need to remap C:\SomePath\PluginName\PluginName.uplugin to RemappedPlugins\PluginName\PluginName.uplugin OutputFile = new StagedFileReference(String.Format("RemappedPlugins/{0}/{1}", InputFile.GetFileNameWithoutExtension(), InputFile.GetFileName())); } } else if (InputFile.IsUnderDirectory(LocalRoot)) { OutputFile = new StagedFileReference(InputFile.MakeRelativeTo(LocalRoot)); } else { throw new AutomationException("Can't deploy {0} because it doesn't start with {1} or {2}", InputFile, ProjectRoot, LocalRoot); } return(OutputFile); }
/// <summary> /// Stage multiple files /// </summary> /// <param name="FileType">The type for the staged files</param> /// <param name="Files">The files to stage</param> public void StageFiles(StagedFileType FileType, DirectoryReference InputDir, IEnumerable <FileReference> Files, StagedDirectoryReference OutputDir) { foreach (FileReference File in Files) { StagedFileReference OutputFile = StagedFileReference.Combine(OutputDir, File.MakeRelativeTo(InputDir)); StageFile(FileType, File, OutputFile); } }
/// <summary> /// Stage multiple files for use by crash reporter /// </summary> /// <param name="FileType">The type of the staged file</param> /// <param name="InputDir">Location of the input directory</param> /// <param name="Option">Whether to stage all subdirectories or just the top-level directory</param> /// <param name="OutputDir">Location of the output directory within the staging folder</param> public void StageCrashReporterFiles(StagedFileType FileType, DirectoryReference InputDir, StageFilesSearch Option, StagedDirectoryReference OutputDir) { List <FileReference> InputFiles = FindFilesToStage(InputDir, Option); foreach (FileReference InputFile in InputFiles) { StagedFileReference StagedFile = StagedFileReference.Combine(OutputDir, InputFile.MakeRelativeTo(InputDir)); StageCrashReporterFile(FileType, InputFile, StagedFile); } }
private void StageAppBundle(DeploymentContext SC, DirectoryReference InPath, StagedDirectoryReference NewName) { // Files with DebugFileExtensions should always be DebugNonUFS List <string> DebugExtensions = GetDebugFileExtensions(); foreach (FileReference InputFile in DirectoryReference.EnumerateFiles(InPath, "*", SearchOption.AllDirectories)) { StagedFileReference OutputFile = StagedFileReference.Combine(NewName, InputFile.MakeRelativeTo(InPath)); StagedFileType FileType = DebugExtensions.Any(x => InputFile.HasExtension(x))? StagedFileType.DebugNonUFS : StagedFileType.NonUFS; SC.StageFile(FileType, InputFile, OutputFile); } }
/// <summary> /// Adds a file to be staged as the given type /// </summary> /// <param name="FileType">The type of file to be staged</param> /// <param name="StagedFile">The staged file location</param> /// <param name="InputFile">The input file</param> public void Add(StagedFileType FileType, StagedFileReference StagedFile, FileReference InputFile) { if (FileType == StagedFileType.UFS) { AddToDictionary(UFSStagingFiles, StagedFile, InputFile); } else if (FileType == StagedFileType.NonUFS) { AddToDictionary(NonUFSStagingFiles, StagedFile, InputFile); } else if (FileType == StagedFileType.DebugNonUFS) { AddToDictionary(NonUFSStagingFilesDebug, StagedFile, InputFile); } }
public override void GetFilesToDeployOrStage(ProjectParams Params, DeploymentContext SC) { // Stage all the build products foreach (StageTarget Target in SC.StageTargets) { SC.StageBuildProductsFromReceipt(Target.Receipt, Target.RequireFilesExist, Params.bTreatNonShippingBinariesAsDebugFiles); } if (SC.bStageCrashReporter) { StagedDirectoryReference CrashReportClientPath = StagedDirectoryReference.Combine("Engine/Binaries", SC.PlatformDir, "CrashReportClient.app"); StageAppBundle(SC, DirectoryReference.Combine(SC.LocalRoot, "Engine/Binaries", SC.PlatformDir, "CrashReportClient.app"), CrashReportClientPath); } // Find the app bundle path List <FileReference> Exes = GetExecutableNames(SC); foreach (var Exe in Exes) { StagedDirectoryReference AppBundlePath = null; if (Exe.IsUnderDirectory(DirectoryReference.Combine(SC.RuntimeProjectRootDir, "Binaries", SC.PlatformDir))) { AppBundlePath = StagedDirectoryReference.Combine(SC.ShortProjectName, "Binaries", SC.PlatformDir, Path.GetFileNameWithoutExtension(Exe.FullName) + ".app"); } else if (Exe.IsUnderDirectory(DirectoryReference.Combine(SC.RuntimeRootDir, "Engine/Binaries", SC.PlatformDir))) { AppBundlePath = StagedDirectoryReference.Combine("Engine/Binaries", SC.PlatformDir, Path.GetFileNameWithoutExtension(Exe.FullName) + ".app"); } // Copy the custom icon and Steam dylib, if needed if (AppBundlePath != null) { FileReference AppIconsFile = FileReference.Combine(SC.ProjectRoot, "Build", "Mac", "Application.icns"); if (FileReference.Exists(AppIconsFile)) { SC.StageFile(StagedFileType.NonUFS, AppIconsFile, StagedFileReference.Combine(AppBundlePath, "Contents", "Resources", "Application.icns")); } } } // Copy the splash screen, Mac specific FileReference SplashImage = FileReference.Combine(SC.ProjectRoot, "Content", "Splash", "Splash.bmp"); if (FileReference.Exists(SplashImage)) { SC.StageFile(StagedFileType.NonUFS, SplashImage); } // Stage the bootstrap executable if (!Params.NoBootstrapExe) { foreach (StageTarget Target in SC.StageTargets) { BuildProduct Executable = Target.Receipt.BuildProducts.FirstOrDefault(x => x.Type == BuildProductType.Executable); if (Executable != null) { // only create bootstraps for executables List <StagedFileReference> StagedFiles = SC.FilesToStage.NonUFSFiles.Where(x => x.Value == Executable.Path).Select(x => x.Key).ToList(); if (StagedFiles.Count > 0 && Executable.Path.FullName.Replace("\\", "/").Contains("/" + TargetPlatformType.ToString() + "/")) { string BootstrapArguments = ""; if (!ShouldStageCommandLine(Params, SC)) { if (!SC.IsCodeBasedProject) { BootstrapArguments = String.Format("../../../{0}/{0}.uproject", SC.ShortProjectName); } else { BootstrapArguments = SC.ShortProjectName; } } string BootstrapExeName; if (SC.StageTargetConfigurations.Count > 1) { BootstrapExeName = Path.GetFileName(Executable.Path.FullName) + ".app"; } else if (Params.IsCodeBasedProject) { BootstrapExeName = Target.Receipt.TargetName + ".app"; } else { BootstrapExeName = SC.ShortProjectName + ".app"; } string AppSuffix = ".app" + Path.DirectorySeparatorChar; string AppPath = Executable.Path.FullName.Substring(0, Executable.Path.FullName.LastIndexOf(AppSuffix) + AppSuffix.Length); foreach (var DestPath in StagedFiles) { string AppRelativePath = DestPath.Name.Substring(0, DestPath.Name.LastIndexOf(AppSuffix) + AppSuffix.Length); StageBootstrapExecutable(SC, BootstrapExeName, AppPath, AppRelativePath, BootstrapArguments); } } } } } // Copy the ShaderCache files, if they exist FileReference DrawCacheFile = FileReference.Combine(SC.ProjectRoot, "Content", "DrawCache.ushadercache"); if (FileReference.Exists(DrawCacheFile)) { SC.StageFile(StagedFileType.UFS, DrawCacheFile); } FileReference ByteCodeCacheFile = FileReference.Combine(SC.ProjectRoot, "Content", "ByteCodeCache.ushadercode"); if (FileReference.Exists(ByteCodeCacheFile)) { SC.StageFile(StagedFileType.UFS, ByteCodeCacheFile); } { // Stage any *.metallib files as NonUFS. // Get the final output directory for cooked data DirectoryReference CookOutputDir; if (!String.IsNullOrEmpty(Params.CookOutputDir)) { CookOutputDir = DirectoryReference.Combine(new DirectoryReference(Params.CookOutputDir), SC.CookPlatform); } else if (Params.CookInEditor) { CookOutputDir = DirectoryReference.Combine(SC.ProjectRoot, "Saved", "EditorCooked", SC.CookPlatform); } else { CookOutputDir = DirectoryReference.Combine(SC.ProjectRoot, "Saved", "Cooked", SC.CookPlatform); } if (DirectoryReference.Exists(CookOutputDir)) { List <FileReference> CookedFiles = DirectoryReference.EnumerateFiles(CookOutputDir, "*.metallib", SearchOption.AllDirectories).ToList(); foreach (FileReference CookedFile in CookedFiles) { SC.StageFile(StagedFileType.NonUFS, CookedFile, new StagedFileReference(CookedFile.MakeRelativeTo(CookOutputDir))); } } } }
/// <summary> /// Adds a file to be staged to the given dictionary /// </summary> /// <param name="FilesToStage">Dictionary of files to be staged</param> /// <param name="StagedFile">The staged file location</param> /// <param name="InputFile">The input file</param> private void AddToDictionary(Dictionary <StagedFileReference, FileReference> FilesToStage, StagedFileReference StagedFile, FileReference InputFile) { FilesToStage[StagedFile] = InputFile; }
/// <summary> /// Stages a file for use by crash reporter. /// </summary> /// <param name="FileType">The type of the staged file</param> /// <param name="InputFile">Location of the input file</param> /// <param name="StagedFile">Location of the file in the staging directory</param> public void StageCrashReporterFile(StagedFileType FileType, FileReference InputFile, StagedFileReference StagedFile) { if (FileType == StagedFileType.UFS) { CrashReporterUFSFiles[StagedFile] = InputFile; } else { StageFile(FileType, InputFile, StagedFile); } }
/// <summary> /// Stage a single file /// </summary> /// <param name="FileType">The type for the staged file</param> /// <param name="InputFile">The source file</param> /// <param name="OutputFile">The staged file location</param> public void StageFile(StagedFileType FileType, FileReference InputFile, StagedFileReference OutputFile) { FilesToStage.Add(FileType, OutputFile, InputFile); }
/// <summary> /// Stage a single file to its default location /// </summary> /// <param name="FileType">The type of file being staged</param> /// <param name="InputFile">Path to the file</param> public void StageFile(StagedFileType FileType, FileReference InputFile) { StagedFileReference OutputFile = GetStagedFileLocation(InputFile); StageFile(FileType, InputFile, OutputFile); }
/// <summary> /// Remaps the given content directory to its final location /// </summary> public virtual StagedFileReference Remap(StagedFileReference Dest) { return(Dest); }
void StageBootstrapExecutable(DeploymentContext SC, string ExeName, FileReference TargetFile, StagedFileReference StagedRelativeTargetPath, string StagedArguments) { FileReference InputFile = FileReference.Combine(SC.LocalRoot, "Engine", "Binaries", SC.PlatformDir, String.Format("BootstrapPackagedGame-{0}-Shipping.exe", SC.PlatformDir)); if (FileReference.Exists(InputFile)) { // Create the new bootstrap program DirectoryReference IntermediateDir = DirectoryReference.Combine(SC.ProjectRoot, "Intermediate", "Staging"); DirectoryReference.CreateDirectory(IntermediateDir); FileReference IntermediateFile = FileReference.Combine(IntermediateDir, ExeName); CommandUtils.CopyFile(InputFile.FullName, IntermediateFile.FullName); CommandUtils.SetFileAttributes(IntermediateFile.FullName, ReadOnly: false); // currently the icon updating doesn't run under mono if (UnrealBuildTool.BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Win64 || UnrealBuildTool.BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Win32) { // Get the icon from the build directory if possible GroupIconResource GroupIcon = null; if (FileReference.Exists(FileReference.Combine(SC.ProjectRoot, "Build/Windows/Application.ico"))) { GroupIcon = GroupIconResource.FromIco(FileReference.Combine(SC.ProjectRoot, "Build/Windows/Application.ico").FullName); } if (GroupIcon == null) { GroupIcon = GroupIconResource.FromExe(TargetFile.FullName); } // Update the resources in the new file using (ModuleResourceUpdate Update = new ModuleResourceUpdate(IntermediateFile.FullName, false)) { const int IconResourceId = 101; if (GroupIcon != null) { Update.SetIcons(IconResourceId, GroupIcon); } const int ExecFileResourceId = 201; Update.SetData(ExecFileResourceId, ResourceType.RawData, Encoding.Unicode.GetBytes(StagedRelativeTargetPath + "\0")); const int ExecArgsResourceId = 202; Update.SetData(ExecArgsResourceId, ResourceType.RawData, Encoding.Unicode.GetBytes(StagedArguments + "\0")); } } // Copy it to the staging directory SC.StageFile(StagedFileType.SystemNonUFS, IntermediateFile, new StagedFileReference(ExeName)); } }
public void StageFiles(StagedFileType FileType, DirectoryReference InputDir, string Wildcard = "*", bool bRecursive = true, string[] ExcludeWildcards = null, StagedDirectoryReference NewPath = null, bool bAllowNone = false, bool bRemap = true, string NewName = null, bool bAllowNotForLicenseesFiles = true, bool bStripFilesForOtherPlatforms = true, bool bConvertToLower = false) { int FilesAdded = 0; if (DirectoryReference.Exists(InputDir)) { FileReference[] InputFiles = CommandUtils.FindFiles(Wildcard, bRecursive, InputDir); HashSet <FileReference> ExcludeFiles = new HashSet <FileReference>(); if (ExcludeWildcards != null) { foreach (string ExcludeWildcard in ExcludeWildcards) { ExcludeFiles.UnionWith(CommandUtils.FindFiles(ExcludeWildcard, bRecursive, InputDir)); } } foreach (FileReference InputFile in InputFiles) { if (ExcludeFiles.Contains(InputFile)) { continue; } if (bStripFilesForOtherPlatforms && !bIsCombiningMultiplePlatforms && IsFileForOtherPlatform(InputFile)) { continue; } // Get the staged location for this file StagedFileReference Dest; if (NewPath != null) { // If the specified a new directory, first we deal with that, then apply the other things. This is used to collapse the sandbox, among other things. Dest = StagedFileReference.Combine(NewPath, InputFile.MakeRelativeTo(InputDir)); } else if (InputFile.IsUnderDirectory(ProjectRoot)) { // Project relative file Dest = StagedFileReference.Combine(RelativeProjectRootForStage, InputFile.MakeRelativeTo(ProjectRoot)); } else if (InputFile.IsUnderDirectory(LocalRoot)) { // Engine relative file Dest = new StagedFileReference(InputFile.MakeRelativeTo(LocalRoot)); } else { throw new AutomationException("Can't deploy {0} because it doesn't start with {1} or {2}", InputFile, ProjectRoot, LocalRoot); } if (!bAllowNotForLicenseesFiles && (Dest.ContainsName(new FileSystemName("NotForLicensees")) || Dest.ContainsName(new FileSystemName("NoRedist")))) { continue; } if (NewName != null) { Dest = StagedFileReference.Combine(Dest.Directory, NewName); } if (bRemap) { Dest = StageTargetPlatform.Remap(Dest); } if (bConvertToLower) { Dest = Dest.ToLowerInvariant(); } FilesToStage.Add(FileType, Dest, InputFile); FilesAdded++; } } if (FilesAdded == 0 && !bAllowNone && !bIsCombiningMultiplePlatforms) { throw new AutomationException(ExitCode.Error_StageMissingFile, "No files found to deploy for {0} with wildcard {1} and exclusions {2}", InputDir, Wildcard, String.Join(", ", ExcludeWildcards)); } }