UE4编安卓时Core模块为何只include Android文件夹?

Core模块

Core模块是整个引擎中最核心的模块。几乎UE4中的每个其他模块都导入Core。Engine\Source\Runtime\Core\Private下有很多文件夹,下面罗列一部分:

G:\St\EngineSource\Engine\Source\Runtime\Core\Private 的目录
2024/07/18  12:02    <DIR>          .
2024/07/18  12:02    <DIR>          ..
2024/08/01  11:29    <DIR>          Android
2024/08/01  11:29    <DIR>          Apple
2024/08/01  11:29    <DIR>          HAL
2024/08/01  11:29    <DIR>          IOS
2024/07/18  12:02    <DIR>          Linux
2024/07/18  12:02    <DIR>          Mac
2024/07/18  12:02    <DIR>          Math
2024/07/18  12:02    <DIR>          Memory
2024/07/18  12:02    <DIR>          Unix
2024/08/01  11:29    <DIR>          Windows

本文的目的

首先,标题的这个说法是不完全正确的。正确的说法是:“Core模块的 Core\Private 是被包含的文件夹,但其中的无关的平台的源文件被排除了”。简称为 “ 在编安卓时只会include其中的Engine\Source\Runtime\Core\Private\Android 文件夹 ”。

在编译安卓时,只会include其中的Android,以及和平台无关的文件夹例如Math,而Mac、Unix等其它平台的文件夹,就不会包含在内。本文的目的是为了找到“在编译安卓时只会include其中的Android”的引擎代码逻辑。

