【UE4源代码观察】观察Core模块

话题

Core模块是整个引擎中最核心的模块,在之前的博客【UE4源代码观察】可视化所有模块的依赖情况中有统计,它被983个模块引用,恐怕除了第三方的模块外基本所有模块都有引用。我想首先观察其中的内容,然后再做测试:将Core模块拷贝到之前【UE4源代码观察】手动建立一个使用UBT进行编译的空白工程建立的空白工程中,看能否将它成功编译,理论上讲,“核心”不应再依赖太多其他的东西,所以我应该不会再需要补充太多它所依赖的东西。

观察

Core模块包含了九百个h文件和近四百个cpp文件,有相当多的内容。在VS的解决方案资源管理器中观察它的文件层级结构是这样的:
在这里插入图片描述
在“Public”层级下分为了35个文件夹和7个头文件,我想在这个层级下观察每个文件夹和头文件都代表了哪些内容。

I.平台相关的文件夹

Android Apple Clang HoloLens IOS Linux Lumin Mac Unix Windows 文件夹都是对应各个平台的内容,而GenericPlatform 是平台抽象类,它其中包含很多其他平台中的类的基类。UE4在跨平台上的语法是这样的:
以FMemory为例,打开UnrealMemory.h:

struct CORE_API FMemory
{
	/** @name Memory functions (wrapper for FPlatformMemory) */

	static FORCEINLINE void* Memmove( void* Dest, const void* Src, SIZE_T Count )
	{
		return FPlatformMemory::Memmove( Dest, Src, Count );
	}

