UE4 编译系统
UE4 编译
UE4的游戏代码工程,从工程的属性可以得知,Build/Clean/Rebuild都是依赖于UBT(Build.bat、Clean.bat和Rebuild.bat)。生成sln文件也依赖于UBT。
|
|
Generate
这里面的所有配置其实都是我们调用Generate的时候自动为我们添加进去的,我们需要首先看我们Generate 的时候会发生什么,之后是分析这些脚本主要是做了什么。
Generate Visual Studio project files
我们Generate的时候,依旧是调用UE4的脚本GenerateProjectFiles.bat
。
|
|
-
GetMSBuildPath.bat:首先我们查看系统中是否存在MSBuild。MSBuild全称(Microsoft Build Engine),是用于构建应用程序的平台。在使用VS做开发,那么一定时时刻刻在使用它。因为是它在背后为你管理生成你的项目文件。当新建一个项目时,注意下项目文件夹中的*.*proj文件就是为MSBuild提供的,这是个文本文件,基于XML格式,里面包含有项目所包含的文件,生成配置,输出配置等信息。
-
FixDependencyFiles.bat:检测编辑器使用的Icon。
-
md ..\Intermediate\Build >nul 2>nul
将对应目录清空
Intermediate文件主要初始化了一些马上要用的空文件夹,和在/Build/BuileRules文件夹下的UBT扫描模块时生成的地址(.txt),动态库(.dll),pdb(调试信息文件);还在ProjectFiles文件夹中生成了一些UE4和项目的工程配置文件。
-
dir /s /b Programs\UnrealBuildTool\*.cs >..\Intermediate\Build\UnrealBuildToolFiles.txt
找到目录下所有以后缀名为.cs的文件添加到UnrealBuildToolFiles.txt中 -
if exist ..\..\Platforms dir /s /b ..\..\Platforms\*.cs >> ..\Intermediate\Build\UnrealBuildToolFiles.txt
//如果存在platforms目录,则将该目录下面的文件也都添加到unrealbuildToolFiles.txt里面 -
fc /b ..\Intermediate\Build\UnrealBuildToolFiles.txt ..\Intermediate\Build\UnrealBuildToolPrevFiles.txt >nul 2>nul
//将unrealBuildToolFiles.txt中的内容拷贝到UnrealBuildToolPrevFiles.txt中 -
%MSBUILD_EXE% /nologo /verbosity:quiet Programs\UnrealBuildTool\UnrealBuildTool.csproj /property:Configuration=Development /property:Platform=AnyCPU /target:Clean
清空 -
%MSBUILD_EXE% /nologo /verbosity:quiet Programs\UnrealBuildTool\UnrealBuildTool.csproj /property:Configuration=Development /property:Platform=AnyCPU /target:Build
编译UBT,我们将得到其可执行文件。 -
调用编译后的UBT的exe, 调用到基本的UnrealBuildTool.cs中的Main函数。
Build
build 依旧是调用脚本。这才是本文的重中之重。
Engine\Build\BatchFiles\Build.bat
其主要顺序为
- build.bat 中调用 UBT
- UBT 执行 target.cs 和所有 Module 的 build.cs 中的逻辑
- UBT 调用 UHT (根据 UE 的宏标记生成代码)
- UHT 生成完毕后,UBT 调用编译器
- 预处理
- 编译
- 链接
在我们介绍UBT功能时,首先我们要知道怎么才能调试UBT。我们首先将UBT设置为启动项目
之后我们把build 的参数列表翻出来,把下面参数填到里面Command line arguments
|
|
UBT 的功能
- 扫描解决方案目录中的模块和插件
- 确定需要重新构建的所有模块
- 调用UHT来解析c++头文件
- 从.Build.cs和.Target.cs创建编译器和链接器选项
- 执行特定于平台的编译器(VisualStudio, LLVM)
编译器需要确定编译的先后顺序,因为源码文件之间往往存在依赖关系,假定A文件依赖于B文件,编译器应该保证做到下面两点。
(1)只有在B文件编译完成后,才开始编译A文件。
(2)当B文件发生变化时,A文件会被重新编译.
编译顺序保存在一个叫做makefile的文件中,里面列出哪个文件先编译,哪个文件后编译。在GCC编译器中makefile文件由configure脚本运行生成,这就是为什么编译时configure必须首先运行的原因。在确定依赖关系的同时,编译器也确定了,编译时会用到哪些头文件。
我们编写的Target.cs , Buile.cs 都是为了方便UBT识别并处理模块的依赖而服务的。
UBT的流程
- 为每个目标创建一个makefile。如果磁盘上已经存在有效的makefile,则加载该文件【CreateMakefile】。
- 将操作导出到JSON文件【ActionGraph.ExportJson】。
- 把所有的操作链接起来【ActionGraph.Link】。
- 执行操作列表。【ActionGraph.ExecuteActions】。
UBT的入口在UnrealBuildTool.cs里面的static int Main(string[] ArgumentsArray)
在这里我们将会进入到BuildMode里面。他首先会解析输入参数,构造全局选项,查找所有可用的模式,获取当前使用的模式ToolMode。对于build来说,其最后会调用到执行模式BuildMode.Execute。 之后会调用到
|
|
建立MakeFile
首先 UBT 调用UEBuildTarget Create会创建一个RulesAssembly,是用来读取和构造项目中的 target.cs 和 Module 的 build.cs 的。
|
|