StagingDirectory
StagingDirectory
#Overview
name: StagingDirectory
The value of this variable can be defined or overridden in .ini config files. 2
.ini config files referencing this setting variable.
It is referenced in 27
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of StagingDirectory is to provide a temporary location for storing intermediate files during the installation or patching process in Unreal Engine 5. This variable is used primarily in the Build Patch Services system, which is responsible for managing game updates and installations.
StagingDirectory is relied upon by the Build Patch Services module, which is part of Unreal Engine’s runtime online subsystem. It’s used in various components of this module, including the HTTP Chunk Installer, Mobile Patching Utils, and the core Build Patch Installer.
The value of StagingDirectory is typically set in one of three ways:
- Through the FBuildInstallerConfiguration or FInstallerConfiguration structures.
- By calling the FBuildPatchServicesModule::SetStagingDirectory() function.
- If not explicitly set, it defaults to a “BuildStaging” folder within the project directory.
StagingDirectory interacts with several other variables, including InstallDirectory, BackupDirectory, and CloudDirectories. These variables work together to define the paths used in the installation and patching process.
Developers should be aware of the following when using StagingDirectory:
- Ensure that the specified directory has sufficient disk space for temporary files.
- The staging directory should be on the same drive as the installation directory for optimal performance.
- The path should not exceed the maximum path length limit of the operating system.
Best practices for using StagingDirectory include:
- Use a dedicated directory for staging to avoid conflicts with other processes.
- Clean up the staging directory after the installation process is complete to free up disk space.
- Consider using a configurable path to allow end-users to specify a custom staging location if needed.
- Ensure proper error handling for cases where the staging directory cannot be created or accessed.
By following these guidelines, developers can ensure smooth operation of the Build Patch Services system and provide a better update and installation experience for end-users.
#Setting Variables
#References In INI files
Location: <Workspace>/Engine/Config/BaseGame.ini:159, section: [/Script/DeveloperToolSettings.PlatformsMenuSettings]
- INI Section:
/Script/DeveloperToolSettings.PlatformsMenuSettings
- Raw value:
(Path="")
- Is Array:
False
Location: <Workspace>/Projects/Lyra/Config/DefaultGame.ini:87, section: [/Script/UnrealEd.ProjectPackagingSettings]
- INI Section:
/Script/UnrealEd.ProjectPackagingSettings
- Raw value:
(Path="")
- Is Array:
False
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Plugins/Runtime/HTTPChunkInstaller/Source/Private/HTTPChunkInstaller.cpp:1531
Scope (from outer to inner):
file
function void FHTTPChunkInstall::BeginChunkInstall
Source code excerpt:
BuildPatchServices::FBuildInstallerConfiguration Configuration(MoveTemp(InstallerActions));
Configuration.StagingDirectory = ChunkStageDir;
Configuration.CloudDirectories = { CloudDir + TEXT("/") + CloudDirectory };
Configuration.InstallDirectory = ChunkInstallDir;
UE_LOG(LogHTTPChunkInstaller,Log,TEXT("Starting Chunk %d install"),InstallingChunkID);
InstallService = BPSModule->CreateBuildInstaller(Configuration, FBuildPatchInstallerDelegate::CreateRaw(this, &FHTTPChunkInstall::OSSInstallComplete));
InstallService->StartInstallation();
#Loc: <Workspace>/Engine/Plugins/Runtime/MobilePatchingUtils/Source/MobilePatchingUtils/Private/MobilePatchingLibrary.cpp:301
Scope (from outer to inner):
file
function void UMobilePendingContent::StartInstall
Source code excerpt:
BuildPatchServices::FBuildInstallerConfiguration Configuration(MoveTemp(InstallerActions));
Configuration.StagingDirectory = StageDir;
Configuration.CloudDirectories = { CloudURL };
Configuration.InstallDirectory = InstallDir;
Installer = BuildPatchServices->CreateBuildInstaller(Configuration, FBuildPatchInstallerDelegate::CreateStatic(OnInstallComplete, this, OnSucceeded, OnFailed));
Installer->StartInstallation();
}
#Loc: <Workspace>/Engine/Source/Developer/DeveloperToolSettings/Classes/Settings/PlatformsMenuSettings.h:18
Scope (from outer to inner):
file
class class UPlatformsMenuSettings : public UObject
Source code excerpt:
/** The directory to which the packaged project will be copied. */
UPROPERTY(config, EditAnywhere, Category=Project)
FDirectoryPath StagingDirectory;
/** Name of the target to use for LaunchOn (only Game/Client targets) */
UPROPERTY(config)
FString LaunchOnTarget;
/** Gets the current launch on target, checking that it's valid, and the default build target if it is not */
#Loc: <Workspace>/Engine/Source/Editor/TurnkeySupport/Private/TurnkeySupportModule.cpp:402
Scope (from outer to inner):
file
class class FTurnkeySupportCallbacks
function static void CookOrPackage
Source code excerpt:
// let the user pick a target directory
if (PlatformsSettings->StagingDirectory.Path.IsEmpty())
{
PlatformsSettings->StagingDirectory.Path = FPaths::ProjectDir();
}
FString OutFolderName;
if (!FDesktopPlatformModule::Get()->OpenDirectoryDialog(FSlateApplication::Get().FindBestParentWindowHandleForDialogs(nullptr), LOCTEXT("PackageDirectoryDialogTitle", "Package project...").ToString(), PlatformsSettings->StagingDirectory.Path, OutFolderName))
{
return;
}
PlatformsSettings->StagingDirectory.Path = OutFolderName;
PlatformsSettings->SaveConfig();
BuildCookRunParams += TEXT(" -stage -archive -package");
if (ShouldBuildProject(PackagingSettings, TargetPlatform))
#Loc: <Workspace>/Engine/Source/Editor/TurnkeySupport/Private/TurnkeySupportModule.cpp:459
Scope (from outer to inner):
file
class class FTurnkeySupportCallbacks
function static void CookOrPackage
Source code excerpt:
}
BuildCookRunParams += FString::Printf(TEXT(" -archivedirectory=\"%s\""), *PlatformsSettings->StagingDirectory.Path);
if (PackagingSettings->ForDistribution)
{
BuildCookRunParams += TEXT(" -distribution");
}
#Loc: <Workspace>/Engine/Source/Editor/TurnkeySupport/Private/TurnkeySupportModule.cpp:688
Scope (from outer to inner):
file
class class FTurnkeySupportCallbacks
function static void ExecuteCustomBuild
Source code excerpt:
if (Build.BuildCookRunParams.Contains("{BrowseForDir}"))
{
// we reuse the already-presenbt StagingDirectory to save it, although it's more like "BuildOutpuDirectory" now
UPlatformsMenuSettings* PlatformsSettings = GetMutableDefault<UPlatformsMenuSettings>();
FString OutFolderName;
if (!FDesktopPlatformModule::Get()->OpenDirectoryDialog(FSlateApplication::Get().FindBestParentWindowHandleForDialogs(nullptr), LOCTEXT("PackageDirectoryDialogTitle", "Package project...").ToString(), PlatformsSettings->StagingDirectory.Path, OutFolderName))
{
return;
}
PlatformsSettings->StagingDirectory.Path = OutFolderName;
PlatformsSettings->SaveConfig();
CommandLine += FString::Printf(TEXT(" -outputdir=\"%s\""), *OutFolderName);
}
#Loc: <Workspace>/Engine/Source/Runtime/Online/BuildPatchServices/Private/BuildPatchFileConstructor.cpp:295
Scope (from outer to inner):
file
function void FBuildPatchFileConstructor::Run
Source code excerpt:
// Check for resume data, we need to also look for a legacy resume file to use instead in case we are resuming from an install of previous code version.
const FString LegacyResumeDataFilename = Configuration.StagingDirectory / TEXT("$resumeData");
const FString ResumeDataFilename = Configuration.MetaDirectory / TEXT("$resumeData");
const bool bHasLegacyResumeData = FileSystem->FileExists(*LegacyResumeDataFilename);
// If we find a legacy resume data file, lets move it first.
if (bHasLegacyResumeData)
{
FileSystem->MoveFile(*ResumeDataFilename, *LegacyResumeDataFilename);
}
FResumeData ResumeData(FileSystem, Configuration.ManifestSet, Configuration.StagingDirectory, ResumeDataFilename);
// Remove incompatible files
if (ResumeData.bHasResumeData)
{
for (const FString& FileToConstruct : Configuration.ConstructList)
{
#Loc: <Workspace>/Engine/Source/Runtime/Online/BuildPatchServices/Private/BuildPatchFileConstructor.cpp:315
Scope (from outer to inner):
file
function void FBuildPatchFileConstructor::Run
Source code excerpt:
{
GLog->Logf(TEXT("FBuildPatchFileConstructor: Deleting incompatible stage file %s"), *FileToConstruct);
FileSystem->DeleteFile(*(Configuration.StagingDirectory / FileToConstruct));
}
}
}
// Save for started versions
TSet<FString> ResumeIds;
#Loc: <Workspace>/Engine/Source/Runtime/Online/BuildPatchServices/Private/BuildPatchFileConstructor.cpp:496
Scope (from outer to inner):
file
function bool FBuildPatchFileConstructor::ConstructFileFromChunks
Source code excerpt:
EConstructionError ConstructionError = EConstructionError::None;
uint32 LastError = 0;
FString NewFilename = Configuration.StagingDirectory / BuildFilename;
// Calculate the hash as we write the data
FSHA1 HashState;
FSHAHash HashValue;
if (!FileManifest.SymlinkTarget.IsEmpty())
#Loc: <Workspace>/Engine/Source/Runtime/Online/BuildPatchServices/Private/BuildPatchFileConstructor.h:38
Scope (from outer to inner):
file
namespace BuildPatchServices
Source code excerpt:
// The location where new installation files will be constructed.
FString StagingDirectory;
// The location where temporary files for tracking can be stored.
FString MetaDirectory;
// The list of files to be constructed, filename paths should match those contained in manifest.
TArray<FString> ConstructList;
#Loc: <Workspace>/Engine/Source/Runtime/Online/BuildPatchServices/Private/BuildPatchInstaller.cpp:270
Scope (from outer to inner):
file
namespace InstallerHelpers
function void LogBuildConfiguration
Source code excerpt:
UE_LOG(LogBPSInstallerConfig, Log, TEXT("Build Config: InstallDirectory: %s"), *InstallerConfiguration.InstallDirectory);
UE_LOG(LogBPSInstallerConfig, Log, TEXT("Build Config: StagingDirectory: %s"), *InstallerConfiguration.StagingDirectory);
UE_LOG(LogBPSInstallerConfig, Log, TEXT("Build Config: BackupDirectory: %s"), *InstallerConfiguration.BackupDirectory);
for (const FString& DatabaseFile : InstallerConfiguration.ChunkDatabaseFiles)
{
UE_LOG(LogBPSInstallerConfig, Log, TEXT("Build Config: ChunkDatabaseFile: %s"), *DatabaseFile);
}
#Loc: <Workspace>/Engine/Source/Runtime/Online/BuildPatchServices/Private/BuildPatchInstaller.cpp:429
Scope (from outer to inner):
file
namespace BuildPatchServices
function FBuildPatchInstaller::FBuildPatchInstaller
Source code excerpt:
, CompleteDelegate(InCompleteDelegate)
, Configuration(MoveTemp(InConfiguration))
, DataStagingDir(Configuration.StagingDirectory / TEXT("PatchData"))
, InstallStagingDir(Configuration.StagingDirectory / TEXT("Install"))
, MetaStagingDir(Configuration.StagingDirectory / TEXT("Meta"))
, PreviousMoveMarker(Configuration.InstallDirectory / TEXT("$movedMarker"))
, ThreadLock()
, bSuccess(false)
, bIsRunning(false)
, bIsInited(false)
, bFirstInstallIteration(true)
#Loc: <Workspace>/Engine/Source/Runtime/Online/BuildPatchServices/Private/BuildPatchInstaller.cpp:666
Scope (from outer to inner):
file
namespace BuildPatchServices
function bool FBuildPatchInstaller::Initialize
Source code excerpt:
// Make sure we have staging directory access.
IFileManager::Get().MakeDirectory(*Configuration.StagingDirectory, true);
if (!IFileManager::Get().DirectoryExists(*Configuration.StagingDirectory))
{
UE_LOG(LogBuildPatchServices, Error, TEXT("Installer setup: Inability to create StagingDirectory %s."), *Configuration.StagingDirectory);
InstallerError->SetError(EBuildPatchInstallError::InitializationError, InitializationErrorCodes::MissingStageDirectory, 0,
FText::Format(NSLOCTEXT("BuildPatchInstallError", "MissingStageDirectory", "The following directory could not be created.\n{0}"), FText::FromString(Configuration.StagingDirectory)));
bInstallerInitSuccess = false;
}
// Make sure that we have a prereq if we've specified a prereq only install.
if (Configuration.InstallMode == EInstallMode::PrereqOnly)
{
#Loc: <Workspace>/Engine/Source/Runtime/Online/BuildPatchServices/Private/BuildPatchInstaller.cpp:857
Scope (from outer to inner):
file
namespace BuildPatchServices
function uint32 FBuildPatchInstaller::Run
Source code excerpt:
{
UE_LOG(LogBuildPatchServices, Log, TEXT("Deleting staging area."));
IFileManager::Get().DeleteDirectory(*Configuration.StagingDirectory, false, true);
CleanupEmptyDirectories(Configuration.InstallDirectory);
}
CleanUpTimer.Stop();
}
BuildProgress.SetStateProgress(EBuildPatchState::CleanUp, 1.0f);
#Loc: <Workspace>/Engine/Source/Runtime/Online/BuildPatchServices/Private/BuildPatchInstaller.cpp:1236
Scope (from outer to inner):
file
namespace BuildPatchServices
function bool FBuildPatchInstaller::RunInstallation
Source code excerpt:
{
UE_LOG(LogBuildPatchServices, Error, TEXT("Could not create new file due to exceeding maximum path length %s"), *StagedConstructionFile);
InstallerError->SetError(EBuildPatchInstallError::PathLengthExceeded, PathLengthErrorCodes::StagingDirectory);
return false;
}
}
// Set initial states on IO state tracker.
const bool bVerifyAllFiles = Configuration.VerifyMode == EVerifyMode::ShaVerifyAllFiles || Configuration.VerifyMode == EVerifyMode::FileSizeCheckAllFiles;
#Loc: <Workspace>/Engine/Source/Runtime/Online/BuildPatchServices/Private/BuildPatchServicesModule.cpp:299
Scope (from outer to inner):
file
function void FBuildPatchServicesModule::SetStagingDirectory
Source code excerpt:
void FBuildPatchServicesModule::SetStagingDirectory( const FString& StagingDir )
{
StagingDirectory = StagingDir;
}
void FBuildPatchServicesModule::SetCloudDirectory(FString CloudDir)
{
TArray<FString> CloudDirs;
CloudDirs.Add(MoveTemp(CloudDir));
#Loc: <Workspace>/Engine/Source/Runtime/Online/BuildPatchServices/Private/BuildPatchServicesModule.cpp:454
Scope (from outer to inner):
file
function const FString& FBuildPatchServicesModule::GetStagingDirectory
Source code excerpt:
{
// Default staging directory
if( StagingDirectory.IsEmpty() )
{
StagingDirectory = FPaths::ProjectDir() + TEXT( "BuildStaging/" );
}
return StagingDirectory;
}
FString FBuildPatchServicesModule::GetCloudDirectory(int32 CloudIdx)
{
FString RtnValue;
if (CloudDirectories.Num())
#Loc: <Workspace>/Engine/Source/Runtime/Online/BuildPatchServices/Private/BuildPatchServicesModule.cpp:501
Scope: file
Source code excerpt:
TSharedPtr<IAnalyticsProvider> FBuildPatchServicesModule::Analytics;
TArray<FString> FBuildPatchServicesModule::CloudDirectories;
FString FBuildPatchServicesModule::StagingDirectory;
FString FBuildPatchServicesModule::BackupDirectory;
#Loc: <Workspace>/Engine/Source/Runtime/Online/BuildPatchServices/Private/BuildPatchServicesModule.h:122
Scope (from outer to inner):
file
class class FBuildPatchServicesModule : public IBuildPatchServicesModule
Source code excerpt:
// Holds the staging directory where we can perform any temporary work
static FString StagingDirectory;
// Holds the backup directory where we can move files that will be clobbered by repair or patch
static FString BackupDirectory;
// Holds the filename for local machine config. This is instead of shipped or user config, to track machine installation config.
FString LocalMachineConfigFile;
#Loc: <Workspace>/Engine/Source/Runtime/Online/BuildPatchServices/Private/BuildPatchSettings.cpp:142
Scope (from outer to inner):
file
namespace BuildPatchServices
function FBuildInstallerConfiguration::FBuildInstallerConfiguration
Source code excerpt:
: InstallerActions(MoveTemp(InInstallerActions))
, InstallDirectory()
, StagingDirectory()
, BackupDirectory()
, ChunkDatabaseFiles()
, CloudDirectories()
, InstallMode(EInstallMode::NonDestructiveInstall)
, VerifyMode(EVerifyMode::ShaVerifyAllFiles)
, DeltaPolicy(EDeltaPolicy::Skip)
#Loc: <Workspace>/Engine/Source/Runtime/Online/BuildPatchServices/Private/BuildPatchSettings.cpp:198
Scope (from outer to inner):
file
namespace BuildPatchServices
function FInstallerConfiguration::FInstallerConfiguration
Source code excerpt:
, InstallManifest(InInstallManifest)
, InstallDirectory()
, StagingDirectory()
, BackupDirectory()
, ChunkDatabaseFiles()
, CloudDirectories()
, InstallTags()
, InstallMode(EInstallMode::NonDestructiveInstall)
, VerifyMode(EVerifyMode::ShaVerifyAllFiles)
#Loc: <Workspace>/Engine/Source/Runtime/Online/BuildPatchServices/Private/BuildPatchSettings.cpp:216
Scope (from outer to inner):
file
namespace BuildPatchServices
function FInstallerConfiguration::FInstallerConfiguration
Source code excerpt:
, InstallManifest(MoveTemp(MoveFrom.InstallManifest))
, InstallDirectory(MoveTemp(MoveFrom.InstallDirectory))
, StagingDirectory(MoveTemp(MoveFrom.StagingDirectory))
, BackupDirectory(MoveTemp(MoveFrom.BackupDirectory))
, ChunkDatabaseFiles(MoveTemp(MoveFrom.ChunkDatabaseFiles))
, CloudDirectories(MoveTemp(MoveFrom.CloudDirectories))
, InstallTags(MoveTemp(MoveFrom.InstallTags))
, InstallMode(MoveFrom.InstallMode)
, VerifyMode(MoveFrom.VerifyMode)
#Loc: <Workspace>/Engine/Source/Runtime/Online/BuildPatchServices/Private/BuildPatchSettings.cpp:234
Scope (from outer to inner):
file
namespace BuildPatchServices
function FInstallerConfiguration::FInstallerConfiguration
Source code excerpt:
, InstallManifest(CopyFrom.InstallManifest)
, InstallDirectory(CopyFrom.InstallDirectory)
, StagingDirectory(CopyFrom.StagingDirectory)
, BackupDirectory(CopyFrom.BackupDirectory)
, ChunkDatabaseFiles(CopyFrom.ChunkDatabaseFiles)
, CloudDirectories(CopyFrom.CloudDirectories)
, InstallTags(CopyFrom.InstallTags)
, InstallMode(CopyFrom.InstallMode)
, VerifyMode(CopyFrom.VerifyMode)
#Loc: <Workspace>/Engine/Source/Runtime/Online/BuildPatchServices/Private/Installer/InstallerError.h:35
Scope (from outer to inner):
file
namespace BuildPatchServices
namespace PathLengthErrorCodes
Source code excerpt:
namespace PathLengthErrorCodes
{
static const TCHAR* StagingDirectory = TEXT("01");
static const TCHAR* InstallDirectory = TEXT("02");
}
/**
* A list of the error codes we will use for each case of download failure.
*/
#Loc: <Workspace>/Engine/Source/Runtime/Online/BuildPatchServices/Public/BuildPatchSettings.h:233
Scope (from outer to inner):
file
namespace BuildPatchServices
Source code excerpt:
IBuildManifestRef InstallManifest;
FString InstallDirectory;
FString StagingDirectory;
FString BackupDirectory;
TArray<FString> ChunkDatabaseFiles;
TArray<FString> CloudDirectories;
TSet<FString> InstallTags;
EInstallMode InstallMode;
EVerifyMode VerifyMode;
#Loc: <Workspace>/Engine/Source/Runtime/Online/BuildPatchServices/Public/BuildPatchSettings.h:264
Scope (from outer to inner):
file
namespace BuildPatchServices
Source code excerpt:
FString InstallDirectory;
// The directory for storing the intermediate files. This would usually be inside the InstallDirectory. Empty string will use module's global setting.
FString StagingDirectory;
// The directory for placing files that are believed to have local changes, before we overwrite them. Empty string will use module's global setting. If both empty, the feature disables.
FString BackupDirectory;
// The list of chunk database filenames that will be used to pull patch data from.
TArray<FString> ChunkDatabaseFiles;
// The list of cloud directory roots that will be used to pull patch data from. Empty array will use module's global setting.
TArray<FString> CloudDirectories;
#Loc: <Workspace>/Engine/Source/Runtime/Online/BuildPatchServices/Public/Interfaces/IBuildPatchServicesModule.h:294
Scope (from outer to inner):
file
class class IBuildPatchServicesModule : public IModuleInterface
function IBuildInstallerRef StartBuildInstall
Source code excerpt:
BuildPatchServices::FBuildInstallerConfiguration BuildInstallerConfiguration(MoveTemp(Actions));
BuildInstallerConfiguration.InstallDirectory = Configuration.InstallDirectory;
BuildInstallerConfiguration.StagingDirectory = Configuration.StagingDirectory;
BuildInstallerConfiguration.BackupDirectory = Configuration.BackupDirectory;
BuildInstallerConfiguration.ChunkDatabaseFiles = Configuration.ChunkDatabaseFiles;
BuildInstallerConfiguration.CloudDirectories = Configuration.CloudDirectories;
BuildInstallerConfiguration.InstallMode = Configuration.InstallMode;
BuildInstallerConfiguration.VerifyMode = Configuration.VerifyMode;
BuildInstallerConfiguration.DeltaPolicy = Configuration.DeltaPolicy;