Build flow of the Unreal Engine4 project

UE通过UBT来构建项目(不管是VS里的Build也好,Editor里的Compile也好,最终都会调用UBT)。UBT和UHT是UE工具链的基石,内容太多,没办法一次性分析全部,先梳理出一个大致的轮廓,有时间再慢慢补充。

先对UBT和UHT的工作职责有一个大概介绍:
UBT

  • Scans solution directory for modules and plug-ins
  • Determines all modules that need to be rebuilt
  • Invokes UHT to parse C++ headers
  • Creates compiler & linker options from .Build.cs & .Target.cs
  • Executes platform specific compilers (VisualStudio, LLVM)

UHT

  • Parses all C++ headers containing UClasses
  • Generates glue code for all Unreal classes & functions
  • Generated files stored in Intermediates directory

言归正传。首先,从零开始,第一步先创建一个C++项目(BasicCode/ThridPerson任选),并打开VS。

打开VS之后可以看到这样的Solution结构:

在Solution中选中创建的Project点击右键-Properties

可以看到,NMake-Gerneral下的构建命令(Build Command)使用的均是Engine\Build\BatchFiles目录下的bat(在Windows平台):

1
2
3
4
5
6
# Build
Engine\Build\BatchFiles\Build.bat
# ReBuild
Engine\Build\BatchFiles\Rebuild.bat
# Clean
Engine\Build\BatchFiles\Clean.bat

以Build.bat为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@echo off
setlocal enabledelayedexpansion

REM The %~dp0 specifier resolves to the path to the directory where this .bat is located in.
REM We use this so that regardless of where the .bat file was executed from, we can change to
REM directory relative to where we know the .bat is stored.
pushd "%~dp0\..\..\Source"

REM %1 is the game name
REM %2 is the platform name
REM %3 is the configuration name

IF EXIST ..\..\Engine\Binaries\DotNET\UnrealBuildTool.exe (
..\..\Engine\Binaries\DotNET\UnrealBuildTool.exe %* -DEPLOY
popd

REM Ignore exit codes of 2 ("ECompilationResult.UpToDate") from UBT; it's not a failure.
if "!ERRORLEVEL!"=="2" (
EXIT /B 0
)

EXIT /B !ERRORLEVEL!
) ELSE (
ECHO UnrealBuildTool.exe not found in ..\..\Engine\Binaries\DotNET\UnrealBuildTool.exe
popd
EXIT /B 999
)

可以看到Build.bat将接收的参数都转发给了UnrealBuildTool.exe:

1
..\..\Engine\Binaries\DotNET\UnrealBuildTool.exe %*

通过UnrealBuildTools构建项目需要传递参数:

  1. %1 is the game name
  2. %2 is the platform name
  3. %3 is the configuration name
  4. %4 is the ProjectPath
1
2
# Example
UnrealBuildTool.exe ThridPerson420 Win64 Development "C:\Users\visionsmile\Documents\Unreal Projects\Examples\ThridPerson420\ThridPerson420.uproject" -WaitMutex -FromMsBuild

然后来看一下UnrealBuildTools是怎么处理的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Engine\Source\Programs\UnrealBuildTools\UnrealBuildTool.cs
private static int Main(string[] Arguments)
{
// make sure we catch any exceptions and return an appropriate error code.
// Some inner code already does this (to ensure the Mutex is released),
// but we need something to cover all outer code as well.
try
{
return GuardedMain(Arguments);
}
catch (Exception Exception)
{
if (Log.IsInitialized())
{
Log.TraceError("UnrealBuildTool Exception: " + Exception.ToString());
}
if (ExtendedErrorCode != 0)
{
return ExtendedErrorCode;
}
return (int)ECompilationResult.OtherCompilationError;
}
}


可以看到传入进来的参数。
在GuardedMain中对引擎和传入参数做了一堆检测之后,会调用RunUBT:

在UBT中会对传入的参数做检测,当前模块的依赖分析(Build.cs),之后会调用UHT来生成代码:
调用的函数为ExecuteHeaderToolIfNecessary(System/ExternalExecution.cs):

如果上一步通过UHT生成成功,就会执行编译的Action了(ActionGraph.ExecuteActions in System/ActionGraphs.cs):

继续进入会检测一堆引擎的构建配置(e.g:Engine/Saved/UnrealBuildTool/BuildConfiguration.xml):

我这里保持的是引擎默认的构建配置,则创建了一个ParallelExecutor(System/ParallelExecutor.cs),然后执行:

将当前的编译任务创建出多个Action,并执行:

开始编译代码:

未完待续。
本文标题:Build flow of the Unreal Engine4 project
文章作者:ZhaLiPeng
发布时间:2019年03月16日 23时09分
本文字数:本文一共有720字
原始链接:https://imzlp.me/posts/6362/
许可协议: CC BY-NC-SA 4.0
转载请保留原文链接及作者信息,谢谢!
您的捐赠将鼓励我继续创作!