最近同事遇到一个编译的问题,如果书写了错误的Log语句,会导致真个unreal build无限卡死:
UE_LOG(LogTemp, Debug, TEXT("Something"));
这里这个Debug
等级其实是不存在的,是一个书写错误,正常情况会报一个编译错误,但在我们的case中,会出现无限等待的情况。
网上也有类似的bug情况: https://answers.unrealengine.com/questions/1003748/error-in-macro-syntax-causes-build-to-hang.html?sort=oldest
可以看到的是cl-filter.exe失去了响应,但也没有更多的线索. 于是想去看看这个过程中发生了什么?
之前一直试用UBT编译,没有好好学习过编译一个cpp发生了什么,UE4是怎么一步步去调用到系统的cl.exe完成一个cpp的编译的
获得NMake中Build.bat 后面的参数,这些参数都会送到UnrealBuildTools.exe 中执行
注意要把$(SolutionDir)换成你自己的绝对路径
这样就可以调试整个UBT运行过程了
include信息
和其他编译日志
分离在windows上,一般在VCToolChain.cs中产生一些全局定义和编译参数 主要是一些包含路径和宏定义 Plugin的话可以在
\Intermediate\Build\Win64\UE4Editor\Development\XXX\Module.XXX.cpp.obj.response
找到这个编译参数文件
这个文件直接决定了后面cl-filter以及cl的编译全部内容
这个构造了对应的cl-filter的命令参数 主要有 cl的路径位置,输出的log位置,以及上面提到的response文件 查看这个参数的方法可以直接断点看,
或者加-Verbose参数激活
一个命令行参数大概长这样
"G:\UnrealEngine\Engine\Build\Windows\cl-filter\cl-filter.exe"-dependencies=G:\G6\MMO-Demo\Plugins\G6Plugin\G6SkillFramework\Intermediate\Build\Win64\UE4Editor\Debug\SkillBridge\AnimationActionHandle.cpp.txt -compiler="C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.28.29333\bin\HostX64\x64\cl.exe" -- "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.28.29333\bin\HostX64\x64\cl.exe" @"G:\G6\MMO-Demo\Plugins\G6Plugin\G6SkillFramework\Intermediate\Build\Win64\UE4Editor\Debug\SkillBridge\AnimationActionHandle.cpp.obj.response" /showIncludes
cl-filter 是cl.exe的封装,我们也可以在UnrealEngine\Engine\Extras\Windows\cl-filter找到他的源码和工程,可以attach或者加上上面的命令行参数进行调试
最终执行的cl.exe,就是使用cl-filter后面的那些参数(主要是response文件) 但是我们需要在Unreal程序的\Engine\Source的下面,无论是安装版本的UE4还是源码版本的UE4都可以,但是编译结果也和你的工作路径有关
通常UBT会把一堆小的cpp整合成一个大的cpp以减小编译时间(减少io次数) 这个行为就叫做Unity Build UE自己也有一些编译参数控制UnityBuild的效果,比如bUseUnityBuild/bForceUnityBuild/bUseAdaptiveUnityBuild
某些时候,单个文件编译单独编译比整合成一个大文件更快
1>[Adaptive unity build] Excluded from XXX unity file: XXX.cpp
那么UE是怎么识别这需要exclude呢,我一开始以为是通过修改时间,实际上看了
Unity.cs中的实现之后了解,实际上是通过git status来识别修改的文件。
相比于git修改过的文件就会标记成exclude from build。
如果你的git仓库有submodule,会导致submodule中的文件无法在根目录被git status识别到,这个需要注意
使用单个文件编译可以检查一些头文件包含缺失的方法,除了在git状态下修改,还有一种方法是配置UnrealVS插件使用快捷键进行单文件编译。
比如#include "CoreMinimal.h"
这个如果忘记写,会导致单文件编译的时候DLLEXPORT无法被识别,这也是我坑了很久的问题
目前还没有完美解决和理解,但是通过拆解整个UBT的过程,也是弥补了自己的一些知识盲区
UBT调试方法:https://blog.csdn.net/u013412391/article/details/106150390 cl-filter解释:https://papalqi.cn/ubt/ UE4单独编译一个cpp的方法:https://docs.unrealengine.com/4.26/zh-CN/ProductionPipelines/DevelopmentSetup/VisualStudioSetup/UnrealVS/
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。