9.1 KiB
Unreal Build Tool
The following is the 80/20 gist of UBT based off its main loop.
For a general outline of the architecture see UBT Architecture Outline
Located in Engine\Source\Programs\UnrealBuildTool\
C# solution.
Main Loop
Located in UnrealBuildTool.cs
- Start peformance info capture
- Parse command line arguments
- Parse global options
- Logging & UBT assembly setup
- Set working directory to Engine/Source
- Setup build mode
- Setup tool mode options
- Get engine directory contents
- Read XML Configurataion
- Create UBT run file
- "Lock Branch"
- Register build platforms
- Create ToolMode which will handle the rest
- Close out
Global Options
Also located in same file.
Offical inline documentation:
Global options for UBT (any modes)
Commandline options are deffined using Epic's CommandLineAttribute
.
ToolMode
Offical inline documentation:
Base class for standalone UBT modes. Different modes can be invoked using the -Mode=[Name] argument on the command line, where [Name] is determined by the ToolModeAttribute on a ToolMode derived class. The log system will be initialized before calling the mode, but little else.
-Mode is defined in GlobalOptions definition.
Has a single function:
public abstract int Execute(CommandLineArguments Arguments, ILogger Logger);
BuildMode
Derived from ToolMode, used to build a target.
Execute
procedure Flow:
- Output arguments & setup the logger
- Read the xml configuration files
- Apply architecture configs (platform specific configs for a target)
- More logging setup
- Create build configuraiton object
- Parse and build targets
- Pase all target descriptors
- Clean all targets with
CleanMode
(a tool mode) that havebRebuild
flagged. - Handle remote builds (Seems to be excluisvely Mac)
- Handle local builds
- Get all project directories & build options
- For each project: create a
SourceFileWorkingSet
object andBuild
.
- Process the dumps to see if anything failed.
- Save Caches
BuildConfiguration
Contains target agonstic settings.
QueueProjectDirectory
Used when retreving all project directories.
Will Enqueue a FileMetadataPrefetch.ScanProjectDirectory
call for the directory with the prefecter.
ScanProjectDirectory
- Get all extension directoires for the target project directory
- For each directory
- Enqueue a scan of the plugin directory (
ScanPluginFolder
, thePlugins
folder) - Enqueue a scan of the project directory (
ScanDirectoryTree
, theSource
folder)
- Enqueue a scan of the plugin directory (
Unreal.GetExtensionDirs
will do an initial scan for Platform, Restricted, and BaseDirectories, and remove them from CachedDirectories based if any of options for doing so are set.
ScanPluginFolder
Similar to ScanProject directory, recursively scans for plugin directories.
- For all subdirectories :
- Check if any of the files has a .uplugin extension
- If it does enqueue a
ScanDirectoryTree
for theSource
directory.
- If it does enqueue a
- Enqueue a
ScanPluginFolder
for the sub directory.
- Check if any of the files has a .uplugin extension
ScanDirectoryTree
Scan an arbitrary directory tree.
DirectoryItem
This is the main container being populated as it gets recursively iterated upn by QueueProjectDirectory and its helper functions.
This is done mainly by CacheDirectories()
which is wrapped by EnumerateDirectories()
(called on the iteration foreach for the above queue & scanning functions).
BuildOptions
Not much, just an enum that lets the user specify:
- Skip Build
- XGE Export
- No Engine Changes
SourceFileWorkingSet & ISourceFileWorkingSet
Defines an interface which allows querying the working set. Files which are in the working set are excluded from unity builds, to improve iterative compile times.
By default Unreal provides the following implmentations of the interface:
- None
EmptySourceFileWorkingSet
- Default
- Git
GitSourceFileWorkingSet
- Perforce
PerforceSourceFileWorkingSet
There is no refrences to where Default is used.
If the project's provider is set to None or the flag bGenerateProjectFiles
is set, it will use the EmptySourceFileWorkingSet (essentially disable any segmentation of the working set from the unity builds).
It picks the others based on whats within the BuildConfiguration.xml located within: UBT Configuration Paths from offical docs
BuildAsync
BuildMode's async task generator.
The first BuildAsync
called within ExecuteAysnc
is a prepper for the actual BuildAsync
- For all target descriptors provied:
- Create & execute init scripts
- Create async a
TargetMakeFile
. - If it should also do PreBuildTargets:
- Add to
TargetDescriptors
- Add to
It prepares the TargetMakeFiles
and TargetDescriptors
for the actual procedure
The Actual BuildAsync
:
- Check the ActionGraph has no conflicts for the current for the current build's make files.
- Make sure no paths exceed the max path length.
- Make a
LinkedAction
for eachTargetMakeFile
:- Convert each
TargetMakeFile
toLinkedAction
with itsTargetDescriptor
. - If a specific
TargetDescriptor
for the make file is setup forSpecificFilesToCompile
:- Check for
bSingleFileBuildDependents
and get all the related sources & headers. (To add toFilesToBuild
) - Generated a list of
ProducedItems
(FileItem
IO action element), these are added to theMergedOutputItems
(Hashset
ofProducedItems
)
- Check for
- Convert each
- Cleanup previous & setup current
HotReload
for aTargetMakeFile
- If there are more than one
TargetDescriptor
for the build, merged them into one list of LinkedActions. - Call
GatherOutputItems
for allTargetDescriptors
Determines all the actions that should be executed for a target (filtering for single module/file, etc..)
ActionGraph.Link
: Link all theMergedActions
together:- Build a map from item to its action.
- Check for cyclic-dependencies, if any are found an exection will be thrown.
- Setup prerequisite action for each action.
- Sort the action graph.
For improved parallelism with local execution.
- Generate Prerequisite Actions based on what was setup with
MergedActions
- Generate the
ActionHistory
- Generate CppDependenciesCache from the TargetDescriptors
- Create the artifact cache if one doesn't already exist. (Place to store compiled binaries, intermediate files, and other output content). Directory is specified by the
BuildConfiguration.ArtifactDirectory
- Generate a list of ModuleDependencyActions that track depedency files:
- From the ActionGraph, get all outdated actions for the cpp dependencies that need to be preprocesed.
- Wait for all
PreprocessActions
to execute on these dependents.
- Determine which actions have outdated cached artifacts and need to be built: (Stored in
ActionToOutatedFlag
)- Check al the link actions to see if its outdated and needs to be built.
- Propcate outdated state for a file to its dependents. (
ProducedModules
/ModuleOutputs
) - Check to se if external dependencies were updated. (
ImportedModules
/ModuleImports
) - Setup
PrerequisiteActions
futher. ActionGraph.GatherAllOutdatadActions
:
Plan the actions to execute for the build. For single file compiles, always rebuild the source file regardless of whether it's out of date.
- Generate a list of
LinkedAction
(MergedActionsToExecute
) usingActionToOutdatedFlag
and Link them to theActionGraph
. - Foreach TargetDescriptor, check to see if a hot reload patch should be applied.
- Only one target can be hot-reloaded if more than one is attempted, an exception will be thrown.
- If There are any non-hot reload actions to execute
HotReload.CheckForLiveCodingSessionActive
will check to prevent the build from continuing if a Live coding sessions is detected. As the user needs to shutdown the editor/engine in order for this to occur.
- If a hot-reload target is detected, the
MergedActionsToExecute
is overwritten with aLiveCodingActionsToExecute
. - If the BuildOptions has
NoEngineChanges
set, throw an exception if any engine file modifcations are detected. - Make sure build configuration can use the executor if for the
BuildPlatform
set for theTargetDescriptors
- Delete from the
ActionGraph
any outdatedProducedItem
s (fromMergedActionsToExecute
) and save theActionHistory
(History
) - Create directories for the outdated items.
- Time to execute actions:
- If just exporting XGE, export the actions to an XML file.
- If
WriteOutdatedActionsFile
was specified, write the actions to a JSON output. - Actually execute the actions:
- If there are no
MergedActionsToExcecute
just state to the user that the target/s are up to date. - Log targets to build and toolchain info.
- Set the memory per action via the
ActionExecuter
. - Wait for
actionArtifactCache
to be ready. - Execute each action with
ActionGraph.ExecuteActionsAsync
- Flush the
actionArtifactCache
of any changes.
- If there are no
- For all the make files: Deploy the receipt of the actions via the build platform.