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

news2024/11/24 22:31:44

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.CreateMakefile
				string 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.coloradmin.cn/o/2063757.html

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

相关文章

AOC U27U2P创作设计旗舰——传递情感,用色彩说话!

摘要&#xff1a;每一次设计都是一种表达&#xff0c;每一次创作都是一次成长 并不是所有的路在一开始走的时候&#xff0c;都能找到正确的方向。对于设计师而言&#xff0c;在创作与设计的道路上&#xff0c;亦是如此。灵感的枯竭、无休止的改稿、色彩的偏差等等&#xff0c;…

基于springboot的校园失物招领系统--论文pf

TOC springboot483基于springboot的校园失物招领系统--论文pf 第1章 绪论 1.1 课题背景 二十一世纪互联网的出现&#xff0c;改变了几千年以来人们的生活&#xff0c;不仅仅是生活物资的丰富&#xff0c;还有精神层次的丰富。在互联网诞生之前&#xff0c;地域位置往往是人…

Linux yum提示Error downloading packages

很明显的错误&#xff0c;没有考虑过磁盘空间&#xff0c;记录一下。 Error downloading packages:gcc-4.8.5-44.el7.x86_64: Insufficient space in download directory /var/cache/yum/x86_64/7/base/packages* free 0 * needed 16 M使用du查看当前目录下所有文件大小 du …

mac安装ipa包【金铲铲为例】

mac安装ipa包 安装PlayCover 链接&#xff1a;https://github.com/PlayCover/PlayCover 1、点最新Releases 2、cmd ↓&#xff0c;拉到最下面下载dmg 3、安装 图标拖拽到Applications里 IPA下载 以金铲铲为例&#xff0c;良心砸壳包站点&#xff0c;有能力可以支持一下…

Python办公自动化 python-pptx模块的安装与使用【1】

学好办公自动化&#xff0c;走遍天下都不怕&#xff01;&#xff01; 前面已经学习了python自动处理Excel数据和自动生成word试卷的案例&#xff0c; 今天学习一下python中的python-pptx模块&#xff0c;主要用于自动化生成和更新PPT文件。主要是python-pptx的用法&#xff0c;…

react 的学习随记

npx create-react-app my-app 创建一个名叫my-app的react的项目 npm run eject 运行 显示config 文件夹 react jsx &#xff08;使用时将babel 将jsx转为js&#xff09; 单页面时需要引用 1&#xff0c;样式&#xff08;在虚拟dom时&#xff09; 1. 引用样式时 用classNa…

(第三十三天)

1. 设置主从从 mysql57 服务器 &#xff08; 1 &#xff09;配置主数据库 [rootmsater_5 ~] # systemctl stop filewalld [rootmsater_5 ~] # setenforce 0 [rootmsater_5 ~] # systemctl disable filewalld [rootmsater_5 ~] # ls anaconda-ks.cfg mysql-5.7.44-linux-g…

解决STM32使用J-Link可以擦除和读取但是无法烧录问题

现象 使用J-Link烧录模组固件&#xff0c;出现可以读取和擦除&#xff0c;但是无法烧录问题&#xff0c;提示错误如下&#xff1a; ERROR: Programming failed address 0x08000080 (program error)End of flash programmingERROR: Program failed 读出来的时候这个地址数据…

AWS EC2:助力中国企业扬帆出海

在全球化的今天&#xff0c;中国的企业家们正积极寻找机会走向世界舞台。在这个过程中&#xff0c;云计算成为了不可或缺的技术支撑。亚马逊AWS作为全球领先的云服务提供商&#xff0c;其EC2&#xff08;Elastic Compute Cloud&#xff09;弹性云服务器以其卓越的性能和广泛的基…

【学习笔记】灰色预测 GM(1,1) 模型 —— Matlab

文章目录 前言一、灰色预测模型灰色预测适用情况GM (1,1)模型 二、示例指数规律检验(原始数据级比检验)级比检验的定义GM(1,1) 模型的级比检验 模型求解求解微分方程 模型评价(检验模型对原始数据的拟合程度)残差检验级比偏差检验 三、代码实现----Matlab级比检验代码模型求解代…

