How To: BuildGraph
What is BuildGraph?
BuildGraph is a script-based build system that has been integrated into the Unreal build pipeline as of 4.13. The core selling point of BuildGraph is that it gives developers more flexibility in how they go about generating specific outputs from UBT (Unreal Build Tool). If you have used makefiles before or setup a build farm then you should be right at home with this system, as it is basically a combination of the two systems.
BuildGraphs consist of one major component; the BuildGraph script. A BuildGraph script is an XML document that uses a custom schema to define how to process and handle the content found within it. As found in the Unreal Documentation a BuildGraph script file is typically made up of the following elements:
- Tasks: Actions that are executed as part of a build process (compiling, cooking, etc.).
- Nodes: A named sequence of ordered tasks that are executed to produce outputs. Before they can be executed, nodes may depend on other nodes executing their tasks first.
- Agents: A group of nodes that are executed on the same machine (if running as part of a build system). Agents have no effect when building locally.
- Triggers: Container for groups that should only be executed after manual intervention.
- Aggregates: Groups of nodes and named outputs that can be referred to with a single name.
BuildGraph Usage Example
BuildGraph isn’t just made for building the engine as a whole either, you can compile your game project, compile a specific engine component and even perform batch tasks like file renaming or moving of content.
Here is an example of a BuildGraph script that compiles the UnrealHeaderTool and outputs the files that are compiled:
<?xml version='1.0' ?>
<BuildGraph xmlns="https://www.epicgames.com/BuildGraph" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://www.epicgames.com/BuildGraph ../Schema.xsd" >
<Agent Name="Properties Agent" Type="CompileWin64">
<!-- Compile UnrealHeaderTool -->
<Node Name="Compile UnrealHeaderTool">
<Compile Target="UnrealHeaderTool" Platform="Win64" Configuration="Development" Tag="#UHTFiles"/>
<Log Message="The following files are part of UnrealHeaderTool:" Files="#UHTFiles"/>
</Node>
</Agent>
<Aggregate Name="Building Examples" Requires="Compile UnrealHeaderTool"/>
</BuildGraph>
Breaking it down
The BuildGraph xml declaration at the top describes what these nodes mean to the xml parser. One thing to note here is the schema location value needs to point to the location of the schema file in your engine directory (Typically found in Engine\Build\Graph
).
<?xml version='1.0' ?>
<BuildGraph xmlns="https://www.epicgames.com/BuildGraph" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://www.epicgames.com/BuildGraph ../Schema.xsd" >
The next line as outlined in element section is declaring an agent for a build machine to use, if you are using BuildGraph only on a local build machine this won’t mean anything for you.
<Agent Name="Properties Agent" Type="CompileWin64">
The following section of the script defines a node (task to complete) and what it wants that node to do. In this case it wants to build the UnrealHeaderTool for 64bit Windows in Development Configuration and during this process output all the compiled file names to the console.
<Node Name="Compile UnrealHeaderTool">
<Compile Target="UnrealHeaderTool" Platform="Win64" Configuration="Development" Tag="#UHTFiles"/>
<Log Message="The following files are part of UnrealHeaderTool:" Files="#UHTFiles"/>
</Node>
Lastly the aggregate specifier is used to allow for the term Building Examples to be used as an alias for running the compile UnrealHeaderTool node. If this file had multiple nodes the aggregate specifier could be used to run only a small selection of those nodes without having to explicitly declare them when running a script.
<Aggregate Name="Building Examples" Requires="Compile UnrealHeaderTool"/>
BuildGraph Parameters
The next step, obviously, is to customize our BuildGraph so we can pass in parameters at run time to change the flow of the build. This is quite a simple task and can be achieved with a few simple lines.
Take this BuildGraph script:
<?xml version='1.0' ?>
<BuildGraph xmlns="https://www.epicgames.com/BuildGraph" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://www.epicgames.com/BuildGraph ../Schema.xsd" >
<Agent Name="Agent 1" Type="CompileWin64">
<Node Name="Manipulate Some Files">
<Log Message="Here are all the files in Engine/Build/..." Files="Engine/Build/..."/>
<Copy FromDir="Engine/Build" Files="..." ToDir="Engine/TestNumber1"/>
<Delete Files="Engine/TestNumber1/.../*.bat;Engine/TestNumber1/.../*.sh;Engine/TestNumber1/Android/..."/>
<Log Message="Here are all the files in Engine/TestNumber1/..." Files="Engine/TestNumber1/..."/>
</Node>
</Agent>
</BuildGraph>
Taken from the TagsAndFiles build script in the examples folder
In this script we are copying all the files from the Engine/Build
folder to the Engine/TestNumber1
folder, after that we are then deleting all batch files and all the contents in the Android folder.
Let’s say we didn’t want to always delete the files, but instead give our selves and option to do so whenever we wanted.
At the top of the BuildGraph script lets declare a parameter also known as an option :
<Option Name="DeleteAfterCopy" Restrict="true|false" DefaultValue="false" Description="Whether or not we want to delete the Android folders and batch files after copying"/>
Here we used the Option specifier to denote that this value is an optional parameter and then we gave it a name. The Restrict attribute does what the name implies and restricts this options values to either be true or false. As with the previous attribute DefaultValue is pretty obvious in that it sets the default value of this option.
Using the option value in our script is fairly straight forward:
<!-- Accessing a value in BuildGraph scripts is done by using $([OptionName]) -->
<!-- Comparison operations are done the usual way $([OptionName]) == comparator -->
<Do If="'$(DeleteAfterCopy)' == true">
<Delete Files="Engine/TestNumber1/.../*.bat;Engine/TestNumber1/.../*.sh;Engine/TestNumber1/Android/..."/>
</Do>
This will now only run when DeleteAfterCopy is set to true.
Your final BuildGraph Script should look something like this:
<?xml version='1.0' ?>
<BuildGraph xmlns="https://www.epicgames.com/BuildGraph" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://www.epicgames.com/BuildGraph ../Schema.xsd" >
<Option Name="DeleteAfterCopy" Restrict="true|false" DefaultValue="false" Description="Whether or not we want to delete the Android folders and batch files after copying"/>
<Agent Name="Agent 1" Type="CompileWin64">
<Node Name="Manipulate Some Files">
<Log Message="Here are all the files in Engine/Build/..." Files="Engine/Build/..."/>
<Copy FromDir="Engine/Build" Files="..." ToDir="Engine/TestNumber1"/>
<Do If="'$(DeleteAfterCopy)' == true">
<Delete Files="Engine/TestNumber1/.../*.bat;Engine/TestNumber1/.../*.sh;Engine/TestNumber1/Android/..."/>
</Do>
<Log Message="Here are all the files in Engine/TestNumber1/..." Files="Engine/TestNumber1/..."/>
</Node>
</Agent>
</BuildGraph>
Now that we know how to create a BuildGraph script lets try running the scripts we have made.
Using BuildGraph Scripts
Initial Setup
To get started running your own build scripts you need to make sure you have cloned/downloaded the source version of the engine found here: https://github.com/EpicGames/UnrealEngine/ (if you get an access denied error make sure you are logged in and have your github account tied to your Epic Games Account).
After downloading the source version Run Setup.bat found in the root directory of the download, following the completion of that script run GenerateProjectFiles.bat. Note: You do not need to build the engine to use the BuildGraph command.
Running a BuildGraph Script
Running a BuildGraph script is as simple as opening up a cmd window and running a single line of code. All it needs to do is call the UnrealAutomationTool and execute the BuildGraph command. To run our specific scripts we give it the path to the script we want to run and pass it the node we want to execute.
"[EnginePath]\Engine\Engine\Build\BatchFiles\RunUAT.bat" BuildGraph
-Script=[Path To Your Script Location e.g Engine/Build/Graph/Examples/AllExamples.xml]
-target=[Name of node to run]
The original example I gave is found in Engine\Engine\Build\Graph\Examples
folder and is called Building.xml
. To run this BuildGraph script all we would need to do is open up a cmd window and run:
"[EnginePath]\Engine\Engine\Build\BatchFiles\RunUAT.bat" BuildGraph
-Script="Engine\Engine\Build\Graph\Examples\Building.xml"
-target="Compile UnrealHeaderTool"
Running with options
Using the script we made in the Parameters Section we can do the same thing we did above. We call the RunUAT batch file, give it a script location, and a target node to execute. This time however we set the value of DeleteAfterCopy:
"[EnginePath]\Engine\Engine\Build\BatchFiles\RunUAT.bat" BuildGraph
-Script="Engine\Engine\Build\Graph\Examples\TutorialBuild.xml"
-target="Compile UnrealHeaderTool" -set:DeleteAfterCopy=true
As you can see setting options is done using -set:[Option Name]=[Value]
. As we set the required attribute earlier if we try and enter a value that is not true or false the build will fail. If all went well you should now have a new folder called TestNumber1 in your Engine folder that is missing all the batch files and the Android folder.
If you want some more examples of how to use the BuildGraph system I do recommend checking out the examples folder I mentioned above as well as the BuildGraph script used to compile the engine (Which you can find more about in my article on Building an Installed Version of Unreal).
If you have any questions or problems with anything you find in this article please do let me know either in the comment section below or you can hit me up on twitter: jack_knobel.