理解UnrealBuildTool
转自:https://zhuanlan.zhihu.com/p/57186557
介绍
虚幻引擎是当前比较流行的游戏开发引擎之一,许多流行的游戏都是虚幻引擎开发的。
然而“引擎”这个词在行业中的定义比较模糊,对不同的人会产生不同的意思。它是一个代码库?是一个编辑器?还是一个工具箱?
可能它全都是,然而却差了很多文档来让人正确地认识它。
以前的工作中经常涉及到整合第三方库到引擎中,我花了很多时间来理解虚幻的build过程。现在把结果写在这个文章里。
如果你不理解C++是如何编译的,我推荐你读一下这个网站: LearnCpp
虚幻引擎是什么?
我想试着用我自己的理解来阐述这一点。虚幻引擎是一堆C++代码,可以在不同的平台上(操作系统)以不同的方式编译。你可以用自己的游戏代码来拓展引擎代码(即在虚幻的基础上开发游戏),然而你的代码会非常依赖引擎代码。
当你从源码编译虚幻引擎,你会生成一个游戏客户端(运行在PC或者游戏机上的东西),一个游戏服务器(用于多人游戏),一个编辑器和许多其他小程序(在引擎源码中叫做Programs,即完成特定任务的特定程序)。这个编辑器可以让你做很多事情,包含可以设计场景的工具,还可以编写(拖拉)蓝图(虚幻引擎特有的一种脚本语言)。这些小程序包含一堆工具,比如Unreal Build Tool和Unreal Header Tool,这就是这篇文章我们要讨论的。
Unreal Build Tool是什么?
为了支持代码的多种编译形式和多平台支持,甚至将相同的代码编译成一个.lib或者一个.dll(用于支持热加载),虚幻开发团队决定开发自己的构建工具,这意味着不再使用传统的makefile或者MSbuild,而是使用Unreal Build Tool。因此在虚幻中进行C++开发以及整合第三方库,与传统方式比起来会有一些不同。
Unreal Build Tool由C#编写,且作为整个虚幻编译过程中第一个编译步骤。当你运行“GenerateProjectFiles”(一个批处理文件,用于在Window平台下生成Visual Studio的解决方案和工程),这第一个步骤就是在Source/Programs/UnrealBuildTool/UnrealBuiltTool.csproj工程下执行MSBuild来编译这个“Unreal Build Tool”。
所以,Unreal Build Tool 其实就是一个命令行程序,却可以完成很多事情,比如生成工程文件、执行Unreal Header Tool、为各种不同的平台个构建风格调用编译器(Compiler)和连接器(Linker)。这个过程后面还会详细解释。
Modules(模块)
虚幻引擎中的模块其实就是一系列源文件。可以是C++模块或者C#模块。C#模块使用.csproj(Visual Studio C#工程描述文件)作为它的工程文件。
对于C++模块,就有些奇怪了。模块使用一个“模块名.build.cs”文件来定义,这个文件跟vcxproj(Visual Studio C++工程描述文件)类似,一个Private目录用于存放私有的头文件和源文件;以及一个Public目录用于存放公开的头文件和源文件。
Public目录下的头文件默认会暴露给其他模块(在添加模块依赖后可以直接include这个目录下的文件),Private目录下的则不会(除非手动添加PrivateIncludePath)。
所以,创建一个C++模块的规则就是,在Engine/Source 或者 你的游戏工程/Source 下面创建一个新的目录并添加一个.Build.cs文件。这个模块对其他模块的依赖也需要在.Build.cs文件夹中配置好。
对于整合第三方代码也是一样,创建一个目录,一个 .Build.cs,并在 .Build.cs 文件中描述该模块如何构建以及哪些头文件需要暴露给其他模块。
一个C++模块可以被编译为一个整体(monolith),也可以编译为其他模块(一个可执行文件,Dll等)的一部分,又或是一个.dll用于热加载。这就是虚幻提供的灵活性。
参考Modules
Targets(目标)
虚幻中的一个Target可以被理解为前面提到的一个“编译形式”。
UnrealBuildTool支持构建多个目标类型: - Game游戏 - 一个独立的游戏 - Client客户端 - 与游戏相同,但不包含任何服务器代码。适用于网络游戏。 - Server服务器 - 与游戏相同,但不包含任何客户端代码。适用于网络游戏中的专用服务器。 - Editor编辑器 - 扩展虚幻编辑器的目标。 - Program程序 - 构建在虚幻引擎之上的独立实用程序。
目标是通过扩展名为.Target.cs的C#源文件声明的,并存储在项目的Source目录下。 可以通过它来设置一堆Target所依赖的定义和其他属性等。即使像UnrealHeaderTool这样的Unreal实用程序也是作为Program目标构建的。
生成项目文件
首先,要做的是运行GenerateProjectFiles。但是......会发生什么?
- Unreal Build Tool被构建了。
- 批处理文件调用了类似如下的命令(取决于您的项目,Visual Studio版本,平台等)
-ProjectFiles -nodummyconfigs -game -engine -2017 "-project=Path\To\Your\Project.uproject" -Platforms=Win64+XboxOne+UWP64 -noSolutionSuffix - Unreal Build Tool会在引擎和游戏目录搜索所有带有.Build.cs拓展的文件来发现所有定义的模块。
- Unreal Build Tool会搜索所有带有.Target.cs拓展的文件来发现所有定义的目标。
- 它将生成一个包含所有目标作为构建配置和所有模块作为项目的解决方案。
C#项目只是源文件夹中的.csproj文件。C ++项目并不完全是“标准”项目。它不再调用MSBuild,而是调用UnrealBuildTool!
构建C++项目
在Unreal中构建C++项目时,您可以看到(基于vcxproj的NMakeBuildCommandLine属性)将调用与此类似的命令行:
C:\Path\To\Your\Engine\Build.bat TargetName Win64 Debug "$(SolutionDir)$(ProjectName).uproject" -waitmutex $(AdditionalBuildArguments) -2017
它的背后其实又调用了UnrealBuildTool!
那么,UnrealBuildTool在这儿的作用是:
- 编译目标。它在运行时编译了.Target.cs代码(使用C#编译器)来获取构建属性。这是UnrealBuildTool从中获取大部分定义和平台信息的地方。某些属性(例如bBuildEditor)表示你需要的是构建编辑器。它会创建一个WITH_EDITOR定义,然后由编译器转发到源文件。以实现源代码中的条件编译:#if WITH_EDITOR 条件编译。
- 解析所有依赖模块,包含来自.Target.cs和.Build.cs(模块)的依赖。
- 将编译所有依赖模块的Build.cs,以获取有关如何构建每个模块的额外属性。
- 解析哪些模块使用了共享编译头(即.Build.cs文件中包含SharedPCHHeaderFile属性,比如CoreUObject,Core,Engine等)。
- 解析哪些模块依赖于UObject模块。
- 对所有依赖于UObject的模块运行Unreal Header Tool,这时虚幻引擎会注入一些行为到你的类中,强制你在文件中加入由Unreal Header Tool生成的“.generated.h”头文件。
- 基于Unreal Header Tool生成的代码,解析所有Include路径。
- 基于解析后的路径、定义、外部库等,生成一系列会在目标环境执行的命令列表:
- 为共享预编译头调用编译器(CL.EXE)
- 调用编译器来编译源文件(CL.EXE)
- 调用链接器(LINK.EXE)
- 调用所有这些操作
显然,这些步骤比较简略。还有更多的细节和设置,比如你是否使用CLR,是否使用Mono,是否使用Clang等等。但大致的步骤和上面所讲的一样。
结论
我希望这篇文章可以帮助那些习惯使用标准构建工具的人了解UnrealBuildTool的细节。
理解UnrealBuildTool的更多相关文章
- 理解CSS视觉格式化
前面的话 CSS视觉格式化这个词可能比较陌生,但说起盒模型可能就恍然大悟了.实际上,盒模型只是CSS视觉格式化的一部分.视觉格式化分为块级和行内两种处理方式.理解视觉格式化,可以确定得到的效果是应 ...
- 彻底理解AC多模式匹配算法
(本文尤其适合遍览网上的讲解而仍百思不得姐的同学) 一.原理 AC自动机首先将模式组记录为Trie字典树的形式,以节点表示不同状态,边上标以字母表中的字符,表示状态的转移.根节点状态记为0状态,表示起 ...
- 理解加密算法(三)——创建CA机构,签发证书并开始TLS通信
接理解加密算法(一)--加密算法分类.理解加密算法(二)--TLS/SSL 1 不安全的TCP通信 普通的TCP通信数据是明文传输的,所以存在数据泄露和被篡改的风险,我们可以写一段测试代码试验一下. ...
- node.js学习(三)简单的node程序&&模块简单使用&&commonJS规范&&深入理解模块原理
一.一个简单的node程序 1.新建一个txt文件 2.修改后缀 修改之后会弹出这个,点击"是" 3.运行test.js 源文件 使用node.js运行之后的. 如果该路径下没有该 ...
- 如何一步一步用DDD设计一个电商网站(一)—— 先理解核心概念
一.前言 DDD(领域驱动设计)的一些介绍网上资料很多,这里就不继续描述了.自己使用领域驱动设计摸滚打爬也有2年多的时间,出于对知识的总结和分享,也是对自我理解的一个公开检验,介于博客园这个平 ...
- 学习AOP之透过Spring的Ioc理解Advisor
花了几天时间来学习Spring,突然明白一个问题,就是看书不能让人理解Spring,一方面要结合使用场景,另一方面要阅读源代码,这种方式理解起来事半功倍.那看书有什么用呢?主要还是扩展视野,毕竟书是别 ...
- ThreadLocal简单理解
在java开源项目的代码中看到一个类里ThreadLocal的属性: private static ThreadLocal<Boolean> clientMode = new Thread ...
- JS核心系列:理解 new 的运行机制
和其他高级语言一样 javascript 中也有 new 运算符,我们知道 new 运算符是用来实例化一个类,从而在内存中分配一个实例对象. 但在 javascript 中,万物皆对象,为什么还要通过 ...
- 深入理解JS 执行细节
javascript从定义到执行,JS引擎在实现层做了很多初始化工作,因此在学习JS引擎工作机制之前,我们需要引入几个相关的概念:执行环境栈.全局对象.执行环境.变量对象.活动对象.作用域和作用域链等 ...
随机推荐
- SUSE 中文是乱码
http://www.wo81.com/tec/os/suse/2014-04-30/186.html 操作系统:SUSE Linux Enterprise 11 问题:vi 打开文件,中文是乱码 ...
- Gin-Go学习笔记五:Gin-Web框架 文件的操作
文件的操作 1> 文件的创建,删除,写入内容,读取内容.(此实例使用的是text文件) 2> Gin 并没有提供文件的创建,删除,读写这个操作的专门的接口,所以采用的是常用 ...
- Clang交叉编译初识
最近工作中要编译一个第三方的C库用于iOS端使用,我直接在Mac OS的终端中./configure & make & make install常规走下来,却无法在真机iOS上使用,提 ...
- [转]C++ 堆栈溢出的原因以及可行的解决方法
栈溢出(stackoverflow)的原因及解决办法 大家都知道,Windows程序的内存机制大概是这样的:全局变量(局部的静态变量本质也属于此范围)存储于堆内存,该段内存较大,一般不会溢出: 函数地 ...
- The field file exceeds its maximum permitted size of 1048576 bytes.
问题原因:Spring Boot内置tomcat限制了请求文件的大小 下面是修改方法:根据自己的Spring Boot版本 2.0之后版本的修改方式 在主配置文件 application.proper ...
- 微软源码站点-C#编程指南
地址:https://referencesource.microsoft.com/#System.Web/HttpPostedFile.cs 微软的源码可以在这里看. ---------------- ...
- UiPath: Selectors repair 选择器的修复,即被选择的按钮发生改变如何选择第二按钮
实现批量注册用户功能时,出现第一个用户注册完时,弹出确认按钮,点击即可,但是第二个用户注册完成时,弹出的按钮与第一个有差异,图形用户界面元素及其父元素的属性都发生改变.所以就点不了按钮,就卡死在这.如 ...
- 201800628模拟赛T2——最大土地面积
题目描述 在某块平面土地上有N个点,你可以选择其中的任意四个点,将这片土地围起来,当然,你希望这四个点围成的多边形面积最大. 输入输出格式 输入格式: 第1行一个正整数N,接下来N行,每行2个数x,y ...
- 微信2.1 for Windows发布 微信群可多人语音或视频通话
5月31日,windows电脑版微信发布更新,微信2.1 for Windows带来最主要的功能是微信群可以多人语音或视频通话了,建个家庭群组,常年在外工作的家人也可以每天见面了,多亲切! 除了可以建 ...
- 11-cmake语法-函数和宏的定义
cmake语法不仅仅可以适用于 CMakeLists.txt,也适用于 xxx.cmake 文档. 在 OpenCV 的 CMakeLists.txt 中,很多 ocv_XXX() 的函数,都是定义在 ...