以这篇文章介绍的方法( http://t.csdnimg.cn/Rd6am )调试安卓构建。具体的命令如下图:

堆栈

UEBuildModuleCPP.FindInputFilesFromDirectoryRecursive() at G:/St/EngineSource/Engine/Source/Programs/UnrealBuildTool/Configuration/UEBuildModuleCPP.cs:line 1,458
UEBuildModuleCPP.FindInputFiles() at G:/St/EngineSource/Engine/Source/Programs/UnrealBuildTool/Configuration/UEBuildModuleCPP.cs:line 1,403
UEBuildModuleCPP.Compile()
UEBuildBinary.SetupBinaryLinkEnvironment()
UEBuildBinary.Build()
UEBuildTarget.Build()
BuildMode.CreateMakefile()
BuildMode.Build()
BuildMode.Execute()
UnrealBuildTool.Main()

其中的ExcludeNames是

[0] = {string} "Win32"
[1] = {string} "Win64"
[2] = {string} "HoloLens"
[3] = {string} "Mac"
[4] = {string} "XboxOne"
[5] = {string} "PS4"
[6] = {string} "IOS"
[7] = {string} "Linux"
[8] = {string} "LinuxAArch64"
[9] = {string} "AllDesktop"
[10] = {string} "TVOS"
[11] = {string} "Switch"
[12] = {string} "Quail"
[13] = {string} "Lumin"
[14] = {string} "XXX"
[15] = {string} "Windows"
[16] = {string} "Microsoft"
[17] = {string} "Apple"
[18] = {string} "Unix"
[19] = {string} "Sony"
[20] = {string} "Fake"

整个堆栈的解释:
1、本函数(UnrealBuildTool.UEBuildModuleCPP.FindInputFilesFromDirectoryRecursive):如果路径名称字符串包含了上面罗列了字符串之一,那就会被Exclude(剔除)掉;
2、父方法(UnrealBuildTool.UEBuildModuleCPP.FindInputFiles):排除掉其它平台的文件夹后,得到InputFiles,后面会说所谓Input是什么意思;

(图:函数Watch实况)

3、祖先方法(UnrealBuildTool.UEBuildModuleCPP.Compile):这个方法实际上是具体某个Module执行的,作用是编译这个模块(编译这个模块内的所有有必要编译的代码)。但是,不是实际上交给CPU运行底层编译器(cl.exe)的效果,而是做好任务规划,就好像是老师给学生们布置作业一样,这里的作用是把作业清单给布置好。所以前面说的InputFiles就是这样的一份将要交给后续编译器实际编译的“作业清单”了。该方法的签名是:
public override List<FileItem> Compile(ReadOnlyTargetRules Target 目标包含平台信息, UEToolChain ToolChain 值是AndroidToolChai这篇文档不细究其含义, CppCompileEnvironment BinaryCompileEnvironment, FileReference SingleFileToCompile, ISourceFileWorkingSet WorkingSet, TargetMakefile Makefile)

(图:Target的Watch实况,其中我们关注到Platform信息是Android)

TargetMakefile文件是指编译Target时的makefile。Makefile的含义见  http://t.csdnimg.cn/Rd6am 。

4、祖先方法(UnrealBuildTool.UEBuildBinary.SetupBinaryLinkEnvironment):这个方法主要是将所有Modules的所有需要编译的代码文件(InputFiles)都汇总在一起。

 每一个模块的InputFiles都会汇聚在 BinaryLinkEnvironment.InputFiles 中:

foreach (UEBuildModule Module in Modules) {//省略若干代码LinkInputFiles = Module.Compile(Target, ToolChain, BinaryCompileEnvironment, SingleFileToCompile, WorkingSet, Makefile);//省略若干代码foreach (FileItem LinkInputFile in LinkInputFiles){ BinaryLinkEnvironment.InputFiles.Add(LinkInputFile); }}

5、祖先方法(UnrealBuildTool.UEBuildBinary.Build):这个方法的作用主要是封装了两个函数
SetupBinaryLinkEnvironment 汇聚需要编译的代码文件
ToolChain.LinkAllFiles 编译后的中间文件需要链接(Link),汇聚链接的任务,同样地,它也不是立即调用底层链接器(link-filter.exe)。

即UnrealBuildTool.UEBuildBinary.Build的作用是汇总了所有的编译任务与链接任务。

6、祖先方法(UnrealBuildTool.UEBuildTarget.Build):这个方法的目的是为了构建出单个binary文件,在本案例中是 Binaries/Android/项目名Client-arm64.so 文件;


7、祖先方法(UnrealBuildTool.BuildMode.CreateMakefile):这个方法的目的是准备好Makefile.bin,下面是伪代码

if 存在Makefile,本例子中是 G:\St\我的项目名\Intermediate\Build\Android\我的项目名Client\Development\Makefile.bin :
{ Makefile = 加载该Makefile,见“图:Makefile的加载”; 
}if (Makefile == null)
{走上面提到的所有方法,获取任务列表;创建Makefile,并填充任务列表;
}
else
{ 针对Makefile中的任务进行再次确认,对于新增的、更新了的代码再次编译与链接;  
}

8、祖先方法(UnrealBuildTool.BuildMode.Build):所谓的Mode,主要是指TargetDescriptors中描述的 Target(安卓)和Configuration(Development)。它主要做两件事情:
确认Makefile也就是确认所有的编译、链接任务(UnrealBuildTool.BuildMode.CreateMakefile)
实际让CPU执行这些任务(ActionGraph.ExecuteActions)

9、祖先方法(UnrealBuildTool.BuildMode.Execute)。
10、总入口(UnrealBuildTool.UnrealBuildTool.Main):UBT的总入口。

ExcludeNames

前文提到的ExcludeNames的原理很简单,不细说,代码如下:

 调试注意事项

1、每次断点前,都删除掉 G:\St\我的项目名\Intermediate\Build\Android\我的项目名Client\Development\Makefile.bin,目的是可以触发与InputFiles有关的逻辑,也就是分析编译任务、链接任务的逻辑;
2、先断点在 "Core" 这个module上,前提是按照下面方法添加C#代码,断点成功后,再下断点在 UnrealBuildTool.UEBuildModuleCPP.FindInputFilesFromDirectoryRecursive 上

运行数据截图留念

(图:经过过滤后的需要编译的部分文件)

(图:Makefile的加载)

UEBuildTarget.{MyProjectName}Client.json

起初研究这个问题的时候,以为Core模块只include了Engine\Source\Runtime\Core\Private\Android文件夹,但只是说include文件夹中的部分文件被加入到了InputFiles中, Engine\UE4\Source\Runtime\Core\Core.Build.cs 中PrivateIncludePaths包含的是整个 Runtime/Core/Private:

public class Core : ModuleRules
{public Core(ReadOnlyTargetRules Target) : base(Target){
……
PrivateIncludePaths.AddRange(new string[] {"Developer/DerivedDataCache/Public","Runtime/SynthBenchmark/Public","Runtime/Core/Private",
……

在上面打包的过程中,产出了UEBuildTarget.项目名Client.json,里面包含了所有模块的实际 include 的列表。

ModuleRules

ModuleRules是指编译某模块的规则,例如说PrivateIncludePaths需要包含什么路径。它的触发路径是 UEBuildTarget.Create → CreateAllDependentModules → CreateModules → CreateModuleRules() → new 模块类。详见 http://t.csdnimg.cn/Rd6am 。在Core.build.cs中断点可以发现其调用堆栈:

零碎

1、 识别出Action过期的代码是: UnrealBuildTool.ActionGraph.IsActionOutdated
2、 【问AI】在UE4中,.uhtmanifest的作用是什么?下面是它的相关代码,供你参考

FileReference ModuleInfoFileName = FileReference.Combine(Makefile.ProjectIntermediateDirectory, TargetDescriptor.Name + ".uhtmanifest");
ExternalExecution.ExecuteHeaderToolIfNecessary(BuildConfiguration, TargetDescriptor.ProjectFile, TargetDescriptor.Name, Makefile.TargetType, Makefile.bHasProjectScriptPlugin, UObjectModules: Makefile.UObjectModules, ModuleInfoFileName: ModuleInfoFileName, bIsGatheringBuild: bIsGatheringBuild, bIsAssemblingBuild: bIsAssemblingBuild, WorkingSet: WorkingSet);

【AI答】在UE4中,`.uhtmanifest`文件是用于存储模块信息的清单文件。它记录了模块的依赖关系、编译选项和其他相关信息,以便在构建过程中进行模块的编译和链接。

根据提供的代码片段,可以看出它的作用是调用头文件工具(Header Tool)来生成或更新`.uhtmanifest`文件。具体来说,代码中的`ExternalExecution.ExecuteHeaderToolIfNecessary()`函数用于执行头文件工具,并传递相关参数,包括构建配置、项目文件、模块名称、目标类型等。

通过执行头文件工具,UE4可以分析项目的代码和模块依赖关系,并生成或更新`.uhtmanifest`文件。这个清单文件在后续的构建过程中被引擎和编辑器使用,以确保正确的模块编译和链接。

总结起来,`.uhtmanifest`文件在UE4中的作用是记录模块信息,用于构建过程中的模块编译和链接。

3、在找代码的过程中,看到有

Engine\UE4\Source\Developer\Android\AndroidTargetPlatform\AndroidTargetPlatform.Build.cs:4
PublicIncludePaths.AddRange(new string[]{"Runtime/Core/Public/Android"}
);

它也提到了安卓目录 Runtime/Core/Public/Android,但它位于 AndroidTargetPlatform 模块,一个模块的Rule是不会影响到另一个模块的,所以不用关注它。

Makefile的有效性

在 UnrealBuildTool.TargetMakefile.IsValidForSourceFiles 中看到有很近似的代码,但通过阅读理解可以看出来,它是针对部分源代码文件的增删改情况,令TargetMakefile失效的。当我添加了一个代码cpp文件后,代码见“图:IsValidForSourceFiles ”,就会进入到return false的情况,从而导致重新创建Makefile。下面三件事情有关联:
1、当翻译单元,即cpp文件,不是h文件,有增删改 →
2、需要产生新的Makefile,见“代码块:Makefile赋值为空,并再次创建” →
3、由于Makefile等价于编译、链接的任务清单,所以传给底层编译器的任务就不一样了。

(图:IsValidForSourceFiles )

// UnrealBuildTool.BuildMode.CreateMakefilestring Reason;if(!TargetMakefile.IsValidForSourceFiles(Makefile, TargetDescriptor.ProjectFile, TargetDescriptor.Platform, WorkingSet, out Reason)){Log.TraceInformation("Invalidating makefile for {0} ({1})", TargetDescriptor.Name, Reason);Makefile = null;}
……Makefile = Target.Build(BuildConfiguration, WorkingSet, bIsAssemblingBuild, TargetDescriptor.SingleFileToCompile);

(代码块:Makefile赋值为空,并再次创建)

(图:UEBuildModuleCPP.GetSourceFiles(InputDirectory)方法返回的是翻译单元,即cpp文件,SourceFiles 中包含了 G:\St\EngineSource\Engine\Source\Runtime\Core\Private\Android)


(图:当新增h文件时,Makefile不会失效)

(图:判定文件夹的write时间,从而判断有效性,注意北京时间 = utc + 8)

本文总结

本文找到了“Core模块在编译Android时,实际上只编译Core/Private/Android目录下的文件,而没有编译其它平台的文件”的引擎源码,并进一步地理解“Makefile”“Module”等概念。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/877688.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

学习笔记七:基于Jenkins+k8s+Git+DockerHub等技术链构建企业级DevOps容器云平台

基于Jenkinsk8sGitDockerHub等技术链构建企业级DevOps容器云平台 安装Jenkins在kubernetes中部署jenkins创建名称空间创建pv,上传pv.yaml创建pvc创建一个sa账号通过deployment部署jenkins更新资源清单文件把jenkins前端加上service&#xff0c;提供外部网络访问 配置Jenkins获取…

数学建模学习(116):全面解析梯度下降算法及其在机器学习中的应用与优化

文章目录 1.梯度下降简介1.1 梯度下降的数学原理1.2 学习率的选择2 梯度下降变体3.梯度下降优化器3.1 动量法(Momentum)3.2 AdaGrad3.3 RMSprop3.4 Adam3.5 Python 使用不同优化器训练线性回归模型4.案例:使用梯度下降优化加利福尼亚房价预测模型4.1. 数据准备4.2. 模型训练…

功能测试和性能测试区别简析,软件测试公司如何开展有效测试?

软件功能测试旨在验证软件是否按照需求和设计规范正常运行&#xff0c;软件性能测试则是用来评估软件在特定负载条件下的行为和响应时间&#xff0c;确保软件在高并发和高需求的环境中能够稳定运行。 虽然两者都属于软件测试的重要组成部分&#xff0c;但它们的目的和重点却有…

【经典算法】BFS_最短路问题

目录 1. 最短路问题介绍2. 算法原理和代码实现(含题目链接)1926.迷宫中离入口最近的出口433.最小基因变化127.单词接龙675.为高尔夫比赛砍树 3. 算法总结 1. 最短路问题介绍 最短路径问题是图论中的一类十分重要的问题。本篇文章只介绍边权为1(或边权相同)的最简单的最短路径问…

手机谷歌浏览器怎么用

谷歌浏览器不仅在PC端受欢迎&#xff0c;在移动端也是广泛应用的。为了帮助大家更好的理解和使用手机谷歌浏览器&#xff0c;本文将详细介绍如何使用手机谷歌浏览器&#xff0c;对这款浏览器感到陌生的话就快快学起来吧。&#xff08;本文由https://chrome.cmrrs.com/站点的作者…

会声会影剪辑视频收费吗,会声会影最新破解版

会声会影2024&#xff1a;引领视频创作新时代的创新之旅** 在数字时代的浪潮中&#xff0c;视频创作已成为连接世界、表达创意的重要方式。随着技术的不断进步&#xff0c;一款名为“会声会影2024”的视频编辑软件横空出世&#xff0c;它不仅继承了前代产品的优秀传统&#xf…

如何在VMwareWorkstation上安装的ESXi系统扩容存储

在做ESXi的相关实验的时候&#xff0c;需要扩容ESXi的存储&#xff0c;那么如何进行操作呢&#xff1f; 扩容VMwareWorkstation上虚拟机的存储 首先我们需要先扩容虚拟机上的存储&#xff08;可不关闭虚拟机&#xff09;按照图下所示&#xff0c;右键虚拟机&#xff0c;点击设…

银行总分支文件分发系统:在安全与效率之间找到平衡

银行的组织结构通常根据其规模、业务范围和地域分布而有所不同&#xff0c;但一般会包括以下几个层级&#xff1a;总行-区域总部或分行-分行-支行-业务中心或服务中心-国际分支机构-附属机构或子公司。 在日常中&#xff0c;存在总分支文件分发的业务场景&#xff0c;文件类型通…

最方便的MODIS数据下载

这篇文章给出现在最方便的MODIS数据下载方法。 传统的方式通过访问NASA的数据中心&#xff1a;https://ladsweb.modaps.eosdis.nasa.gov/ 具体方法可以参考我前面的一篇文章&#xff1a;https://blog.csdn.net/qq_39085138/article/details/116302600 但是可以发现如果想要处理…

代码随想录算法训练营第二十二天(回溯 一)

开始学习回溯&#xff01; 回溯理论基础 代码随想录文章链接:代码随想录 文章摘要: 什么是回溯法 回溯法也可以叫做回溯搜索法&#xff0c;它是一种搜索的方式。 在二叉树系列中&#xff0c;我们已经不止一次&#xff0c;提到了回溯。 回溯是递归的副产品&#xff0c;只…

屏幕翻译器下载哪个?语言达人必备这些

想象一下&#xff0c;你站在人头攒动的12分钟洛杉矶沙滩音乐节现场&#xff0c;四周是来自世界各地的音乐爱好者&#xff0c;他们带着各自的文化与热情&#xff0c;用不同的语言欢呼、交谈。 舞台上&#xff0c;乐队正激情演奏&#xff0c;旋律激荡人心&#xff0c;但偶尔传来…

HarmonyOS 开发

环境 下载IDE 代码 import { hilog } from kit.PerformanceAnalysisKit; import testNapi from libentry.so; import { router } from kit.ArkUI; import { common, Want } from kit.AbilityKit;Entry Component struct Index {State message: string Hello HarmonyOS!;p…

AI赋能软件测试:从自动化到智能化,让测试工作事半功倍

引言 在当今这个日新月异的数字时代&#xff0c;人工智能&#xff08;AI&#xff09;正以不可阻挡之势渗透并重塑着各行各业&#xff0c;其中&#xff0c;软件开发与测试领域更是迎来了前所未有的变革。随着软件系统的复杂性日益增加&#xff0c;用户对软件质量、性能及安全性的…

SQL每日一练-0816

今日SQL题&#xff1a;计算每个项目的年度收入增长率 难度系数&#xff1a;&#x1f31f;☆☆☆☆☆☆☆☆☆ 1、题目要求 计算每个项目每年的收入总额&#xff0c;并计算项目收入环比增长率。找出每年收入增长率最高的项目。输出结果显示年份、项目ID、项目名称、项…

微软AI人工智能认证有哪些?

微软提供的人工智能认证主要包括以下几个方面&#xff1a; Azure AI Fundamentals&#xff08;AI900认证&#xff09;&#xff1a;这是一个基础认证&#xff0c;旨在展示与Microsoft Azure软件和服务开发相关的基本AI概念&#xff0c;以创建AI解决方案。它面向具有技术和非技术…

[数据集][目标检测]航拍屋顶检测数据集VOC+YOLO格式458张3类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;458 标注数量(xml文件个数)&#xff1a;458 标注数量(txt文件个数)&#xff1a;458 标注类别…

【EI检索稳定】2024年第四届数字化社会与智能系统国际学术会议(DSInS 2024)

由悉尼科技大学和西南交通大学联合主办&#xff0c;四川大学、中南大学社会计算研究中心、西南财经大学、武汉理工大学协办的2024年第四届数字化社会与智能系统国际学术会议将于2024年11月22-24日在中国郑州举行。会议主题主要聚焦智能系统在数字化社会中的相关技术和应用发展。…

Vsphere连接ESXI主机创建虚拟机并安装操作系统

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f427;Linux基础知识(初学)&#xff1a;点击&#xff01; &#x1f427;Linux高级管理防护和群集专栏&#xff1a;点击&#xff01; &#x1f510;Linux中firewalld防火墙&#xff1a;点击&#xff01; ⏰️创作…

Nature系列|病理人工智能综述以及模型的可解释性分析|顶刊速递·24-08-21

小罗碎碎念 文献日推主题&#xff1a;病理AI综述&模型可解释性分析 今天准备了四篇文章&#xff0c;感觉之前一次推六篇&#xff0c;多了点&#xff0c;以后都这个标准了。 前三篇都是nature reviews系列的大综述&#xff0c;其中两篇是不区分癌种的&#xff0c;第三篇是专…

FTP协议-匿名用户登录 从0到1

前言 日常大家可能接触web漏洞比较多而对其他端口及协议不那么了解&#xff0c;其实其他协议漏洞在渗透中也同样重要只是平时可能接触得不多。本文将介绍FTP协议、FTP匿名用户登录及其具体流程分析和自动化利用demo。 FTP简介 FTP是File Transfer Protocol&#xff08;文件传…