jmeter中添加断言,使用包括匹配模式显示失败

1、在jmeter中为某个接口添加断言&#xff0c;测试模式中检查文本内容比较长时且模式匹配规则选择包括时则在运行时会提示失败&#xff0c;实际接口已经正确返回数据了。 2、这种情况下失败是因为测试模块中的检查文本内容过长&#xff0c;不应该在模式匹配规则中选择包括&…

“由于找不到msvcr110.dll无法继续执行”错误提示?msvcr110.dll在电脑中处于什么位置?

“由于找不到msvcr110.dll无法继续执行”的错误提示&#xff0c;是许多用户在使用基于Microsoft Visual C开发的应用程序时可能遇到的一个典型问题。这条错误消息指出系统缺少一个关键的动态链接库文件&#xff08;DLL&#xff09;&#xff0c;即 msvcr110.dll&#xff0c;这是…

融资管理系统项目

系列文章目录 第一章 基础知识、数据类型学习 第二章 万年历项目 第三章 代码逻辑训练习题 第四章 方法、数组学习 第五章 图书管理系统项目 第六章 面向对象编程&#xff1a;封装、继承、多态学习 第七章 封装继承多态习题 第八章 常用类、包装类、异常处理机制学习 第九章 集…

SpringBoot框架如何实现上传与下载查看文件

基于SpringBoot框架&#xff0c;如何实现文件的上传与下载查看 提要 本项目借鉴于spring-guides/gs-uploading-files: Uploading Files :: Learn how to build a Spring application that accepts multi-part file uploads. (github.com)SpringBoot官网学习文档关于如何下载文…

Git基础学习(一)

文章目录 一. Git1. 定义2. SVN与Git的的区别 一. Git 1. 定义 Git 是一种分布式版本控制系统&#xff0c;用于管理软件项目的源代码。它是由 Linux 之父 Linus Torvalds 开发的&#xff0c;并已经成为了现代软件开发领域中最流行的版本控制系统之一。 使用 Git 可以追踪代码…

旅游管理系统

TOC springboot0748旅游管理系统 第1章 绪论 1.1课题背景 计算机的普及和互联网时代的到来使信息的发布和传播更加方便快捷。用户可以通过计算机上的浏览器访问多个应用系统&#xff0c;从中获取一些可以满足用户需求的管理系统。网站系统有时更像是一个大型“展示平台”&a…

基于SpringBoot的家电销售展示平台--论文pf

TOC springboot514基于SpringBoot的家电销售展示平台--论文pf 第1章 绪论 1.1选题动因 当前的网络技术&#xff0c;软件技术等都具备成熟的理论基础&#xff0c;市场上也出现各种技术开发的软件&#xff0c;这些软件都被用于各个领域&#xff0c;包括生活和工作的领域。随着…

HTML+JS谁是卧底游戏

先说一句&#xff1a;一段时间没发文章&#xff0c;好多僵尸粉关注我&#xff0c;这CSDN&#x1f620; 主要功能 玩家设置&#xff1a;在游戏开始前&#xff0c;输入总人数、卧底人数和白板人数。系统会自动计算出剩下的平民人数&#xff0c;并随机分配身份。 身份查看&#…

html+css+js实现登录界面设计

在现代网页设计中&#xff0c;创建一个功能齐全且用户友好的登录页面是至关重要的。本文将介绍如何使用 HTML 和 CSS 创建一个简单而有效的登录页面&#xff0c;包括验证码、记住密码选项及忘记密码链接。 1. HTML 结构 我们将从 HTML 代码开始&#xff0c;构建一个包含登录表…

【Google SEO】搜索引擎索引综合SEO指南

有没有想过网站是如何在搜索引擎上列出的&#xff0c;以及 Google、Bing 和其他公司如何在几秒钟内为我们提供大量信息&#xff1f; 这种闪电般快速性能的秘诀在于搜索索引。它可以与所有页面的庞大且完美有序的目录档案进行比较。进入索引意味着搜索引擎已经看到了你的页面&a…