	static FORCEINLINE int32 Memcmp( const void* Buf1, const void* Buf2, SIZE_T Count )
	{
		return FPlatformMemory::Memcmp( Buf1, Buf2, Count );
	}

会发现FMemory中使用了很多FPlatformMemory的成员函数。
FPlatformMemory是什么要看它include的"HAL/PlatformMemory.h":

#include COMPILED_PLATFORM_HEADER(PlatformMemory.h)

这个宏会根据不同的平台扩展为对应平台的文件,比如我现在是Windows,则扩展为了WindowsPlatformMemory.h:
在这里插入图片描述
在这个文件中会看到:

typedef FWindowsPlatformMemory FPlatformMemory;

FWindowsPlatformMemory这个类的基类是FGenericPlatformMemory

II.其他文件夹

algo: algorithm(算法)。包含众多算法,如二分法查找等
Async:异步。多线程相关的内容,很重要,TaskGraphInterfaces就在这里。
Container:容器类
Delegates:应该是一个重要的部分,看名字似乎是入口函数?对此理解不深,待后续理解。
FramePro:看名字似乎是Frame Profiler?
HAL:Hardware Abstraction Layer(硬件抽象层)
Hash:看名字似乎和哈希有关?
Internationalization:包含本地化相关内容,包括FText的定义。
Logging:打Log相关
Math:数学库
MemPro:看名字是Memory Profiler?
Misc:杂项
Modules:模块相关的基本功能
ProfilingDebugging:看名字似乎是性能分析调试相关。
Serialization:序列化相关。
Templates:模板类,包括智能指针。
UObject:虽然UObject的定义有专门的模块,但Core模块似乎需要一些提前定义的内容,比如UObjectHierarchyFwd.h中存放的前向声明,其他还包含一些XXXVersion.h,待后续研究。

IO看名字本以为是个有分量的部分,但其中只有一个IoDispatcher文件,目前还不清楚是做什么用的。
Memory看名字本以为是个有分量的部分,但其中只有一个MemoryArena文件,目前还不清楚是做什么用的。
MSVC其中只包括了一个头文件,在这个头文件中只有一个宏。

还有一些目前并不太清楚和什么相关的:
Concepts Features Stats Traits。其中Stats或许应该研究下。

III.头文件

Core.h中include了大量的h文件,本身不包含其他定义,目前还不清楚在什么情况下需要include“Core.h”。
CoreMinimal.h被前者include,它很重要,通常都能在其他头文件中看到它第一个被include。这个文件会include一些最基本的头文件,它和UE4的IWYU规则有关。
CoreTypes.h它include了一些最底层的定义,被CoreMinimal所include,
CoreFwd.h包含了很多基本的类的前向声明,它也被CoreMinimal所include。
CoreSharedPCH.h中也include了大量的头文件,但也不清楚什么情况下需要include它。
CoreGlobals.h中有很多内容,应该非常重要,待后续研究。
PixelFormat.h还不清楚作用。

测试

完整工程见GIT上的完整工程,我把步骤与遇到的问题记录下来:

1.拷贝模块

虽然Core模块很核心,但是它本身还是依赖了两个模块:BuildSettings 和 TraceLog。这两个模块本身内容量不多,而且并没有再依赖于更多的模块了,因此这里就直接将他们一起拷贝过来了。

2.注释掉PrivateIncludePathModuleNames

1>UnrealBuildTool : error : Could not find definition for module 'TargetPlatform', (referenced via Target -> TestA.Build.cs -> Core.Build.cs)

我发现在PrivateIncludePathModuleNames中,Core模块还指定一些模块中的文件会被include

PrivateIncludePathModuleNames.AddRange(
		new string[] {
			"TargetPlatform",
			"DerivedDataCache",
            "InputDevice",
            "Analytics",
			"RHI"
		}
		);

这些模块本身又会依赖更多的模块,因此若将它们拷贝过来会耗费很大的力气,于是我选择先将这部分注释掉。这一操作一定会导致后续有include找不到,但如果牵扯到的内容不多的话,那再继续注释掉相关的功能也可以接受。

3.拷贝第三方库

1>UnrealBuildTool : error : Could not find definition for module 'zlib', (referenced via Target -> TestA.Build.cs -> Core.Build.cs)

有些第三方库的模块找不到,于是我拷贝了这些模块过来,包括zlib IntelTBB IntelVTune ICU。这些库似乎.lib文件也需要一块拷贝(我并不确定能否用源码编译出来)。一下子让工程的体积变大了。

4.注释掉相关的功能

第2步的“恶果”来了:

1>  [5/18] Module.Core.9_of_12.cpp
1>D:/0_WorkSpace/UEYaksueTest/Engine/Source/Runtime/Core/Private/Serialization/Archive.cpp(25): fatal error C1083: 无法打开包括文件: “Interfaces/ITargetPlatform.h”: No such file or directory
1>  [6/18] Module.Core.7_of_12.cpp
1>D:/0_WorkSpace/UEYaksueTest/Engine/Source/Runtime/Core/Private/Misc/CoreMisc.cpp(18): fatal error C1083: 无法打开包括文件: “DerivedDataCacheInterface.h”: No such file or directory

但万幸所牵扯的内容很少,先注释掉h文件的include,然后再注释掉使用的地方就好了。

5.处理链接错误

1>Module.Core.2_of_12.cpp.obj : error LNK2001: 无法解析的外部符号 "wchar_t * GInternalProjectName" (?GInternalProjectName@@3PA_WA)
1>Module.Core.7_of_12.cpp.obj : error LNK2001: 无法解析的外部符号 "wchar_t * GInternalProjectName" (?GInternalProjectName@@3PA_WA)
1>Module.Core.8_of_12.cpp.obj : error LNK2001: 无法解析的外部符号 "wchar_t * GInternalProjectName" (?GInternalProjectName@@3PA_WA)
1>Module.Core.11_of_12.cpp.obj : error LNK2001: 无法解析的外部符号 "wchar_t * GInternalProjectName" (?GInternalProjectName@@3PA_WA)
1>Module.Core.2_of_12.cpp.obj : error LNK2001: 无法解析的外部符号 "wchar_t const * const GForeignEngineDir" (?GForeignEngineDir@@3PEB_WEB)
1>D:\0_WorkSpace\UEYaksueTest\Engine\Binaries\Win64\Test1.exe : fatal error LNK1120: 2 个无法解析的外部命令

这两个没找到的变量都是extern,在CoreGlobals.h中有定义:

extern CORE_API TCHAR GInternalProjectName[64];
extern CORE_API const TCHAR* GForeignEngineDir;

他们的定义都在UE4Game.cpp中:

TCHAR GInternalProjectName[64] = TEXT("");
IMPLEMENT_FOREIGN_ENGINE_DIR()

由于在源代码的Target,UE4Editor.Target.cs中有:

ExtraModuleNames.Add("UE4Game");

所以这两个变量定义能够找到。但是现在我的工程里没有UE4Game模块,所以并不能找到定义。
于是,我临时将 GInternalProjectName 的 extern符号去掉,将 GForeignEngineDir 使用的地方注掉,便可以保证了编译通过。

6.完成!测试

为了测试Core模块能否可以正常使用,我在TestA.cpp中尝试使用了TArray:

#include"../../Runtime/Core/Public/CoreMinimal.h"

#include<iostream>

int main()
{
	TArray<int> testList;
	testList.Add(3);
	testList.Add(4);
	std::cout << testList[0]- testList[1]<< std::endl;
	return 0;
}

最终可以成功编译,并且运行:
在这里插入图片描述

### UE4 打包 Linux 平台教程 #### 准备工作 为了成功打包UE4项目至Linux平台,需先确认已安装必要的工具链。这包括但不限于Visual Studio及其配套组件[^1]。 对于特定于Linux的设置,在Windows环境中准备时,确保拥有适用于Linux构建的SDK和其他依赖项。这些通常可以在Epic Games启动程序中的附加模块找到并安装。 #### 配置项目支持Linux 要在工程项目中启用对Linux的支持,可在`.build.cs`文件里加入相应的配置语句以引入所需第三方库[^3]: ```csharp PublicDependencyModuleNames.AddRange(new string[] { "Projects", "InputCore", "UnrealEd", "LevelEditor", "Landscape", "Slate", "SlateCore", "Linux" }); ``` 这段代码展示了如何向项目的构建脚本添加公共依赖模块名列表里的Linux条目,从而让该项目能够识别和处理针对Linux的操作需求。 #### 修改引擎源码(如有必要) 有时为了让某些特性正常运作或优化性能表现,可能需要调整虚幻引擎本身的源代码。这类改动应当谨慎行事,并记录好所做的每一步操作以便日后回溯。 #### 清理与重试 遇到打包失败的情况时,清理中间产物是一个有效的排查手段。具体做法是从项目根目录移除`Intermediate`和`Saved`这两个文件夹后再尝试重新编译打包过程[^4]。 #### 使用命令行进行打包 利用命令提示符执行自动化流程也是一种高效的方式。切换到指定版本的UE4安装路径下,例如: ```bash cd "C:\Program Files\Epic Games\UE_4.2X" ``` 这里的`4.2X`代表实际使用的虚幻引擎大版本号,请根据实际情况替换。之后可调用批处理文件或者PowerShell脚本来完成后续步骤。 #### 注意事项 - **环境一致性**:保持开发机上所有软件处于最新稳定状态有助于减少兼容性问题的发生概率。 - **测试充分性**:在不同硬件条件下广泛测试生成的应用程序能帮助发现潜在缺陷。 - **文档查阅**:官方文档始终是最权威的信息来源之一;面对疑难杂症时不妨深入挖掘其中的知识点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值